Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAI Refactoring #1094

Merged
merged 59 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
068bdd0
Separation of the formats regarding the format xslt files and made th…
haogatyp Aug 17, 2023
112b330
#766 Refactor configuration, added options (currently only xslt file…
haogatyp Aug 20, 2023
d7e2477
#766 Including the prefix xslt in the base xslt instead of the other …
haogatyp Aug 23, 2023
83a0a4e
#766 ServerFactory directly reads oai options from configuration and …
haogatyp Aug 25, 2023
84e700e
#766 Fix absolut path for xsltFile
haogatyp Aug 25, 2023
d0fcdcd
#766 Fix some coding style.
haogatyp Aug 25, 2023
5fa63f7
Fix coding style.
haogatyp Aug 28, 2023
32f8269
Adjust visibility of some option getter methods.
haogatyp Aug 29, 2023
b78a459
#766 Add basic option getter tests for the BaseServer.
haogatyp Aug 29, 2023
e92fc9b
#766 Removed usage of getcwd().
haogatyp Aug 29, 2023
ce5004d
#766 Fix method access level
haogatyp Aug 29, 2023
4039c6e
#766 Split ServerFactory test methods.
haogatyp Aug 29, 2023
b167ac2
#766 Merge default and format specific options.
haogatyp Aug 31, 2023
aa07706
#766 Remove unnecessary check on "true".
haogatyp Aug 31, 2023
b9585c9
#766 Removed throwing the exception, as this is already happening at …
haogatyp Aug 31, 2023
97311cc
#766 Set the value for xsltFile so that it can be overwritten again u…
haogatyp Aug 31, 2023
2d24448
#1097 Made ViewHelper configurable.
haogatyp Aug 31, 2023
a711037
#766 Replaced options array with single properties.
haogatyp Sep 1, 2023
9a5da62
#1097 Default and format-specific ViewHelper options are combined add…
haogatyp Sep 1, 2023
098856f
#1097 Check if viewhelpers exist.
haogatyp Sep 1, 2023
88b9275
#766 Replace marker comment with a more technical marker.
haogatyp Sep 1, 2023
2388d8b
#766 Removed some double spaces.
haogatyp Sep 1, 2023
90b25f2
#766 Removed some double blank lines.
haogatyp Sep 1, 2023
a84057c
#766 Remove some hard coded format specific code and reduced oai form…
haogatyp Sep 5, 2023
23621bc
#1101 Generate OAI ListMetadataFormats from configuration.
haogatyp Sep 5, 2023
1b27ea9
#1101 Add xslt viewhelper for generating the OAI ListMetadataFormats.
haogatyp Sep 5, 2023
99c919e
#1101 Made string composition more readable.
haogatyp Sep 6, 2023
a24cf61
#1101 Reworked the behavior of the incremental option merging so that…
haogatyp Sep 6, 2023
f551e13
#1101 Fix option merging.
haogatyp Sep 7, 2023
4963cf7
#1101 Fix coding style.
haogatyp Sep 7, 2023
f8cd379
#1101 Added tests for ListMetadataFormats viewhelper.
haogatyp Sep 7, 2023
52593fc
#1101 Removed deprecated property.
haogatyp Sep 7, 2023
79cac6d
#1101 Fix some coding style.
haogatyp Sep 7, 2023
c4a8ba6
#766 Added comments to OAI config
j3nsch Sep 25, 2023
a8d230c
#766 Rename option "viewHelper"
haogatyp Oct 5, 2023
7967b50
#766 Fixed some typos.
haogatyp Oct 5, 2023
42c37f6
#766 Fix return empty string for integer variables. Renaming maxRecor…
haogatyp Oct 5, 2023
882c038
#766 Now also checking for array.
haogatyp Oct 5, 2023
8c5cec9
#766 Using DocumentInterface instead of Document.
haogatyp Oct 5, 2023
70b7504
#766 Added class comment.
haogatyp Oct 5, 2023
e979a6a
#766 Fix class comment.
haogatyp Oct 6, 2023
6f70e08
#766 Adjust option getters and setters for NULL values.
haogatyp Oct 6, 2023
b773cf1
#766 Using shorter parameter names in setter methods.
haogatyp Oct 6, 2023
111b442
#766 Fix some comments.
haogatyp Oct 6, 2023
c28ecb2
#766 Removed unnecessary ternary operator.
haogatyp Oct 6, 2023
403318e
#766 Removed outdated todo comment.
haogatyp Oct 6, 2023
f25c07a
#766 Renaming the marker for metadata format replacement.
haogatyp Oct 6, 2023
d83ab74
#766 Adjust error message.
haogatyp Oct 6, 2023
bc3f3ac
#766 Renamed OaiConfig to match the class name.
haogatyp Oct 6, 2023
e61c90c
#766 Fixed coding style
j3nsch Oct 9, 2023
f27d9da
#766 Empty line after header (coding style)
j3nsch Oct 9, 2023
719d66b
#766 Shorten class variable comments.
haogatyp Oct 10, 2023
bb48b41
#766 Added a comment to make things hopefully more clear.
haogatyp Oct 10, 2023
43072df
#766 Removed unused method.
haogatyp Oct 10, 2023
1ca259f
#766 Use class name only ones in the function.
haogatyp Oct 10, 2023
01de758
#766 Moved oai server test classes to oai test.
haogatyp Oct 10, 2023
ec8f82d
#766 Updated comment
j3nsch Oct 10, 2023
59b25c3
#766 Removed unnecessary mock test class and moved remaining mock tes…
haogatyp Oct 10, 2023
6527e7b
#766 Added a function to add view helpers to a oai server.
haogatyp Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions application/configs/application.ini
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,17 @@ oai.description.eprints.comment.text =
; oai.format.[lower cased format identifier ].prefix = [prefix]
oai.format.default.class = Oai_Model_BaseServer
oai.format.default.viewHelper = optionValue, fileUrl, frontdoorUrl, transferUrl, dcmiType, dcType, openAireType
oai.format.copy_xml.xsltFile = copy_xml.xslt
oai.format.epicur.xsltFile = epicur.xslt
oai.format.marc21.xsltFile = marc21.xslt
oai.format.oai_dc.xsltFile = oai_dc.xslt
oai.format.oai_pp.xsltFile = oai_pp.xslt
oai.format.xmetadissplus.xsltFile = XMetaDissPlus.xslt
oai.format.default.checkEmbargo = 0
oai.format.default.hasFilesVisibleInOai = 0

