diff --git a/config/module.config.php b/config/module.config.php index f03154dd..fa1eb3ef 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -175,7 +175,7 @@ 'adapter' => 'uri', ], 'resource' => [ - 'label' => 'Omeka resource (by ID)', // @translate + 'label' => 'Omeka resource', // @translate 'adapter' => 'resource', ], ], @@ -192,7 +192,7 @@ 'csv_import_multivalue_separator' => ',', 'csv_import_rows_by_batch' => 20, 'csv_import_global_language' => '', - 'csv_import_identifier_property' => '', + 'csv_import_identifier_property' => 'dcterms:identifier', 'csv_import_automap_check_names_alone' => false, ], ], diff --git a/src/Form/MappingForm.php b/src/Form/MappingForm.php index 52fbc786..d74b597f 100644 --- a/src/Form/MappingForm.php +++ b/src/Form/MappingForm.php @@ -265,6 +265,27 @@ public function init() ], ]); + $basicSettingsFieldset->add([ + 'name' => 'identifier_property', + 'type' => PropertySelect::class, + 'options' => [ + 'label' => 'Resource identifier property', // @translate + 'info' => 'Use this property, generally "dcterms:identifier", to identify the existing resources to link or to get. In all cases, it is strongly recommended to add one or more unique identifiers to all your resources.', // @translate + 'empty_option' => 'Select below', // @translate + 'prepend_value_options' => [ + 'internal_id' => 'Internal ID', // @translate + ], + 'term_as_value' => true, + ], + 'attributes' => [ + 'value' => $userSettings->get( + 'csv_import_identifier_property', + $default['csv_import_identifier_property']), + 'class' => 'chosen-select', + 'data-placeholder' => 'Select a property', // @translate + ], + ]); + $this->add([ 'type' => 'fieldset', 'name' => 'advanced-settings', @@ -319,27 +340,6 @@ public function init() ]); } - $advancedSettingsFieldset->add([ - 'name' => 'identifier_property', - 'type' => PropertySelect::class, - 'options' => [ - 'label' => 'Resource identifier property', // @translate - 'info' => 'Use this property, generally "dcterms:identifier", to identify the existing resources, so it will be possible to update them. One column of the file must map the selected property. In all cases, it is strongly recommended to add one ore more unique identifiers to all your resources.', // @translate - 'empty_option' => 'Select below', // @translate - 'prepend_value_options' => [ - 'internal_id' => 'Internal ID', // @translate - ], - 'term_as_value' => true, - ], - 'attributes' => [ - 'value' => $userSettings->get( - 'csv_import_identifier_property', - $default['csv_import_identifier_property']), - 'class' => 'action-option chosen-select', - 'data-placeholder' => 'Select a property', // @translate - ], - ]); - $advancedSettingsFieldset->add([ 'name' => 'action_unidentified', 'type' => 'radio', diff --git a/src/Job/Import.php b/src/Job/Import.php index a36cecbf..aedbc2d2 100644 --- a/src/Job/Import.php +++ b/src/Job/Import.php @@ -157,7 +157,7 @@ public function perform() // The main identifier property may be used as term or as id in some // places, so prepare it one time only. if (empty($args['identifier_property']) || $args['identifier_property'] === 'internal_id') { - $this->identifierPropertyId = $args['identifier_property']; + $this->identifierPropertyId = 'internal_id'; } elseif (is_numeric($args['identifier_property'])) { $this->identifierPropertyId = (int) $args['identifier_property']; } else { @@ -170,12 +170,8 @@ public function perform() $this->rowsByBatch = (int) $args['rows_by_batch']; } - // The core allows batch processes only for creation and deletion. - if (!in_array($args['action'], [self::ACTION_CREATE, self::ACTION_DELETE, self::ACTION_SKIP]) - // It allows to identify resources too, so to use a new resource - // from a previous row. - || ($args['action'] === self::ACTION_CREATE && $this->resourceType === 'resources') - ) { + // The core allows batch processes only for deletion. + if (!in_array($args['action'], [self::ACTION_DELETE, self::ACTION_SKIP])) { $this->rowsByBatch = 1; } diff --git a/src/Mapping/AbstractMapping.php b/src/Mapping/AbstractMapping.php index 8c31111b..c11a512b 100644 --- a/src/Mapping/AbstractMapping.php +++ b/src/Mapping/AbstractMapping.php @@ -57,7 +57,7 @@ public function init(array $args, ServiceLocatorInterface $serviceLocator) $this->args = $args; $this->serviceLocator = $serviceLocator; $this->logger = $serviceLocator->get('Omeka\Logger'); - $this->api = $serviceLocator->get('Omeka\ApiManager'); + $this->api = $serviceLocator->get('ControllerPluginManager')->get('api'); } public function getServiceLocator() diff --git a/src/Mapping/PropertyMapping.php b/src/Mapping/PropertyMapping.php index 4278a68c..36b8cad4 100644 --- a/src/Mapping/PropertyMapping.php +++ b/src/Mapping/PropertyMapping.php @@ -1,6 +1,9 @@ csvPropertySelector($view->translate('Properties'), false); } + public function init(array $args, ServiceLocatorInterface $serviceLocator) + { + parent::init($args, $serviceLocator); + $this->findResourceFromIdentifier = $serviceLocator->get('ControllerPluginManager') + ->get('findResourceFromIdentifier'); + + // The main identifier property may be used as term or as id in some + // places, so prepare it one time only. + if (empty($args['identifier_property']) || $args['identifier_property'] === 'internal_id') { + $this->propertyIdentifier = 'internal_id'; + } elseif (is_numeric($args['identifier_property'])) { + $this->propertyIdentifier = (int) $args['identifier_property']; + } else { + $result = $this->api + ->searchOne('properties', ['term' => $args['identifier_property']])->getContent(); + $this->propertyIdentifier = $result ? $result->id() : 'internal_id'; + } + } + public function processRow(array $row) { // Reset the data and the map between rows. @@ -46,6 +78,7 @@ public function processRow(array $row) } $dataTypeAdapters = $this->getDataTypeAdapters(); + $findResourceFromIdentifier = $this->findResourceFromIdentifier; // Get default option values. $globalLanguage = isset($this->args['global_language']) ? $this->args['global_language'] : ''; @@ -98,8 +131,9 @@ public function processRow(array $row) break; case 'resource': + $identifier = $this->findResource($value, $this->propertyIdentifier); $valueData = [ - 'value_resource_id' => $value, + 'value_resource_id' => $identifier, 'property_id' => $propertyId, 'type' => $type, ]; @@ -148,4 +182,18 @@ protected function getDataTypeAdapters() } return $dataTypeAdapters; } + + protected function findResource($identifier, $propertyIdentifier = 'o:id') + { + $resourceType = $this->args['resource_type']; + $findResourceFromIdentifier = $this->findResourceFromIdentifier; + $resourceId = $findResourceFromIdentifier($identifier, $propertyIdentifier, $resourceType); + if (empty($resourceId)) { + $this->logger->err(new Message('"%s" (%s) is not a valid resource identifier.', // @translate + $identifier, $propertyIdentifier)); + $this->setHasErr(true); + return false; + } + return $resourceId; + } }