Ejemplo n.º 1
0
 /**
  * @covers PKPLocale
  */
 public function testGet3LetterIsoFromLocale()
 {
     self::assertEquals('eng', Locale::get3LetterIsoFromLocale('en_US'));
     self::assertEquals('por', Locale::get3LetterIsoFromLocale('pt_BR'));
     self::assertEquals('por', Locale::get3LetterIsoFromLocale('pt_PT'));
     self::assertNull(Locale::get3LetterIsoFromLocale('xx_XX'));
 }
 /**
  * @see MetadataDataObjectAdapter::extractMetadataFromDataObject()
  * @param $submission Submission
  * @param $authorMarcrelatorRole string the marcrelator role to be used
  *  for submission authors.
  * @return MetadataDescription
  */
 function &extractMetadataFromDataObject(&$submission, $authorMarcrelatorRole = 'aut')
 {
     assert(is_a($submission, 'Submission'));
     $mods34Description =& $this->instantiateMetadataDescription();
     // Retrieve the primary locale.
     $catalogingLocale = Locale::getPrimaryLocale();
     $catalogingLanguage = Locale::get3LetterIsoFromLocale($catalogingLocale);
     // Establish the association between the meta-data description
     // and the submission.
     $mods34Description->setAssocId($submission->getId());
     // Title
     $localizedTitles =& $submission->getTitle(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'titleInfo/title', $localizedTitles);
     // Authors
     // FIXME: Move this to a dedicated adapter in the Author class.
     $authors =& $submission->getAuthors();
     foreach ($authors as $author) {
         /* @var $author Author */
         // Create a new name description.
         $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.mods34.schema.Mods34NameSchema', ASSOC_TYPE_AUTHOR);
         // Type
         $authorType = 'personal';
         $authorDescription->addStatement('[@type]', $authorType);
         // Family Name
         $authorDescription->addStatement('namePart[@type="family"]', $author->getLastName());
         // Given Names
         $firstName = (string) $author->getFirstName();
         $middleName = (string) $author->getMiddleName();
         $givenNames = trim($firstName . ' ' . $middleName);
         if (!empty($givenNames)) {
             $authorDescription->addStatement('namePart[@type="given"]', $givenNames);
         }
         // Affiliation
         // NB: Our MODS mapping currently doesn't support translation for names.
         // This can be added when required by data consumers. We therefore only use
         // translations in the cataloging language.
         $affiliation = $author->getAffiliation($catalogingLocale);
         if ($affiliation) {
             $authorDescription->addStatement('affiliation', $affiliation);
         }
         // Terms of address (unmapped field)
         $termsOfAddress = $author->getData('nlm34:namePart[@type="termsOfAddress"]');
         if ($termsOfAddress) {
             $authorDescription->addStatement('namePart[@type="termsOfAddress"]', $termsOfAddress);
         }
         // Date (unmapped field)
         $date = $author->getData('nlm34:namePart[@type="date"]');
         if ($date) {
             $authorDescription->addStatement('namePart[@type="date"]', $date);
         }
         // Role
         $authorDescription->addStatement('role/roleTerm[@type="code" @authority="marcrelator"]', $authorMarcrelatorRole);
         // Add the author to the MODS schema.
         $mods34Description->addStatement('name', $authorDescription);
         unset($authorDescription);
     }
     // Sponsor
     // NB: Our MODS mapping currently doesn't support translation for names.
     // This can be added when required by data consumers. We therefore only use
     // translations in the cataloging language.
     $supportingAgency = $submission->getSponsor($catalogingLocale);
     if ($supportingAgency) {
         $supportingAgencyDescription = new MetadataDescription('lib.pkp.plugins.metadata.mods34.schema.Mods34NameSchema', ASSOC_TYPE_AUTHOR);
         $sponsorNameType = 'corporate';
         $supportingAgencyDescription->addStatement('[@type]', $sponsorNameType);
         $supportingAgencyDescription->addStatement('namePart', $supportingAgency);
         $sponsorRole = 'spn';
         $supportingAgencyDescription->addStatement('role/roleTerm[@type="code" @authority="marcrelator"]', $sponsorRole);
         $mods34Description->addStatement('name', $supportingAgencyDescription);
     }
     // Type of resource
     $typeOfResource = 'text';
     $mods34Description->addStatement('typeOfResource', $typeOfResource);
     // Creation & copyright date
     $submissionDate = $submission->getDateSubmitted();
     if (strlen($submissionDate) >= 4) {
         $mods34Description->addStatement('originInfo/dateCreated[@encoding="w3cdtf"]', $submissionDate);
         $mods34Description->addStatement('originInfo/copyrightDate[@encoding="w3cdtf"]', substr($submissionDate, 0, 4));
     }
     // Submission language
     $submissionLanguage = Locale::get3LetterFrom2LetterIsoLanguage($submission->getLanguage());
     if (!$submissionLanguage) {
         // Assume the cataloging language by default.
         $submissionLanguage = $catalogingLanguage;
     }
     $mods34Description->addStatement('language/languageTerm[@type="code" @authority="iso639-2b"]', $submissionLanguage);
     // Pages (extent)
     $mods34Description->addStatement('physicalDescription/extent', $submission->getPages());
     // Abstract
     $localizedAbstracts =& $submission->getAbstract(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'abstract', $localizedAbstracts);
     // Discipline
     $localizedDisciplines = $submission->getDiscipline(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/topic', $localizedDisciplines);
     // Subject class
     $localizedSubjectClasses = $submission->getSubjectClass(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/topic', $localizedSubjectClasses);
     // Subject
     $localizedSubjects = $submission->getSubject(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/topic', $localizedSubjects);
     // Geographical coverage
     $localizedCoverageGeo = $submission->getCoverageGeo(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/geographic', $localizedCoverageGeo);
     // Chronological coverage
     $localizedCoverageChron = $submission->getCoverageChron(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/temporal', $localizedCoverageChron);
     // Record creation date
     $recordCreationDate = date('Y-m-d');
     $mods34Description->addStatement('recordInfo/recordCreationDate[@encoding="w3cdtf"]', $recordCreationDate);
     // Record identifier
     $mods34Description->addStatement('recordInfo/recordIdentifier[@source="pkp"]', $submission->getId());
     // Cataloging language
     $mods34Description->addStatement('recordInfo/languageOfCataloging/languageTerm[@authority="iso639-2b"]', $catalogingLanguage);
     // Handle unmapped fields.
     $this->extractUnmappedDataObjectMetadataFields($submission, $mods34Description);
     return $mods34Description;
 }
 /**
  * Create a hierarchical array that represents the MODS DOM
  * from the meta-data description.
  *
  * @param $doc XMLNode|DOMDocument the MODS document node.
  * @param $root XMLNode|DOMDocument the root node of the
  *  MODS document.
  * @param $modsDescription MetadataDescription
  * @return array a hierarchical array of XMLNode|DOMDocument objects
  *  representing the MODS document.
  */
 function &_buildDocumentHierarchy(&$doc, &$root, &$modsDescription)
 {
     // Get the MODS schema.
     $modsSchema =& $modsDescription->getMetadataSchema();
     if (is_a($modsSchema, 'ModsSchema')) {
         // Identify the cataloging language.
         assert($modsDescription->hasStatement('recordInfo/languageOfCataloging/languageTerm[@authority="iso639-2b"]'));
         $catalogingLanguage = $modsDescription->getStatement('recordInfo/languageOfCataloging/languageTerm[@authority="iso639-2b"]');
     } else {
         // This must be a MODS name schema.
         assert(is_a($modsSchema, 'ModsNameSchema'));
         $catalogingLanguage = 'undefined';
     }
     // Initialize the document hierarchy with the root node.
     $documentHierarchy = array('@branch' => &$root);
     // Find the translations required for top-level elements.
     // We need this array later because we'll have to repeat non-translated
     // values for every translated top-level element.
     $properties = $modsDescription->getProperties();
     $translations = array();
     foreach ($properties as $propertyName => $property) {
         /* @var $property MetadataProperty */
         if ($modsDescription->hasStatement($propertyName)) {
             $nodes = explode('/', $propertyName);
             $topLevelNode = array_shift($nodes);
             if (!isset($translations[$topLevelNode])) {
                 $translations[$topLevelNode] = array();
             }
             if ($property->getTranslated()) {
                 foreach ($modsDescription->getStatementTranslations($propertyName) as $locale => $value) {
                     $isoLanguage = Locale::get3LetterIsoFromLocale($locale);
                     if (!in_array($isoLanguage, $translations[$topLevelNode])) {
                         $translations[$topLevelNode][] = $isoLanguage;
                     }
                 }
             } else {
                 if (!in_array($catalogingLanguage, $translations[$topLevelNode])) {
                     $translations[$topLevelNode][] = $catalogingLanguage;
                 }
             }
         }
     }
     // Build the document hierarchy.
     foreach ($properties as $propertyName => $property) {
         /* @var $property MetadataProperty */
         if ($modsDescription->hasStatement($propertyName)) {
             // Get relevant property attributes.
             $translated = $property->getTranslated();
             $cardinality = $property->getCardinality();
             // Get the XML element hierarchy.
             $nodes = explode('/', $propertyName);
             $hierarchyDepth = count($nodes) - 1;
             // Normalize property values to an array of translated strings.
             if ($translated) {
                 // Only the main MODS schema can contain translated values.
                 assert(is_a($modsSchema, 'ModsSchema'));
                 // Retrieve the translated values of the statement.
                 $localizedValues =& $modsDescription->getStatementTranslations($propertyName);
                 // Translate the PKP locale into ISO639-2b 3-letter codes.
                 $translatedValues = array();
                 foreach ($localizedValues as $locale => $translatedValue) {
                     $isoLanguage = Locale::get3LetterIsoFromLocale($locale);
                     assert(!is_null($isoLanguage));
                     $translatedValues[$isoLanguage] = $translatedValue;
                 }
             } else {
                 // Untranslated statements will be repeated for all languages
                 // present in the top-level element.
                 $untranslatedValue =& $modsDescription->getStatement($propertyName);
                 $translatedValues = array();
                 assert(isset($translations[$nodes[0]]));
                 foreach ($translations[$nodes[0]] as $isoLanguage) {
                     $translatedValues[$isoLanguage] = $untranslatedValue;
                 }
             }
             // Normalize all values to arrays so that we can
             // handle them uniformly.
             $translatedValueArrays = array();
             foreach ($translatedValues as $isoLanguage => $translatedValue) {
                 if ($cardinality == METADATA_PROPERTY_CARDINALITY_ONE) {
                     assert(is_scalar($translatedValue));
                     $translatedValueArrays[$isoLanguage] = array(&$translatedValue);
                 } else {
                     assert(is_array($translatedValue));
                     $translatedValueArrays[$isoLanguage] =& $translatedValue;
                 }
                 unset($translatedValue);
             }
             // Add the translated values one by one to the element hierarchy.
             foreach ($translatedValueArrays as $isoLanguage => $translatedValueArray) {
                 foreach ($translatedValueArray as $translatedValue) {
                     // Add a language attribute to the top-level element if
                     // it differs from the cataloging language.
                     $translatedNodes = $nodes;
                     if ($isoLanguage != $catalogingLanguage) {
                         assert(strpos($translatedNodes[0], '[') === false);
                         $translatedNodes[0] .= '[@lang="' . $isoLanguage . '"]';
                     }
                     // Create the node hierarchy for the statement.
                     $currentNodeList =& $documentHierarchy;
                     foreach ($translatedNodes as $nodeDepth => $nodeName) {
                         // Are we at a leaf node?
                         if ($nodeDepth == $hierarchyDepth) {
                             // Is this a top-level attribute?
                             if (substr($nodeName, 0, 1) == '[') {
                                 assert($nodeDepth == 0);
                                 assert($translated == false);
                                 assert($cardinality == METADATA_PROPERTY_CARDINALITY_ONE);
                                 assert(!is_object($translatedValue));
                                 $attributeName = trim($nodeName, '[@"]');
                                 XMLCustomWriter::setAttribute($root, $attributeName, (string) $translatedValue);
                                 continue;
                             }
                             // This is a sub-element.
                             if (isset($currentNodeList[$nodeName])) {
                                 // Only properties with cardinality "many" can
                                 // have more than one leaf node.
                                 assert($cardinality == METADATA_PROPERTY_CARDINALITY_MANY);
                                 // Check that the leaf list is actually there.
                                 assert(isset($currentNodeList[$nodeName]['@leaves']));
                                 // We should never find any branch in a leaves node.
                                 assert(!isset($currentNodeList[$nodeName]['@branch']));
                             } else {
                                 // Create the leaf list in the hierarchy.
                                 $currentNodeList[$nodeName]['@leaves'] = array();
                             }
                             if (is_a($translatedValue, 'MetadataDescription')) {
                                 // Recursively process composite properties.
                                 $leafNode =& $this->_processCompositeProperty($doc, $propertyName, $translatedValue);
                             } else {
                                 // Cast scalar values to string types for XML binding.
                                 $translatedValue = (string) $translatedValue;
                                 // Create the leaf element.
                                 $leafNode =& $this->_createNode($doc, $nodeName, $translatedValue);
                             }
                             // Add the leaf element to the leaves list.
                             $currentNodeList[$nodeName]['@leaves'][] =& $leafNode;
                             unset($leafNode);
                         } else {
                             // This is a branch node.
                             // Has the branch already been created? If not: create it.
                             if (isset($currentNodeList[$nodeName])) {
                                 // Check that the branch node is actually there.
                                 assert(isset($currentNodeList[$nodeName]['@branch']));
                                 // We should never find any leaves in a branch node.
                                 assert(!isset($currentNodeList[$nodeName]['@leaves']));
                             } else {
                                 // Create the branch node.
                                 $branchNode =& $this->_createNode($doc, $nodeName);
                                 // Add the branch node list and add the new node as it's root element.
                                 $currentNodeList[$nodeName] = array('@branch' => &$branchNode);
                                 unset($branchNode);
                             }
                         }
                         // Set the node list pointer to the sub-element
                         $currentNodeList =& $currentNodeList[$nodeName];
                     }
                 }
             }
         }
     }
     return $documentHierarchy;
 }