; OPUS 4 XML (only for admins)
oai.format.copy_xml.class = Oai_Model_Prefix_CopyXml_CopyXmlServer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sieht gut aus. Das ist die Idee, aber lass mal bitte die CopyXmlServer Klasse weg. Für dieses eine Format machen wir das ohne Klasse.

Wir haben hier auch noch ein weiteres Problem mit der Klasse. WIr hatten ja vereinbart prefixLabel als "Flag" zu verwenden, ob das Format bei ListMetadataFormats auftauchen soll oder nicht. Gibt es einen Eintrag in der Konfiguration, der aber leer ist, wird es nicht gelistet. Wenn man versucht das mit der Klasse zu machen wird es schwierig, weil man nicht so einfach zwischen NULL weil nicht gesetzt und NULL explizit gesetzt unterscheiden kann.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vermutlich werden wir doch noch eine Option für die "Sichtbarkeit" brauchen und eine Option für die Access-Kontrolle, vielleicht "adminOnly". Das kann später ausgebaut werden, wenn es UseCases für eine feinere Kontrolle über ACLs gibt.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wir könnten jetzt auch erst einmal sagen, Formate, die nicht sichtbar sind, können nur von Admins abgerufen werden und uns damit die zweite Option erst einmal sparen.


oai.format.epicur.class = Oai_Model_Prefix_Epicur_EpicurServer
oai.format.marc21.class = Oai_Model_Prefix_MarcXml_MarcXmlServer
oai.format.oai_dc.class = Oai_Model_Prefix_Oai_OaiDcServer
oai.format.oai_pp.class = Oai_Model_Prefix_Oai_OaiPpServer
oai.format.xmetadissplus.class = Oai_Model_Prefix_XMetaDissPlus_XMetaDissPlusServer

; ERROR CONTROLLER SETTINGS
errorController.showException = 0
Expand Down
252 changes: 210 additions & 42 deletions modules/oai/models/BaseServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
* @license http://www.gnu.org/licenses/gpl.html General Public License
*/

use Opus\Common\Config\ConfigException;
use Opus\Common\Document;
use Opus\Common\DocumentFinderInterface;
use Opus\Common\DocumentInterface;
use Opus\Common\Log;
use Opus\Common\Model\NotFoundException;
Expand Down Expand Up @@ -62,21 +64,6 @@ class Oai_Model_BaseServer extends Application_Model_Abstract
*/
protected $proc;

/**
* Holds information about which document state aka server_state
* are delivered out
*
* @var array
*/
private $deliveringDocumentStates = ['published', 'deleted']; // maybe deleted documents too

/**
* Holds restriction types for xMetaDiss
*
* @var array
*/
private $xMetaDissRestriction = ['doctoralthesis', 'habilitation'];

/** @var Oai_Model_XmlFactory */
private $xmlFactory;

Expand Down Expand Up @@ -122,6 +109,24 @@ class Oai_Model_BaseServer extends Application_Model_Abstract
/** @var string */
private $viewHelper;

/** @var bool */
private $checkEmbargo = false;

/** @var array */
private $documentTypesAllowed;

