/lib/task/import/csvImportTask.class.php
PHP | 1195 lines | 946 code | 123 blank | 126 comment | 109 complexity | f46a10c5e46844c4f6e39f6d8ddfe701 MD5 | raw file
Possible License(s): CC-BY-3.0, AGPL-3.0, MIT, ISC
- <?php
- /*
- * This file is part of the Access to Memory (AtoM) software.
- *
- * Access to Memory (AtoM) is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Access to Memory (AtoM) is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Access to Memory (AtoM). If not, see <http://www.gnu.org/licenses/>.
- */
- /**
- * Import csv data
- *
- * @package symfony
- * @subpackage task
- * @author Mike Cantelon <mike@artefactual.com>
- */
- class csvImportTask extends csvImportBaseTask
- {
- protected $namespace = 'csv';
- protected $name = 'import';
- protected $briefDescription = 'Import csv information object data';
- protected $detailedDescription = <<<EOF
- Import CSV data
- EOF;
- /**
- * @see sfTask
- */
- protected function configure()
- {
- parent::configure();
- $this->addOptions(array(
- new sfCommandOption(
- 'source-name',
- null,
- sfCommandOption::PARAMETER_OPTIONAL,
- 'Source name to use when inserting keymap entries.'
- ),
- new sfCommandOption(
- 'default-parent-slug',
- null,
- sfCommandOption::PARAMETER_OPTIONAL,
- 'Parent slug under which imported items, with no parent specified, will be added.'
- ),
- new sfCommandOption(
- 'default-legacy-parent-id',
- null,
- sfCommandOption::PARAMETER_OPTIONAL,
- 'Legacy parent ID under which imported items, with no parent specified, will be added.'
- ),
- new sfCommandOption(
- 'skip-nested-set-build',
- null,
- sfCommandOption::PARAMETER_NONE,
- "Don't build the nested set upon import completion."
- ),
- new sfCommandOption(
- 'index',
- null,
- sfCommandOption::PARAMETER_NONE,
- "Index for search during import."
- )
- ));
- }
- /**
- * @see sfTask
- */
- public function execute($arguments = array(), $options = array())
- {
- $configuration = ProjectConfiguration::getApplicationConfiguration('qubit', 'test', false);
- $sf_context = sfContext::createInstance($configuration);
- $this->validateOptions($options);
- $skipRows = ($options['skip-rows']) ? $options['skip-rows'] : 0;
- // source name can be specified so, if importing from multiple
- // sources, you can accommodate legacy ID collisions in files
- // you import from different places
- $sourceName = ($options['source-name'])
- ? $options['source-name']
- : basename($arguments['filename']);
- if (false === $fh = fopen($arguments['filename'], 'rb'))
- {
- throw new sfException('You must specify a valid filename');
- }
- $databaseManager = new sfDatabaseManager($this->configuration);
- $conn = $databaseManager->getDatabase('propel')->getConnection();
- // set default publication status
- $results = $conn->query('SELECT i18n.value
- FROM setting INNER JOIN setting_i18n i18n ON setting.id = i18n.id
- WHERE setting.name=\'defaultPubStatus\'');
- if ($results)
- {
- $defaultStatusId = $results->fetchColumn();
- }
- else
- {
- $defaultStatusId = QubitTerm::PUBLICATION_STATUS_PUBLISHED_ID;
- }
- // TODO: this may be unnecessary as it may now be part of Qubit trunk
- // create note term if it doesn't yet exist
- QubitFlatfileImport::createOrFetchTerm(
- QubitTaxonomy::NOTE_TYPE_ID,
- 'Language note'
- );
- QubitFlatfileImport::createOrFetchTerm(
- QubitTaxonomy::RAD_NOTE_ID,
- 'Cast note'
- );
- QubitFlatfileImport::createOrFetchTerm(
- QubitTaxonomy::RAD_NOTE_ID,
- 'Credits note'
- );
- QubitFlatfileImport::createOrFetchTerm(
- QubitTaxonomy::RAD_NOTE_ID,
- 'Signatures note'
- );
- // Load taxonomies into variables to avoid use of magic numbers
- $termData = QubitFlatfileImport::loadTermsFromTaxonomies(array(
- QubitTaxonomy::DESCRIPTION_STATUS_ID => 'descriptionStatusTypes',
- QubitTaxonomy::PUBLICATION_STATUS_ID => 'pubStatusTypes',
- QubitTaxonomy::DESCRIPTION_DETAIL_LEVEL_ID => 'levelOfDetailTypes',
- QubitTaxonomy::NOTE_TYPE_ID => 'noteTypes',
- QubitTaxonomy::RAD_NOTE_ID => 'radNoteTypes',
- QubitTaxonomy::RAD_TITLE_NOTE_ID => 'titleNoteTypes',
- QubitTaxonomy::MATERIAL_TYPE_ID => 'materialTypes',
- QubitTaxonomy::RIGHT_ACT_ID => 'copyrightActTypes',
- QubitTaxonomy::COPYRIGHT_STATUS_ID => 'copyrightStatusTypes',
- QubitTaxonomy::PHYSICAL_OBJECT_TYPE_ID => 'physicalObjectTypes'
- ));
- // Allow default parent ID to be overridden by CLI options
- if ($options['default-parent-slug'])
- {
- $defaultParentId = getIdCorrespondingToSlug($options['default-parent-slug']);
- if (!$options['quiet'])
- {
- print 'Parent ID of slug "'. $options['default-parent-slug'] .'" is '. $defaultParentId;
- }
- } else if($options['default-legacy-parent-id']) {
- // attempt to fetch keymap entry
- $keyMapEntry = QubitFlatfileImport::fetchKeymapEntryBySourceAndTargetName(
- $options['default-legacy-parent-id'],
- $sourceName,
- 'information_object'
- );
- if ($keyMapEntry)
- {
- $defaultParentId = $keyMapEntry->target_id;
- } else {
- throw new sfException('Could not find Qubit ID corresponding to legacy ID.');
- }
- print 'Using default parent ID '. $defaultParentId .' (legacy parent ID '. $options['default-legacy-parent-id'] .")\n";
- } else {
- $defaultParentId = QubitInformationObject::ROOT_ID;
- }
- // Define import
- $import = new QubitFlatfileImport(array(
- /* Pass context */
- 'context' => sfContext::createInstance($this->configuration),
- /* What type of object are we importing? */
- 'className' => 'QubitInformationObject',
- /* Allow silencing of progress info */
- 'displayProgress' => ($options['quiet']) ? false : true,
- /* How many rows should import until we display an import status update? */
- 'rowsUntilProgressDisplay' => $options['rows-until-update'],
- /* Where to log errors to */
- 'errorLog' => $options['error-log'],
- /* the status array is a place to put data that should be accessible
- from closure logic using the getStatus method */
- 'status' => array(
- 'options' => $options,
- 'sourceName' => $sourceName,
- 'defaultParentId' => $defaultParentId,
- 'copyrightStatusTypes' => $termData['copyrightStatusTypes'],
- 'copyrightActTypes' => $termData['copyrightActTypes'],
- 'defaultStatusId' => $defaultStatusId,
- 'descriptionStatusTypes' => $termData['descriptionStatusTypes'],
- 'pubStatusTypes' => $termData['pubStatusTypes'],
- 'levelOfDetailTypes' => $termData['levelOfDetailTypes'],
- 'materialTypes' => $termData['materialTypes'],
- 'physicalObjectTypes' => $termData['physicalObjectTypes']
- ),
- /* import columns that map directory to QubitInformationObject properties */
- 'standardColumns' => array(
- 'updatedAt',
- 'createdAt',
- 'accessConditions',
- 'accruals',
- 'acquisition',
- 'alternateTitle',
- 'appraisal',
- 'archivalHistory',
- 'arrangement',
- 'culture',
- 'descriptionIdentifier',
- 'extentAndMedium',
- 'findingAids',
- 'identifier',
- 'locationOfCopies',
- 'locationOfOriginals',
- 'physicalCharacteristics',
- 'relatedUnitsOfDescription',
- 'reproductionConditions',
- 'revisionHistory',
- 'rules',
- 'scopeAndContent',
- 'sources',
- 'title'
- ),
- /* import columns that should be redirected to QubitInformationObject
- properties (and optionally transformed)
- Example:
- 'columnMap' => array(
- 'Archival History' => 'archivalHistory',
- 'Revision history' => array(
- 'column' => 'revision',
- 'transformationLogic' => function(&$self, $text)
- {
- return $self->appendWithLineBreakIfNeeded(
- $self->object->revision,
- $text
- );
- }
- )
- ),
- */
- 'columnMap' => array(
- 'radEdition' => 'edition',
- 'institutionIdentifier' => 'institutionResponsibleIdentifier'
- ),
- /* import columns that can be added using the
- QubitInformationObject::addProperty method */
- 'propertyMap' => array(
- 'radOtherTitleInformation' => 'otherTitleInformation',
- 'radTitleStatementOfResponsibility' => 'titleStatementOfResponsibility',
- 'radStatementOfProjection' => 'statementOfProjection',
- 'radStatementOfCoordinates' => 'statementOfCoordinates',
- 'radStatementOfScaleArchitectural' => 'statementOfScaleArchitectural',
- 'radStatementOfScaleCartographic' => 'statementOfScaleCartographic',
- 'radPublishersSeriesNote' => 'noteOnPublishersSeries',
- 'radIssuingJurisdiction' => 'issuingJurisdictionAndDenomination',
- 'radEditionStatementOfResponsibility' => 'editionStatementOfResponsibility',
- 'radTitleProperOfPublishersSeries' => 'titleProperOfPublishersSeries',
- 'radParallelTitlesOfPublishersSeries' => 'parallelTitleOfPublishersSeries',
- 'radOtherTitleInformationOfPublishersSeries' => 'otherTitleInformationOfPublishersSeries',
- 'radStatementOfResponsibilityRelatingToPublishersSeries' => 'statementOfResponsibilityRelatingToPublishersSeries',
- 'radNumberingWithinPublishersSeries' => 'numberingWithinPublishersSeries',
- 'radStandardNumber' => 'standardNumber'
- ),
- /* import columns that can be added as QubitNote objects */
- 'noteMap' => array(
- 'languageNote' => array(
- 'typeId' => array_search('Language note', $termData['noteTypes'])
- ),
- 'publicationNote' => array(
- 'typeId' => array_search('Publication note', $termData['noteTypes'])
- ),
- 'generalNote' => array(
- 'typeId' => array_search('General note', $termData['noteTypes'])
- ),
- 'archivistNote' => array(
- 'typeId' => array_search("Archivist's note", $termData['noteTypes'])
- ),
- 'radNoteCast' => array(
- 'typeId' => array_search('Cast note', $termData['radNoteTypes'])
- ),
- 'radNoteCredits' => array(
- 'typeId' => array_search('Credits note', $termData['radNoteTypes'])
- ),
- 'radNoteSignaturesInscriptions' => array(
- 'typeId' => array_search('Signatures note', $termData['radNoteTypes'])
- ),
- 'radNoteConservation' => array(
- 'typeId' => array_search('Conservation', $termData['radNoteTypes'])
- ),
- 'radNoteGeneral' => array(
- 'typeId' => array_search('General note', $termData['radNoteTypes'])
- ),
- 'radNotePhysicalDescription' => array(
- 'typeId' => array_search('Physical description', $termData['radNoteTypes'])
- ),
- 'radNotePublishersSeries' => array(
- 'typeId' => array_search("Publisher's series", $termData['radNoteTypes'])
- ),
- 'radNoteRights' => array(
- 'typeId' => array_search('Rights', $termData['radNoteTypes'])
- ),
- 'radNoteAccompanyingMaterial' => array(
- 'typeId' => array_search('Accompanying material', $termData['radNoteTypes'])
- ),
- 'radNoteAlphaNumericDesignation' => array(
- 'typeId' => array_search('Alpha-numeric designations', $termData['radNoteTypes'])
- ),
- 'radNoteEdition' => array(
- 'typeId' => array_search('Edition', $termData['radNoteTypes'])
- ),
- 'radTitleStatementOfResponsibilityNote' => array(
- 'typeId' => array_search('Statements of responsibility', $termData['titleNoteTypes'])
- ),
- 'radTitleParallelTitles' => array(
- 'typeId' => array_search('Parallel titles and other title information', $termData['titleNoteTypes'])
- ),
- 'radTitleSourceOfTitleProper' => array(
- 'typeId' => array_search('Source of title proper', $termData['titleNoteTypes'])
- ),
- 'radTitleVariationsInTitle' => array(
- 'typeId' => array_search('Variations in title', $termData['titleNoteTypes'])
- ),
- 'radTitleAttributionsAndConjectures' => array(
- 'typeId' => array_search('Attributions and conjectures', $termData['titleNoteTypes'])
- ),
- 'radTitleContinues' => array(
- 'typeId' => array_search('Continuation of title', $termData['titleNoteTypes'])
- ),
- 'radTitleNoteContinuationOfTitle' => array(
- 'typeId' => array_search('Continuation of title', $termData['titleNoteTypes'])
- )
- ),
- /* these values get stored to the rowStatusVars array */
- 'variableColumns' => array(
- 'legacyId',
- 'parentId',
- 'copyrightStatus',
- 'copyrightExpires',
- 'copyrightHolder',
- 'qubitParentSlug',
- 'descriptionStatus',
- 'publicationStatus',
- 'levelOfDetail',
- 'repository',
- 'language',
- 'script',
- 'languageOfDescription',
- 'scriptOfDescription',
- 'physicalObjectName',
- 'physicalObjectLocation',
- 'physicalObjectType',
- 'physicalStorageLocation',
- 'digitalObjectPath',
- 'digitalObjectURI'
- ),
- /* these values get exploded and stored to the rowStatusVars array */
- 'arrayColumns' => array(
- 'accessionNumber' => '|',
- 'creators' => '|',
- 'creatorHistories' => '|',
- // TODO: the creatorDates* columns should be depricated in favor of
- // a separate event import
- 'creatorDates' => '|',
- 'creatorDateNotes' => '|',
- 'creatorDatesStart' => '|',
- 'creatorDatesEnd' => '|',
- 'nameAccessPoints' => '|',
- 'nameAccessPointHistories' => '|',
- 'placeAccessPoints' => '|',
- 'placeAccessPointHistories' => '|', // not yet implemented
- 'subjectAccessPoints' => '|',
- 'subjectAccessPointScopes' => '|', // not yet implemented
- 'eventActors' => '|',
- 'eventTypes' => '|',
- 'eventPlaces' => '|',
- 'eventDates' => '|',
- 'eventStartDates' => '|',
- 'eventEndDates' => '|',
- 'eventDescriptions' => '|'
- ),
- /* import logic to execute before saving information object */
- 'preSaveLogic' => function(&$self)
- {
- // set repository
- if (
- isset($self->rowStatusVars['repository'])
- && $self->rowStatusVars['repository']
- )
- {
- $repository = $self->createOrFetchRepository($self->rowStatusVars['repository']);
- $self->object->repositoryId = $repository->id;
- }
- // set level of detail
- if (isset($self->rowStatusVars['levelOfDetail'])
- && 0 < strlen($self->rowStatusVars['levelOfDetail']))
- {
- $levelOfDetailTermId = array_search(
- (trim($self->rowStatusVars['levelOfDetail'])) ? $self->rowStatusVars['levelOfDetail'] : 'Full',
- $self->status['levelOfDetailTypes']
- );
- $self->object->descriptionDetailId = $levelOfDetailTermId;
- }
- // storage language-related properties as serialized data
- $languageProperties = array(
- 'language',
- 'script',
- 'languageOfDescription',
- 'scriptOfDescription'
- );
- foreach($languageProperties as $serializeProperty)
- {
- if (isset($self->rowStatusVars[$serializeProperty])
- && 0 < strlen($self->rowStatusVars[$serializeProperty]))
- {
- $data = explode('|', $self->rowStatusVars[$serializeProperty]);
- $self->object->addProperty(
- $serializeProperty,
- serialize($data)
- );
- }
- }
- // set description status
- if (isset($self->rowStatusVars['descriptionStatus'])
- && 0 < strlen($self->rowStatusVars['descriptionStatus']))
- {
- $statusTermId = array_search(
- trim($self->rowStatusVars['descriptionStatus']),
- $self->status['descriptionStatusTypes']
- );
- if (false !== $statusTermId)
- {
- $self->object->descriptionStatusId = $statusTermId;
- }
- else
- {
- printf("Row %s: Invalid description status '%s', using null instead\n",
- $self->getStatus('rows') + 1,
- trim($self->rowStatusVars['descriptionStatus']));
- }
- }
- // set publication status
- if (isset($self->rowStatusVars['publicationStatus'])
- && 0 < strlen($self->rowStatusVars['publicationStatus']))
- {
- $pubStatusTermId = array_search_case_insensitive(
- $self->rowStatusVars['publicationStatus'],
- $self->status['pubStatusTypes']
- );
- if (!$pubStatusTermId)
- {
- print "Publication status: '". $self->rowStatusVars['publicationStatus'] ."' is invalid. Using default.\n";
- $pubStatusTermId = $self->status['defaultStatusId'];
- }
- } else {
- $pubStatusTermId = $self->status['defaultStatusId'];
- }
- $self->object->setPublicationStatus($pubStatusTermId);
- if (
- isset($self->rowStatusVars['qubitParentSlug'])
- && $self->rowStatusVars['qubitParentSlug']
- )
- {
- $parentId = getIdCorrespondingToSlug($self->rowStatusVars['qubitParentSlug']);
- } else {
- if (!isset($self->rowStatusVars['parentId']) || !$self->rowStatusVars['parentId'])
- {
- // Don't overwrite valid parentId when adding an i18n row
- if (!isset($self->object->parentId))
- {
- $parentId = $self->status['defaultParentId'];
- }
- } else {
- if ($mapEntry = $self->fetchKeymapEntryBySourceAndTargetName(
- $self->rowStatusVars['parentId'],
- $self->getStatus('sourceName'),
- 'information_object'
- ))
- {
- $parentId = $mapEntry->target_id;
- } else {
- $error = 'For legacyId '
- . $self->rowStatusVars['legacyId']
- .' Could not find parentId '
- . $self->rowStatusVars['parentId']
- .' in key_map table';
- print $self->logError($error);
- }
- }
- }
- if (isset($parentId))
- {
- $self->object->parentId = $parentId;
- }
- },
- /* import logic to execute after saving information object */
- 'postSaveLogic' => function(&$self)
- {
- if (!$self->object->id)
- {
- throw new sfException('Information object save failed');
- } else {
- // add keymap entry
- $keymap = new QubitKeymap;
- $keymap->sourceId = $self->rowStatusVars['legacyId'];
- $keymap->sourceName = $self->getStatus('sourceName');
- $keymap->targetId = $self->object->id;
- $keymap->targetName = 'information_object';
- $keymap->save();
- // add physical objects
- if (
- isset($self->rowStatusVars['physicalObjectName'])
- && $self->rowStatusVars['physicalObjectName']
- )
- {
- $names = explode('|', $self->rowStatusVars['physicalObjectName']);
- $locations = explode('|', $self->rowStatusVars['physicalObjectLocation']);
- $types = (isset($self->rowStatusVars['physicalObjectType']))
- ? explode('|', $self->rowStatusVars['physicalObjectType'])
- : array();
- foreach($names as $index => $name)
- {
- // if location column populated
- if ($self->rowStatusVars['physicalObjectLocation'])
- {
- // if current index applicable
- if (isset($locations[$index]))
- {
- $location = $locations[$index];
- } else {
- $location = $locations[0];
- }
- } else {
- $location = '';
- }
- // if object type column populated
- if ($self->rowStatusVars['physicalObjectType'])
- {
- // if current index applicable
- if (isset($types[$index]))
- {
- $type = $types[$index];
- } else {
- $type = $types[0];
- }
- } else {
- $type = 'Box';
- }
- $physicalObjectTypeId = array_search(
- $type,
- $self->getStatus('physicalObjectTypes')
- );
- // Create new physical object type if not found
- if ($physicalObjectTypeId === false)
- {
- $newType = new QubitTerm;
- $newType->name = $type;
- $newType->culture = isset($self->object->culture) ? $self->object->culture : 'en';
- $newType->taxonomyId = QubitTaxonomy::PHYSICAL_OBJECT_TYPE_ID;
- $newType->parentId = QubitTerm::ROOT_ID;
- $newType->save();
- $physicalObjectTypeId = $newType->id;
- }
- $container = $self->createOrFetchPhysicalObject(
- $name,
- $location,
- $physicalObjectTypeId
- );
- // associate container with information object
- $self->createRelation(
- $container->id,
- $self->object->id,
- QubitTerm::HAS_PHYSICAL_OBJECT_ID
- );
- }
- }
- // add subject access points
- $accessPointColumns = array(
- 'subjectAccessPoints' => QubitTaxonomy::SUBJECT_ID,
- 'placeAccessPoints' => QubitTaxonomy::PLACE_ID,
- );
- foreach($accessPointColumns as $columnName => $taxonomyId)
- {
- if (isset($self->rowStatusVars[$columnName]))
- {
- $index = 0;
- foreach($self->rowStatusVars[$columnName] as $subject)
- {
- if ($subject)
- {
- $scope = false;
- if (isset($self->rowStatusVars['subjectAccessPointScopes'][$index]))
- {
- $scope = $self->rowStatusVars['subjectAccessPointScopes'][$index];
- }
- $self->createAccessPoint($taxonomyId, $subject);
- if ($scope)
- {
- // get term ID
- $query = "SELECT t.id FROM term t \r
- INNER JOIN term_i18n i ON t.id=i.id \r
- WHERE i.name=? AND t.taxonomy_id=? AND culture='en'";
- $statement = QubitFlatfileImport::sqlQuery(
- $query,
- array($subject, $taxonomyId)
- );
- $result = $statement->fetch(PDO::FETCH_OBJ);
- if ($result)
- {
- $termId = $result->id;
- // check if a scope note already exists for this term
- $query = "SELECT n.id FROM note n INNER JOIN note_i18n i ON n.id=i.id WHERE n.object_id=? AND n.type_id=?";
- $statement = QubitFlatfileImport::sqlQuery(
- $query,
- array($termId, QubitTerm::SCOPE_NOTE_ID)
- );
- $result = $statement->fetch(PDO::FETCH_OBJ);
- if (!$result)
- {
- // add scope note if it doesn't exist
- $note = new QubitNote;
- $note->objectId = $termId;
- $note->typeId = QubitTerm::SCOPE_NOTE_ID;
- $note->content = $self->content($scope);
- $note->scope = 'QubitTerm'; # not sure if this is needed
- $note->save();
- }
- } else {
- throw new sfException('Could not find term "'. $subject .'"');
- }
- }
- }
- $index++;
- }
- }
- }
- // add name access points
- if (isset($self->rowStatusVars['nameAccessPoints']))
- {
- // add name access points
- $index = 0;
- foreach($self->rowStatusVars['nameAccessPoints'] as $name)
- {
- // skip blank names
- if ($name)
- {
- $actorOptions = array();
- if (isset($self->rowStatusVars['nameAccessPointHistories'][$index]))
- {
- $actorOptions['history'] = $self->rowStatusVars['nameAccessPointHistories'][$index];
- }
- if (isset($self->object->repositoryId))
- {
- $actorOptions['repositoryId'] = $self->object->repositoryId;
- }
- $actor = $self->createOrFetchActor($name, $actorOptions);
- $self->createRelation($self->object->id, $actor->id, QubitTerm::NAME_ACCESS_POINT_ID);
- }
- $index++;
- }
- }
- // add accessions
- if (
- isset($self->rowStatusVars['accessionNumber'])
- && count($self->rowStatusVars['accessionNumber'])
- )
- {
- foreach($self->rowStatusVars['accessionNumber'] as $accessionNumber)
- {
- // attempt to fetch keymap entry
- $accessionMapEntry = $self->fetchKeymapEntryBySourceAndTargetName(
- $accessionNumber,
- $self->getStatus('sourceName'),
- 'accession'
- );
- // if no entry found, create accession and entry
- if (!$accessionMapEntry)
- {
- print "\nCreating accession # ". $accessionNumber ."\n";
- // create new accession
- $accession = new QubitAccession;
- $accession->identifier = $accessionNumber;
- $accession->save();
- // create keymap entry for accession
- $keymap = new QubitKeymap;
- $keymap->sourceId = $accessionNumber;
- $keymap->sourceName = $self->getStatus('sourceName');
- $keymap->targetId = $accession->id;
- $keymap->targetName = 'accession';
- $keymap->save();
- $accessionId = $accession->id;
- } else {
- $accessionId = $accessionMapEntry->target_id;
- }
- print "\nAssociating accession # ". $accessionNumber ." with ". $self->object->title ."\n";
- // add relationship between information object and accession
- $self->createRelation($self->object->id, $accessionId, QubitTerm::ACCESSION_ID);
- }
- }
- // add material-related term relation
- if (isset($self->rowStatusVars['radGeneralMaterialDesignation']))
- {
- foreach($self->rowStatusVars['radGeneralMaterialDesignation'] as $material)
- {
- $self->createObjectTermRelation(
- $self->object->id,
- $material
- );
- }
- }
- // add copyright info
- // TODO: handle this via a separate import
- if (isset($self->rowStatusVars['copyrightStatus']) && $self->rowStatusVars['copyrightStatus'])
- {
- switch (strtolower($self->rowStatusVars['copyrightStatus']))
- {
- case 'under copyright':
- print "Adding rights for ". $self->object->title ."...\n";
- $rightsHolderId = false;
- $rightsHolderNames = explode('|', $self->rowStatusVars['copyrightHolder']);
- if ($self->rowStatusVars['copyrightExpires'])
- {
- $endDates = explode('|', $self->rowStatusVars['copyrightExpires']);
- }
- foreach($rightsHolderNames as $index => $rightsHolderName)
- {
- $rightsHolderName = ($rightsHolderName) ? $rightsHolderName : 'Unknown';
- $rightsHolder = $self->createOrFetchRightsHolder($rightsHolderName);
- $rightsHolderId = $rightsHolder->id;
- $rightsHolderName = trim(strtolower($rightsHolderName));
- if (
- $rightsHolderName == 'city of vancouver'
- || strpos($rightsHolderName, 'city of vancouver') === 0
- )
- {
- $restriction = 1;
- } else {
- $restriction = 0;
- }
- $rightAndRelation = array(
- 'restriction' => $restriction,
- 'basisId' => QubitTerm::RIGHT_BASIS_COPYRIGHT_ID,
- 'actId' => array_search(
- 'Replicate',
- $self->getStatus('copyrightActTypes')
- ),
- 'copyrightStatusId' => array_search(
- 'Under copyright',
- $self->getStatus('copyrightStatusTypes')
- )
- );
- if (isset($endDates))
- {
- // if rightsholder/expiry dates and paired, use
- // corresponding date ...otherwise just use the
- // first expiry date
- $rightAndRelation['endDate']
- = (count($endDates) == count($rightsHolderNames))
- ? $endDates[$index]
- : $endDates[0];
- if (!is_numeric($rightAndRelation['endDate']))
- {
- throw new sfException('Copyright expiry '. $rightAndRelation['endDate']
- .' is invalid.');
- }
- }
- if ($rightsHolderId) $rightAndRelation['rightsHolderId'] = $rightsHolderId;
- $self->createRightAndRelation($rightAndRelation);
- }
- break;
- case 'unknown':
- $rightsHolder = $self->createOrFetchRightsHolder('Unknown');
- $rightsHolderId = $rightsHolder->id;
- $rightAndRelation = array(
- 'rightsHolderId' => $rightsHolderId,
- 'restriction' => 0,
- 'basisId' => QubitTerm::RIGHT_BASIS_COPYRIGHT_ID,
- 'actId' => array_search(
- 'Replicate',
- $self->getStatus('copyrightActTypes')
- ),
- 'copyrightStatusId' => array_search(
- 'Unknown',
- $self->getStatus('copyrightStatusTypes')
- )
- );
- if ($self->rowStatusVars['copyrightExpires'])
- {
- $rightAndRelation['endDate'] = $self->rowStatusVars['copyrightExpires'];
- }
- $self->createRightAndRelation($rightAndRelation);
- break;
- case 'public domain':
- $rightAndRelation = array(
- 'restriction' => 1,
- 'basisId' => QubitTerm::RIGHT_BASIS_COPYRIGHT_ID,
- 'actId' => array_search(
- 'Replicate',
- $self->getStatus('copyrightActTypes')
- ),
- 'copyrightStatusId' => array_search(
- 'Public domain',
- $self->getStatus('copyrightStatusTypes')
- )
- );
- if ($self->rowStatusVars['copyrightExpires'])
- {
- $rightAndRelation['endDate'] = $self->rowStatusVars['copyrightExpires'];
- }
- $self->createRightAndRelation($rightAndRelation);
- break;
- default:
- throw new sfException('Copyright status "'
- . $self->rowStatusVars['copyrightStatus']
- .'" not handled: adjust script or import data');
- break;
- }
- }
- // add ad-hoc events
- if (isset($self->rowStatusVars['eventActors']))
- {
- foreach($self->rowStatusVars['eventActors'] as $index => $actor)
- {
- // initialize data that'll be used to create the event
- $eventData = array(
- 'actorName' => $actor
- );
- // define whether each event-related column's values go directly
- // into an event property or put into a varibale for further
- // processing
- $eventColumns = array(
- 'eventTypes' => array(
- 'variable' => 'eventType',
- 'requiredError' => 'You have populated the eventActors column but not the eventTypes column.'
- ),
- 'eventPlaces' => array('variable' => 'place'),
- 'eventDates' => array('property' => 'date'),
- 'eventStartDates' => array('property' => 'startDate'),
- 'eventEndDates' => array('property' => 'endDate'),
- 'eventDescriptions' => array('property' => 'description')
- );
- // handle each of the event-related columns
- $eventType = false;
- $place = false;
- foreach($eventColumns as $column => $definition)
- {
- if (isset($self->rowStatusVars[$column]))
- {
- $value
- = (count($self->rowStatusVars['eventActors']) == count($self->rowStatusVars[$column]))
- ? $self->rowStatusVars[$column][$index]
- : $self->rowStatusVars[$column][0];
- // allow column value(s) to set event property
- if (isset($definition['property']))
- {
- $eventData[($definition['property'])] = $value;
- }
- // allow column values(s) to set variable
- if (isset($definition['variable']))
- {
- $$definition['variable'] = $value;
- }
- } else if (isset($definition['requiredError'])) {
- throw new sfException('You have populated the eventActors column but not the eventTypes column.');
- }
- }
- // if an event type has been specified, attempt to create the event
- if ($eventType)
- {
- // do lookup of type ID
- $typeTerm = $self->createOrFetchTerm(QubitTaxonomy::EVENT_TYPE_ID, $eventType);
- $eventTypeId = $typeTerm->id;
- // create event
- $event = $self->createOrUpdateEvent($eventTypeId, $eventData);
- // create a place term if specified
- if ($place)
- {
- // create place
- $placeTerm = $self->createTerm(QubitTaxonomy::PLACE_ID, $place);
- $self->createObjectTermRelation($event->id, $placeTerm->id);
- }
- } else {
- throw new sfException('eventTypes column need to be populated.');
- }
- }
- }
- // add creators and create events
- $createEvents = array();
- if (isset($self->rowStatusVars['creators'])
- && count($self->rowStatusVars['creators']))
- {
- foreach($self->rowStatusVars['creators'] as $index => $creator)
- {
- // Init eventData array and add creator name
- $eventData = array('actorName' => $creator);
- setupEventDateData($self, $eventData, $index);
- // Add creator history if specified
- if(isset($self->rowStatusVars['creatorHistories'][$index]))
- {
- $eventData['actorHistory'] = $self->rowStatusVars['creatorHistories'][$index];
- }
- array_push($createEvents, $eventData);
- }
- }
- else if(
- isset($self->rowStatusVars['creatorDatesStart'])
- || isset($self->rowStatusVars['creatorDatesEnd'])
- ) {
- foreach($self->rowStatusVars['creatorDatesStart'] as $index => $date)
- {
- $eventData = array();
- setupEventDateData($self, $eventData, $index);
- array_push($createEvents, $eventData);
- }
- }
- else if(isset($self->rowStatusVars['creatorDates'])) {
- foreach($self->rowStatusVars['creatorDates'] as $index => $date)
- {
- $eventData = array();
- setupEventDateData($self, $eventData, $index);
- array_push($createEvents, $eventData);
- }
- }
- // create events, if any
- if (count($createEvents))
- {
- if ($self->rowStatusVars['culture'] != $self->object->sourceCulture)
- {
- // Add i18n data to existing event
- $sql = "SELECT id FROM event WHERE information_object_id = ? and type_id = ?;";
- $stmt = QubitFlatfileImport::sqlQuery($sql, array(
- $self->object->id,
- QubitTerm::CREATION_ID));
- $i = 0;
- while ($eventId = $stmt->fetchColumn())
- {
- $createEvents[$i++]['eventId'] = $eventId;
- }
- }
- foreach($createEvents as $eventData)
- {
- $event = $self->createOrUpdateEvent(
- QubitTerm::CREATION_ID,
- $eventData
- );
- }
- }
- // This will import only a single digital object;
- // if both a URI and path are provided, the former is preferred.
- if ($uri = $self->rowStatusVars['digitalObjectURI']) {
- $do = new QubitDigitalObject;
- try {
- $do->importFromURI($uri);
- $do->informationObject = $self->object;
- $do->save($conn);
- // importFromURI can raise if the download hits a timeout
- } catch (Exception $e) {
- $self->logError($e->getMessage());
- }
- } elseif ($path = $self->rowStatusVars['digitalObjectPath']) {
- if (false === $content = file_get_contents($path)) {
- $this->logError("Unable to read file: ".$path);
- } else {
- $do = new QubitDigitalObject;
- $do->assets[] = new QubitAsset($path, $content);
- $do->usageId = QubitTerm::MASTER_ID;
- $do->informationObject = $self->object;
- $do->save($conn);
- }
- }
- }
- }
- ));
- // allow search indexing to be enabled via a CLI option
- $import->searchIndexingDisabled = ($options['index']) ? false : true;
- // convert content with | characters to a bulleted list
- $import->contentFilterLogic = function($text)
- {
- return (substr_count($text, '|'))
- ? '* '. str_replace("|", "\n* ", $text)
- : $text;
- };
- $import->addColumnHandler('levelOfDescription', function(&$self, $data)
- {
- $self->object->setLevelOfDescriptionByName($data);
- });
- // map value to taxonomy term name and take note of taxonomy term's ID
- $import->addColumnHandler('radGeneralMaterialDesignation', function(&$self, $data)
- {
- if ($data)
- {
- $data = explode('|', $data);
- foreach ($data as $value)
- {
- $materialIndex = array_search(
- $value,
- $self->getStatus('materialTypes')
- );
- if (is_numeric($materialIndex))
- {
- $self->rowStatusVars['radGeneralMaterialDesignation'][] = $materialIndex;
- } else {
- throw new sfException('Invalid material type:'. $value);
- }
- }
- }
- });
- $import->csv($fh, $skipRows);
- // build nested set if desired
- if (!$options['skip-nested-set-build'])
- {
- $buildNestedSet = new propelBuildNestedSetTask($this->dispatcher, $this->formatter);
- $buildNestedSet->setCommandApplication($this->commandApplication);
- $buildNestedSet->setConfiguration($this->configuration);
- $ret = $buildNestedSet->run();
- }
- }
- }
- function array_search_case_insensitive($search, $array)
- {
- return array_search(strtolower($search), array_map('strtolower', $array));
- }
- function setupEventDateData(&$self, &$eventData, $index)
- {
- // add dates if specified
- if (
- isset($self->rowStatusVars['creatorDates'][$index])
- || isset($self->rowStatusVars['creatorDatesStart'][$index])
- )
- {
- // Start and end date
- foreach(array(
- 'creatorDatesEnd' => 'endDate',
- 'creatorDatesStart' => 'startDate'
- )
- as $statusVar => $eventProperty
- )
- {
- if (isset($self->rowStatusVars[$statusVar][$index])) {
- $eventData[$eventProperty] = $self->rowStatusVars[$statusVar][$index] .'-00-00';
- }
- }
- // Other date info
- foreach(array(
- 'creatorDateNotes' => 'description',
- 'creatorDates' => 'date'
- )
- as $statusVar => $eventProperty
- )
- {
- if (isset($self->rowStatusVars[$statusVar][$index]))
- {
- $eventData[$eventProperty] = $self->rowStatusVars[$statusVar][$index];
- }
- }
- }
- }
- function getIdCorrespondingToSlug($slug)
- {
- $query = "SELECT object_id FROM slug WHERE slug=?";
- $statement = QubitFlatfileImport::sqlQuery(
- $query,
- array($slug)
- );
- $result = $statement->fetch(PDO::FETCH_OBJ);
- if ($result)
- {
- return $result->object_id;
- } else {
- throw new sfException('Could not find information object matching slug "'. $slug .'"');
- }
- }