Skip to content

Commit

Permalink
Allowed to specify multiple properties as identifier.
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel-KM committed Dec 8, 2019
1 parent e625e0c commit 8b2b7ce
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 66 deletions.
5 changes: 4 additions & 1 deletion config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@
'csv_import_multivalue_separator' => ',',
'csv_import_rows_by_batch' => 20,
'csv_import_global_language' => '',
'csv_import_identifier_property' => 'dcterms:identifier',
'csv_import_identifier_properties' => [
'o:id',
'dcterms:identifier',
],
'csv_import_automap_check_names_alone' => false,
],
],
Expand Down
17 changes: 10 additions & 7 deletions src/Controller/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,18 @@ protected function cleanArgs(array $post)
}
}

// Check the identifier property.
if (array_key_exists('identifier_property', $args)) {
$identifierProperty = $args['identifier_property'];
if (empty($identifierProperty) && $identifierProperty !== 'o:id') {
$properties = $api->search('properties', ['term' => $identifierProperty])->getContent();
if (empty($properties)) {
$args['identifier_property'] = null;
// Check the identifier properties.
if (array_key_exists('identifier_properties', $args)) {
$identifierProperties = $args['identifier_properties'] ? $args['identifier_properties'] : [];
foreach ($identifierProperties as $key => $identifierProperty) {
if ($identifierProperty !== 'o:id') {
$property = $api->searchOne('properties', ['term' => $identifierProperty])->getContent();
if (empty($property)) {
unset($args['identifier_properties'][$key]);
}
}
}
$args['identifier_properties'] = array_values($args['identifier_properties']);
}

if (!array_key_exists('column-multivalue', $post)) {
Expand Down
13 changes: 7 additions & 6 deletions src/Form/MappingForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,21 +266,22 @@ public function init()
]);

$basicSettingsFieldset->add([
'name' => 'identifier_property',
'name' => 'identifier_properties',
'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
'label' => 'Resource identifier properties', // @translate
'info' => 'Use these properties, generally "Internal id" or "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' => [
'o:id' => 'Internal ID', // @translate
],
'term_as_value' => true,
],
'attributes' => [
'multiple' => true,
'value' => $userSettings->get(
'csv_import_identifier_property',
$default['csv_import_identifier_property']),
'csv_import_identifier_properties',
$default['csv_import_identifier_properties']),
'class' => 'chosen-select',
'data-placeholder' => 'Select a property', // @translate
],
Expand Down Expand Up @@ -411,7 +412,7 @@ public function init()
'required' => false,
]);
$advancedSettingsInputFilter->add([
'name' => 'identifier_property',
'name' => 'identifier_properties',
'required' => false,
]);
$advancedSettingsInputFilter->add([
Expand Down
54 changes: 31 additions & 23 deletions src/Job/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use CSVImport\Mvc\Controller\Plugin\FindResourcesFromIdentifiers;
use CSVImport\Source\SourceInterface;
use finfo;
use Omeka\Api\Manager;
use Omeka\Mvc\Controller\Plugin\Api;
use Omeka\Job\AbstractJob;
use Omeka\Stdlib\Message;
use Zend\Log\Logger;
Expand All @@ -28,7 +28,7 @@ class Import extends AbstractJob
protected $rowsByBatch = 20;

/**
* @var Manager
* @var Api
*/
protected $api;

Expand Down Expand Up @@ -83,9 +83,9 @@ class Import extends AbstractJob
protected $identifiers;

/**
* @var string|int
* @var array
*/
protected $identifierPropertyId;
protected $identifierProperties;

/**
* @var bool
Expand All @@ -101,7 +101,7 @@ public function perform()
{
ini_set('auto_detect_line_endings', true);
$services = $this->getServiceLocator();
$this->api = $services->get('Omeka\ApiManager');
$this->api = $services->get('ControllerPluginManager')->get('api');
$this->logger = $services->get('Omeka\Logger');
$this->findResourcesFromIdentifiers = $services->get('ControllerPluginManager')
->get('findResourcesFromIdentifiers');
Expand Down Expand Up @@ -154,16 +154,24 @@ public function perform()
return $this->endJob();
}

// 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'] === 'o:id') {
$this->identifierPropertyId = 'o:id';
} elseif (is_numeric($args['identifier_property'])) {
$this->identifierPropertyId = (int) $args['identifier_property'];
} else {
$result = $this->api
->search('properties', ['term' => $args['identifier_property']])->getContent();
$this->identifierPropertyId = $result ? $result[0]->id() : null;
// The main identifier properties may be used as term or as id in some
// places, so prepare them one time only.
$this->identifierProperties = [];
foreach ($args['identifier_properties'] as $identifierProperty) {
if ($identifierProperty === 'o:id') {
$this->identifierProperties[] = 'o:id';
} elseif (is_numeric($identifierProperty)) {
$this->identifierProperties[] = (int) $identifierProperty;
} else {
$result = $this->api
->searchOne('properties', ['term' => $identifierProperty])->getContent();
if ($result) {
$this->identifierProperties[] = $result->id();
}
}
}
if (!$this->identifierProperties) {
$this->identifierProperties = ['o:id'];
}

if (!empty($args['rows_by_batch'])) {
Expand Down Expand Up @@ -258,7 +266,7 @@ protected function processBatchData(array $data)
case self::ACTION_REPLACE:
$findResourcesFromIdentifiers = $this->findResourcesFromIdentifiers;
$identifiers = $this->extractIdentifiers($data);
$ids = $findResourcesFromIdentifiers($identifiers, $this->identifierPropertyId, $this->resourceType);
$ids = $findResourcesFromIdentifiers($identifiers, $this->identifierProperties, $this->resourceType);
$ids = $this->assocIdentifierKeysAndIds($identifiers, $ids);
$idsToProcess = array_filter($ids);
$idsRemaining = array_diff_key($ids, $idsToProcess);
Expand Down Expand Up @@ -294,7 +302,7 @@ protected function processBatchData(array $data)
case self::ACTION_DELETE:
$findResourcesFromIdentifiers = $this->findResourcesFromIdentifiers;
$identifiers = $this->extractIdentifiers($data);
$ids = $findResourcesFromIdentifiers($identifiers, $this->identifierPropertyId, $this->resourceType);
$ids = $findResourcesFromIdentifiers($identifiers, $this->identifierProperties, $this->resourceType);
$idsToProcess = array_filter($ids);
$idsRemaining = array_diff_key($ids, $idsToProcess);

Expand Down Expand Up @@ -521,11 +529,11 @@ protected function identifyMedias(array $data, array $ids)
if (empty($media['o:source']) || empty($media['o:ingester'])) {
continue;
}
$identifierProperties = [];
$identifierProperties['o:ingester'] = $media['o:ingester'];
$identifierProperties['o:item']['o:id'] = $ids[$key];
$identifier = [];
$identifier['o:ingester'] = $media['o:ingester'];
$identifier['o:item']['o:id'] = $ids[$key];
$resourceId = $findResourceFromIdentifier(
$media['o:source'], $identifierProperties, 'media');
$media['o:source'], [$identifier], 'media');
if ($resourceId) {
$media['o:id'] = $resourceId;
}
Expand Down Expand Up @@ -948,7 +956,7 @@ protected function extractPropertyValuesFromResource($resourceJson)
}

/**
* Deduplicate data ids for collections of items set, items, media....
* Deduplicate data ids for collections of items set, items, media
*
* @param array $data
* @return array
Expand Down Expand Up @@ -1091,7 +1099,7 @@ protected function checkOptions()

// Specific check when a identifier is required.
elseif (!in_array($args['action'], [self::ACTION_CREATE, self::ACTION_SKIP])) {
if (empty($args['identifier_property'])) {
if (empty($args['identifier_properties'])) {
$this->hasErr = true;
$this->logger->err(new Message('The action "%s" requires a resource identifier property.', // @translate
$args['action']));
Expand Down
40 changes: 24 additions & 16 deletions src/Mapping/PropertyMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class PropertyMapping extends AbstractMapping
protected $findResourceFromIdentifier;

/**
* @var int|string
* @var array
*/
protected $propertyIdentifier;
protected $identifierProperties;

public function getSidebar(PhpRenderer $view)
{
Expand All @@ -32,16 +32,24 @@ public function init(array $args, ServiceLocatorInterface $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'] === 'o:id') {
$this->propertyIdentifier = 'o: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() : 'o:id';
// The main identifier properties may be used as term or as id in some
// places, so prepare them one time only.
$this->identifierProperties = [];
foreach ($args['identifier_properties'] as $identifierProperty) {
if ($identifierProperty === 'o:id') {
$this->identifierProperties[] = 'o:id';
} elseif (is_numeric($identifierProperty)) {
$this->identifierProperties[] = (int) $identifierProperty;
} else {
$result = $this->api
->searchOne('properties', ['term' => $identifierProperty])->getContent();
if ($result) {
$this->identifierProperties[] = $result->id();
}
}
}
if (!$this->identifierProperties) {
$this->identifierProperties = ['o:id'];
}
}

Expand Down Expand Up @@ -131,7 +139,7 @@ public function processRow(array $row)
break;

case 'resource':
$identifier = $this->findResource($value, $this->propertyIdentifier);
$identifier = $this->findResource($value, $this->identifierProperties);
$valueData = [
'value_resource_id' => $identifier,
'property_id' => $propertyId,
Expand Down Expand Up @@ -183,14 +191,14 @@ protected function getDataTypeAdapters()
return $dataTypeAdapters;
}

protected function findResource($identifier, $propertyIdentifier = 'o:id')
protected function findResource($identifier, $identifierProperties = ['o:id'])
{
$resourceType = $this->args['resource_type'];
$findResourceFromIdentifier = $this->findResourceFromIdentifier;
$resourceId = $findResourceFromIdentifier($identifier, $propertyIdentifier, $resourceType);
$resourceId = $findResourceFromIdentifier($identifier, $identifierProperties, $resourceType);
if (empty($resourceId)) {
$this->logger->err(new Message('"%s" (%s) is not a valid resource identifier.', // @translate
$identifier, $propertyIdentifier));
$identifier, implode('", "', $identifierProperties)));
$this->setHasErr(true);
return false;
}
Expand Down
Loading

0 comments on commit 8b2b7ce

Please sign in to comment.