/** @var array Holds information about which document state aka server_state are delivered out. */
private $documentStatesAllowed = ['published', 'deleted']; // maybe deleted documents too

/** @var bool */
private $notEmbargoedOn = false;

/** @var string */
private $identifierExists = '';

/** @var bool */
private $hasFilesVisibleInOai = false;

/**
* Gather configuration before action handling.
*/
Expand Down Expand Up @@ -329,27 +334,8 @@ protected function handleGetRecord(array &$oaiRequest)

$metadataPrefix = $oaiRequest['metadataPrefix'];

// do not deliver documents which are restricted by document state
if (
$document === null
|| (false === in_array($document->getServerState(), $this->deliveringDocumentStates))
|| (false === $document->hasEmbargoPassed() && stripos($metadataPrefix, 'xmetadiss') === 0)
) {
throw new Oai_Model_Exception('Document is not available for OAI export!', Oai_Model_Error::NORECORDSMATCH);
}
$this->checkExportAllowed($document, $metadataPrefix);

// for xMetaDiss it must be habilitation-thesis or doctoral-thesis
if ('xMetaDiss' === $metadataPrefix) {
$type = $document->getType();
$isHabOrDoc = in_array($type, $this->xMetaDissRestriction);
if (false === $isHabOrDoc) {
throw new Oai_Model_Exception(
"The combination of the given values results in an empty list (xMetaDiss only for habilitation"
. " and doctoralthesis).",
Oai_Model_Error::NORECORDSMATCH
);
}
}
$this->xml->appendChild($this->xml->createElement('Documents'));

$this->createXmlRecord($document);
Expand Down Expand Up @@ -521,11 +507,9 @@ private function handlingOfLists(array &$oaiRequest, $maxRecords)
$resumed = true;
} else {
// no resumptionToken is given
$docListModel = new Oai_Model_DocumentList();
$docListModel->deliveringDocumentStates = $this->deliveringDocumentStates;
$docListModel->xMetaDissRestriction = $this->xMetaDissRestriction;
$restIds = $docListModel->query($oaiRequest);
$totalIds = count($restIds);
$docListModel = new Oai_Model_DocumentList($this);
$restIds = $docListModel->query($oaiRequest);
$totalIds = count($restIds);
}

