diff --git a/Module.php b/Module.php index 61bc4b91491eec0fe4acccd6fe77d6b2f3cca0ac..56777671158f9e2a0432c1e6ffc4bbe5f8810797 100644 --- a/Module.php +++ b/Module.php @@ -85,6 +85,10 @@ SQL; public function upgrade($oldVersion, $newVersion, ServiceLocatorInterface $serviceLocator) { + $config = require __DIR__ . '/config/module.config.php'; + $defaultSettings = $config[strtolower(__NAMESPACE__)]['config']; + $settings = $serviceLocator->get('Omeka\Settings'); + if (version_compare($oldVersion, '0.3', '<')) { $connection = $serviceLocator->get('Omeka\Connection'); $sql = <<<'SQL' @@ -94,10 +98,6 @@ CREATE INDEX IDX_E9AC4F9524CD504D ON oai_pmh_repository_token (expiration); SQL; $connection->exec($sql); - $config = require __DIR__ . '/config/module.config.php'; - $defaultSettings = $config[strtolower(__NAMESPACE__)]['config']; - $settings = $serviceLocator->get('Omeka\Settings'); - $settings->set('oaipmhrepository_name', $settings->get('oaipmh_repository_name', $settings->get('installation_title'))); $settings->set('oaipmhrepository_namespace_id', $settings->get('oaipmhrepository_namespace_id', @@ -119,10 +119,6 @@ SQL; } if (version_compare($oldVersion, '0.3.1', '<')) { - $config = require __DIR__ . '/config/module.config.php'; - $defaultSettings = $config[strtolower(__NAMESPACE__)]['config']; - $settings = $serviceLocator->get('Omeka\Settings'); - $settings->set('oaipmhrepository_global_repository', $defaultSettings['oaipmhrepository_global_repository']); $settings->set('oaipmhrepository_by_site_repository', 'item_set'); @@ -140,6 +136,11 @@ SQL; ALTER TABLE oai_pmh_repository_token CHANGE `set` `set` VARCHAR(190) DEFAULT NULL; SQL; $connection->exec($sql); + + $settings->set('oaipmhrepository_append_identifier_global', + $defaultSettings['oaipmhrepository_append_identifier_global']); + $settings->set('oaipmhrepository_append_identifier_site', + $defaultSettings['oaipmhrepository_append_identifier_site']); } } @@ -245,8 +246,10 @@ SQL; return false; } + $data = $form->getData(); + $defaultSettings = $config[strtolower(__NAMESPACE__)]['config']; - foreach ($params as $name => $value) { + foreach ($data as $name => $value) { if (isset($defaultSettings[$name])) { if ($name === 'oaipmhrepository_namespace_id' && $value === 'localhost') { $value = 'default.must.change'; diff --git a/config/module.config.php b/config/module.config.php index 80a947114927fee098f060662913fc1c2f118e39..3de75aa7a20ecf74bd7135d887257f9dfeeb38fd 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -41,7 +41,7 @@ return [ 'site' => [ 'child_routes' => [ 'oai-pmh' => [ - 'type' => 'Segment', + 'type' => \Zend\Router\Http\Segment::class, 'options' => [ 'route' => '/oai', 'defaults' => [ @@ -55,7 +55,7 @@ return [ ], ], 'oai-pmh' => [ - 'type' => 'Literal', + 'type' => \Zend\Router\Http\Literal::class, 'options' => [ 'route' => '/oai', 'defaults' => [ @@ -99,6 +99,8 @@ return [ 'oaipmhrepository_hide_empty_sets' => true, 'oaipmhrepository_global_repository' => 'item_set', 'oaipmhrepository_by_site_repository' => 'disabled', + 'oaipmhrepository_append_identifier_global' => 'api_url', + 'oaipmhrepository_append_identifier_site' => 'absolute_site_url', 'oaipmhrepository_oai_set_format' => 'basic', 'oaipmhrepository_human_interface' => true, 'oaipmhrepository_redirect_route' => '', diff --git a/config/module.ini b/config/module.ini index e25f26c8336a7628a2ad4965d253108d44a5d487..355004c94cfaa1b571a78b6175afd7c505695e01 100644 --- a/config/module.ini +++ b/config/module.ini @@ -8,5 +8,5 @@ author_link = "https://github.com/biblibre" module_link = "https://github.com/biblibre/omeka-s-module-OaiPmhRepository" support_link = "https://github.com/biblibre/omeka-s-module-OaiPmhRepository/issues" configurable = true -version = "3.2.1" +version = "3.2.2" omeka_version_constraint = "^1.0.0" diff --git a/src/Form/ConfigForm.php b/src/Form/ConfigForm.php index 55b712a4ba47004f5ece72f2effec12d9b406f7a..531ca8f7c53a4c1c9ac81b73161b396ab646ba39 100644 --- a/src/Form/ConfigForm.php +++ b/src/Form/ConfigForm.php @@ -1,11 +1,7 @@ <?php namespace OaiPmhRepository\Form; -use Zend\Form\Element\Checkbox; -use Zend\Form\Element\Number; -use Zend\Form\Element\Radio; -use Zend\Form\Element\Select; -use Zend\Form\Element\Text; +use Zend\Form\Element; use Zend\Form\Form; use Zend\I18n\Translator\TranslatorAwareInterface; use Zend\I18n\Translator\TranslatorAwareTrait; @@ -23,7 +19,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface { $this->add([ 'name' => 'oaipmhrepository_name', - 'type' => Text::class, + 'type' => Element\Text::class, 'options' => [ 'label' => 'Repository name', // @translate 'info' => 'Name for this OAI-PMH repository.', // @translate @@ -35,7 +31,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_namespace_id', - 'type' => Text::class, + 'type' => Element\Text::class, 'options' => [ 'label' => 'Namespace identifier', // @translate 'info' => $this->translate('This will be used to form globally unique IDs for the exposed metadata items.') // @translate @@ -49,7 +45,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_expose_media', - 'type' => Checkbox::class, + 'type' => Element\Checkbox::class, 'options' => [ 'label' => 'Expose media', // @translate 'info' => $this->translate('Whether the plugin should include identifiers for the files associated with items.') // @translate @@ -59,7 +55,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_hide_empty_sets', - 'type' => Checkbox::class, + 'type' => Element\Checkbox::class, 'options' => [ 'label' => 'Hide empty oai sets', // @translate 'info' => 'Whether the module should hide empty oai sets.', // @translate @@ -68,7 +64,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_global_repository', - 'type' => Radio::class, + 'type' => Element\Radio::class, 'options' => [ 'label' => 'Global repository', // @translate 'info' => $this->translate('The global repository contains all the resources of Omeka S, in one place.') // @translate @@ -84,7 +80,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_by_site_repository', - 'type' => Radio::class, + 'type' => Element\Radio::class, 'options' => [ 'label' => 'Site repositories', // @translate 'info' => 'The site repositories simulate multiple oai servers, with the site pools of items and the attached item sets as oai sets.', // @translate @@ -96,11 +92,45 @@ class ConfigForm extends Form implements TranslatorAwareInterface ], ]); + $this->add([ + 'name' => 'oaipmhrepository_append_identifier_global', + 'type' => Element\Radio::class, + 'options' => [ + 'label' => 'Add identifier for global repository', // @translate + 'info' => $this->translate('An identifier may be added to simplify harvests, in particular when there is no unique identifier (ark, noid, call number, etc.).') // @translate + . ' ' . $this->translate('Only one identifier may be added and it can be the api url or a site specific url.') // @translate + . ' ' . $this->translate('Some formats add their own identifier and other ones skip this option.'), // @translate + 'value_options' => [ + 'disabled' => 'None', // @translate + 'api_url' => 'Api url', // @translate + 'relative_site_url' => 'Relative site url', // @translate + 'absolute_site_url' => 'Absolute site url', // @translate + ], + ], + ]); + + $this->add([ + 'name' => 'oaipmhrepository_append_identifier_site', + 'type' => Element\Radio::class, + 'options' => [ + 'label' => 'Add identifier for site repositories', // @translate + 'info' => $this->translate('An identifier may be added to simplify harvests, in particular when there is no unique identifier (ark, noid, call number, etc.).') // @translate + . ' ' . $this->translate('Only one identifier may be added and it can be the api url or a site specific url.') // @translate + . ' ' . $this->translate('Some formats add their own identifier and other ones skip this option.'), // @translate + 'value_options' => [ + 'disabled' => 'None', // @translate + 'api_url' => 'Api url', // @translate + 'relative_site_url' => 'Relative site url', // @translate + 'absolute_site_url' => 'Absolute site url', // @translate + ], + ], + ]); + $valueOptions = $this->getOaiSetFormats(); $valueOptions = array_combine($valueOptions, array_map('ucfirst', $valueOptions)); $this->add([ 'name' => 'oaipmhrepository_oai_set_format', - 'type' => Select::class, + 'type' => Element\Select::class, 'options' => [ 'label' => 'Oai set format', // @translate 'info' => 'The format of the oai set identifiers.', // @translate @@ -113,7 +143,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_human_interface', - 'type' => Checkbox::class, + 'type' => Element\Checkbox::class, 'options' => [ 'label' => 'Human interface', // @translate 'info' => $this->translate('The OAI-PMH pages can be displayed with a themable responsive human interface based on Bootstrap (https://getbootstrap.com).'), // @translate @@ -122,7 +152,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_redirect_route', - 'type' => Text::class, + 'type' => Element\Text::class, 'options' => [ 'label' => 'Global repository redirect route', // @translate 'info' => 'An alias (redirect 301) for backward compatibility with Omeka Classic, that used "/oai-pmh-repository/request", or any other old OAI-PMH repository.', // @translate @@ -131,7 +161,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_list_limit', - 'type' => Number::class, + 'type' => Element\Number::class, 'options' => [ 'label' => 'List limit', // @translate 'info' => $this->translate('Number of individual records that can be returned in a response at once.') // @translate @@ -145,7 +175,7 @@ class ConfigForm extends Form implements TranslatorAwareInterface $this->add([ 'name' => 'oaipmhrepository_token_expiration_time', - 'type' => Number::class, + 'type' => Element\Number::class, 'options' => [ 'label' => 'Token expiration time', // @translate 'info' => $this->translate('In minutes, the length of time a resumption token is valid for.') // @translate diff --git a/src/OaiPmh/Metadata/AbstractMetadata.php b/src/OaiPmh/Metadata/AbstractMetadata.php index aa9d6e9cfb1b092deea9d63a49254104482ac32c..c1b1bdcdfe2e4f6359ceb21b8c39070d0dcd62d2 100644 --- a/src/OaiPmh/Metadata/AbstractMetadata.php +++ b/src/OaiPmh/Metadata/AbstractMetadata.php @@ -12,6 +12,7 @@ use DOMElement; use OaiPmhRepository\OaiPmh\AbstractXmlGenerator; use OaiPmhRepository\OaiPmh\OaiSet\OaiSetInterface; use OaiPmhRepository\OaiPmh\Plugin\OaiIdentifier; +use Omeka\Api\Representation\AbstractResourceEntityRepresentation; use Omeka\Api\Representation\ItemRepresentation; use Omeka\Settings\SettingsInterface; @@ -36,6 +37,11 @@ abstract class AbstractMetadata extends AbstractXmlGenerator implements Metadata */ protected $oaiSet; + /** + * @var bool + */ + protected $isGlobalRepository; + public function setSettings(SettingsInterface $settings) { $this->settings = $settings; @@ -51,6 +57,11 @@ abstract class AbstractMetadata extends AbstractXmlGenerator implements Metadata return $this->oaiSet; } + public function setIsGlobalRepository($isGlobalRepository) + { + $this->isGlobalRepository = $isGlobalRepository; + } + public function declareMetadataFormat(DOMElement $parent) { $elements = [ @@ -91,6 +102,41 @@ abstract class AbstractMetadata extends AbstractXmlGenerator implements Metadata } } + protected function isGlobalRepository() + { + return $this->isGlobalRepository; + } + + protected function singleIdentifier(AbstractResourceEntityRepresentation $resource) + { + if ($this->isGlobalRepository()) { + $append = $this->settings->get('oaipmhrepository_append_identifier_global'); + switch ($append) { + case 'api_url': + return $resource->apiUrl(); + case 'relative_site_url': + case 'absolute_site_url': + $mainSite = $this->settings->get('default_site'); + if ($mainSite) { + $mainSiteSlug = $resource->getServiceLocator()->get('ControllerPluginManager') + ->get('api')->read('sites', $mainSite)->getContent()->slug(); + return $resource->siteUrl($mainSiteSlug, $append === 'absolute_site_url'); + } + break; + } + } else { + $append = $this->settings->get('oaipmhrepository_append_identifier_site'); + switch ($append) { + case 'api_url': + return $resource->apiUrl(); + case 'relative_site_url': + return $resource->siteUrl(); + case 'absolute_site_url': + return $resource->siteUrl(null, true); + } + } + } + abstract public function appendMetadata(DOMElement $parent, ItemRepresentation $item); abstract public function getMetadataPrefix(); diff --git a/src/OaiPmh/Metadata/Mods.php b/src/OaiPmh/Metadata/Mods.php index 3e7f02d39af52f4429d51852f85c93527c74f6cc..5376c43c07a967e79b1da2f74b13f381866e1ab2 100644 --- a/src/OaiPmh/Metadata/Mods.php +++ b/src/OaiPmh/Metadata/Mods.php @@ -133,7 +133,21 @@ class Mods extends AbstractMetadata } $location = $this->appendNewElement($mods, 'location'); - $url = $this->appendNewElement($location, 'url', $item->siteUrl()); + if ($this->isGlobalRepository()) { + $mainSite = $this->settings->get('default_site'); + if ($mainSite) { + $mainSiteSlug = $resource->getServiceLocator()->get('ControllerPluginManager') + ->get('api')->read('sites', $mainSite)->getContent()->slug(); + $append = $this->settings->get('oaipmhrepository_append_identifier_global'); + $url = $item->siteUrl($mainSiteSlug, $append === 'absolute_site_url'); + } else { + $url = $item->apiUrl(); + } + } else { + $append = $this->settings->get('oaipmhrepository_append_identifier_site'); + $url = $item->siteUrl(null, $append === 'absolute_site_url'); + } + $url = $this->appendNewElement($location, 'url', $url); $url->setAttribute('usage', 'primary display'); $publishers = $item->value('dcterms:publisher', ['all' => true]) ?: []; diff --git a/src/OaiPmh/Metadata/OaiDc.php b/src/OaiPmh/Metadata/OaiDc.php index 611056844c9b40cd3b717898f5dcae1ae5439283..0943d44c0babbe7fdaf80dbf4b2c3dce34e410ed 100644 --- a/src/OaiPmh/Metadata/OaiDc.php +++ b/src/OaiPmh/Metadata/OaiDc.php @@ -74,7 +74,10 @@ class OaiDc extends AbstractMetadata } } - $this->appendNewElement($oai_dc, 'dc:identifier', $item->siteUrl()); + $appendIdentifier = $this->singleIdentifier($item); + if ($appendIdentifier) { + $this->appendNewElement($oai_dc, 'dc:identifier', $appendIdentifier); + } // Also append an identifier for each file if ($this->settings->get('oaipmhrepository_expose_media', false)) { diff --git a/src/Service/OaiPmh/Metadata/CdwaLiteFactory.php b/src/Service/OaiPmh/Metadata/CdwaLiteFactory.php index 40202fa3bb2920c704f2db9b612d0935378a3d25..c3e3f77d986e9f1fc1b4e7a19675048a598816a4 100644 --- a/src/Service/OaiPmh/Metadata/CdwaLiteFactory.php +++ b/src/Service/OaiPmh/Metadata/CdwaLiteFactory.php @@ -21,6 +21,9 @@ class CdwaLiteFactory implements FactoryInterface $metadataFormat = new CdwaLite(); $metadataFormat->setSettings($settings); $metadataFormat->setOaiSet($oaiSet); + $isGlobalRepository = !$services->get('ControllerPluginManager') + ->get('params')->fromRoute('__SITE__', false); + $metadataFormat->setIsGlobalRepository($isGlobalRepository); return $metadataFormat; } } diff --git a/src/Service/OaiPmh/Metadata/MetsFactory.php b/src/Service/OaiPmh/Metadata/MetsFactory.php index 19bdfccfcaeb69bc53674c3a99af193b5024fb0b..e041c48bc93adf4a18c0434d73f5d58545c1fd5b 100644 --- a/src/Service/OaiPmh/Metadata/MetsFactory.php +++ b/src/Service/OaiPmh/Metadata/MetsFactory.php @@ -21,6 +21,9 @@ class MetsFactory implements FactoryInterface $metadataFormat = new Mets(); $metadataFormat->setSettings($settings); $metadataFormat->setOaiSet($oaiSet); + $isGlobalRepository = !$services->get('ControllerPluginManager') + ->get('params')->fromRoute('__SITE__', false); + $metadataFormat->setIsGlobalRepository($isGlobalRepository); return $metadataFormat; } } diff --git a/src/Service/OaiPmh/Metadata/ModsFactory.php b/src/Service/OaiPmh/Metadata/ModsFactory.php index 06c3c1b57b8ad95744eba225b0e9a856a873c4a9..9797ad6024978c259532c253c97cc5f32b0f8375 100644 --- a/src/Service/OaiPmh/Metadata/ModsFactory.php +++ b/src/Service/OaiPmh/Metadata/ModsFactory.php @@ -21,6 +21,9 @@ class ModsFactory implements FactoryInterface $metadataFormat = new Mods(); $metadataFormat->setSettings($settings); $metadataFormat->setOaiSet($oaiSet); + $isGlobalRepository = !$services->get('ControllerPluginManager') + ->get('params')->fromRoute('__SITE__', false); + $metadataFormat->setIsGlobalRepository($isGlobalRepository); return $metadataFormat; } } diff --git a/src/Service/OaiPmh/Metadata/OaiDcFactory.php b/src/Service/OaiPmh/Metadata/OaiDcFactory.php index 788609aeaeace95d8afb87611041a1cf04bf6640..12e9b6f9ac659fbb0afffebc9fb5976502f00a86 100644 --- a/src/Service/OaiPmh/Metadata/OaiDcFactory.php +++ b/src/Service/OaiPmh/Metadata/OaiDcFactory.php @@ -21,6 +21,9 @@ class OaiDcFactory implements FactoryInterface $metadataFormat = new OaiDc(); $metadataFormat->setSettings($settings); $metadataFormat->setOaiSet($oaiSet); + $isGlobalRepository = !$services->get('ControllerPluginManager') + ->get('params')->fromRoute('__SITE__', false); + $metadataFormat->setIsGlobalRepository($isGlobalRepository); return $metadataFormat; } }