// handling of document ids
Expand Down Expand Up @@ -743,7 +727,7 @@ private function getDocumentIdByIdentifier($oaiIdentifier)
case 'urn':
$finder = Repository::getInstance()->getDocumentFinder();
$finder->setIdentifierValue('urn', $oaiIdentifier);
$finder->setServerState($this->deliveringDocumentStates);
$finder->setServerState($this->getDocumentStatesAllowed());
$docIds = $finder->getIds();
$docId = $docIds[0];
break;
Expand Down Expand Up @@ -777,7 +761,7 @@ private function getDocumentIdByIdentifier($oaiIdentifier)
*/
private function getDocumentXmlDomNode($document)
{
if (! in_array($document->getServerState(), $this->deliveringDocumentStates)) {
if (! in_array($document->getServerState(), $this->getDocumentStatesAllowed())) {
$message = 'Trying to get a document in server state "' . $document->getServerState() . '"';
Log::get()->err($message);
throw new Exception($message);
Expand Down Expand Up @@ -1093,4 +1077,188 @@ public function setViewHelper($viewHelper)
{
$this->viewHelper = $viewHelper;
}

/**
* Gets the checkEmbargo option.
*
* @return bool
*/
public function isCheckEmbargo()
{
return $this->checkEmbargo;
}

/**
* Sets the checkEmbargo option.
*
* @param mixed $checkEmbargo
*/
public function setCheckEmbargo($checkEmbargo)
{
$this->checkEmbargo = filter_var($checkEmbargo, FILTER_VALIDATE_BOOLEAN);
}

/**
* Gets the allowed document types.
*
* @return array
*/
public function getDocumentTypesAllowed()
{
return $this->documentTypesAllowed;
}

/**
* Sets the allowed document types.
*
* @param array|string $documentTypesAllowed
*/
public function setdocumentTypesAllowed($documentTypesAllowed)
{
if (is_string($documentTypesAllowed)) {
$this->documentTypesAllowed = [$documentTypesAllowed];
} else {
$this->documentTypesAllowed = $documentTypesAllowed;
}
}

/**
* Gets the allowed document states.
*
* @return array
*/
public function getDocumentStatesAllowed()
{
return $this->documentStatesAllowed;
}

/**
* Sets the allowed document states
*
* @param array|string $documentStatesAllowed
*/
public function setDocumentStatesAllowed($documentStatesAllowed)
{
if (is_string($documentStatesAllowed)) {
$this->documentStatesAllowed = [$documentStatesAllowed];
} else {
$this->documentStatesAllowed = $documentStatesAllowed;
}
}

/**
* @return bool
*/
public function isNotEmbargoedOn()
{
return $this->notEmbargoedOn;
}

/**
* @param bool|string $notEmbargoedOn
*/
public function setNotEmbargoedOn($notEmbargoedOn)
{
$this->notEmbargoedOn = filter_var($notEmbargoedOn, FILTER_VALIDATE_BOOLEAN);
}

/**
* @return string
*/
public function getIdentifierExists()
{
return $this->identifierExists;
}

/**
* @param string $identifierExists
*/
public function setIdentifierExists($identifierExists)
{
$this->identifierExists = $identifierExists;
}

/**
* @return bool
*/
public function isHasFilesVisibleInOai()
{
return $this->hasFilesVisibleInOai;
}

/**
* @param bool|string $hasFilesVisibleInOai
*/
public function setHasFilesVisibleInOai($hasFilesVisibleInOai)
{
$this->hasFilesVisibleInOai = filter_var($hasFilesVisibleInOai, FILTER_VALIDATE_BOOLEAN);
}

/**
* Checks if exporting a document is allowed, if not an exception will be thrown.
*
* @param Document $document
* @param string $metadataPrefix
* @return void
* @throws Oai_Model_Exception
*/
protected function checkExportAllowed($document, $metadataPrefix)
{
// do not deliver documents which are restricted by document state
if (
$document === null
|| (! in_array($document->getServerState(), $this->getDocumentStatesAllowed()))
|| (! $document->hasEmbargoPassed() && $this->isCheckEmbargo())
) {
throw new Oai_Model_Exception('Document is not available for OAI export!', Oai_Model_Error::NORECORDSMATCH);
}

$documentTypeRestriction = $this->getDocumentTypesAllowed();
if ($documentTypeRestriction) {
$type = $document->getType();
if (! in_array($type, $documentTypeRestriction)) {
throw new Oai_Model_Exception(
'The combination of the given values results in an empty list (' . $metadataPrefix
. ' only for' . implode(', ', $documentTypeRestriction) . ')',
Oai_Model_Error::NORECORDSMATCH
);
}
}
}

/**
* Get the initialized finder for the given metadata prefix
*
* @param string $metadataPrefix
* @return DocumentFinderInterface
* @throws ConfigException
*/
public function getFinder($metadataPrefix)
{
$today = date('Y-m-d', time());

$finder = Repository::getInstance()->getDocumentFinder();

// add server state restrictions
$finder->setServerState($this->getDocumentStatesAllowed());

if ($this->isHasFilesVisibleInOai()) {
$finder->setHasFilesVisibleInOai();
}

$documentTypesAllowed = $this->getDocumentTypesAllowed();
if ($documentTypesAllowed) {
$finder->setDocumentType($documentTypesAllowed);
}

if ($this->isNotEmbargoedOn()) {
$finder->setNotEmbargoedOn($today);
}

if ($this->getIdentifierExists()) {
$finder->setIdentifierExists($this->getIdentifierExists());
}

return $finder;
}
}
45 changes: 8 additions & 37 deletions modules/oai/models/DocumentList.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,19 @@
*/

use Opus\Common\CollectionRole;
use Opus\Common\Repository;

class Oai_Model_DocumentList
{
/**
* Holds information about which document state aka server_state
* are delivered out
*
* @var array
*
* TODO should be private
*/
public $deliveringDocumentStates;
/** @var Oai_Model_BaseServer */
protected $server;

/**
* Holds restriction types for xMetaDiss
*
* @var array
*
* TODO should be private
* @param Oai_Model_BaseServer $server
*/
public $xMetaDissRestriction;
public function __construct($server)
{
$this->server = $server;
}

/**
* Retrieve all document ids for a valid oai request.
Expand All @@ -64,29 +55,9 @@ class Oai_Model_DocumentList
*/
public function query(array $oaiRequest)
{
$today = date('Y-m-d', time());

$finder = Repository::getInstance()->getDocumentFinder();

// add server state restrictions
$finder->setServerState($this->deliveringDocumentStates);

$metadataPrefix = strtolower($oaiRequest['metadataPrefix']);

if (
strcmp('xmetadissplus', $metadataPrefix) === 0
|| 'xmetadiss' === $metadataPrefix
) {
$finder->setHasFilesVisibleInOai();
$finder->setNotEmbargoedOn($today);
}
if ('xmetadiss' === $metadataPrefix) {
$finder->setDocumentType($this->xMetaDissRestriction);
$finder->setNotEmbargoedOn($today);
}
if ('epicur' === $metadataPrefix) {
$finder->setIdentifierExists('urn');
}
$finder = $this->server->getFinder($metadataPrefix);

if (array_key_exists('set', $oaiRequest)) {
$setarray = explode(':', $oaiRequest['set']);
Expand Down
Loading