/**
  * @see MetadataDataObjectAdapter::injectMetadataIntoDataObject()
  * @param $mods34Description MetadataDescription
  * @param $submission Submission
  * @param $authorClassName string the application specific author class name
  */
 function &injectMetadataIntoDataObject(&$mods34Description, &$submission, $authorClassName)
 {
     assert(is_a($submission, 'Submission'));
     assert($mods34Description->getMetadataSchemaName() == 'plugins.metadata.mods34.schema.Mods34Schema');
     // Get the cataloging language.
     $catalogingLanguage = $mods34Description->getStatement('recordInfo/languageOfCataloging/languageTerm[@authority="iso639-2b"]');
     $catalogingLocale = Locale::getLocaleFrom3LetterIso($catalogingLanguage);
     assert(!is_null($catalogingLocale));
     // Title
     $localizedTitles = $mods34Description->getStatementTranslations('titleInfo/title');
     if (is_array($localizedTitles)) {
         foreach ($localizedTitles as $locale => $title) {
             $submission->setTitle($title, $locale);
         }
     }
     // Names: authors and sponsor
     $foundSponsor = false;
     $nameDescriptions =& $mods34Description->getStatement('name');
     if (is_array($nameDescriptions)) {
         foreach ($nameDescriptions as $nameDescription) {
             /* @var $nameDescription MetadataDescription */
             // Check that we find the expected name schema.
             assert($nameDescription->getMetadataSchemaName() == 'lib.pkp.plugins.metadata.mods34.schema.Mods34NameSchema');
             // Retrieve the name type and role.
             $nameType = $nameDescription->getStatement('[@type]');
             $nameRoles = $nameDescription->getStatement('role/roleTerm[@type="code" @authority="marcrelator"]');
             // Transport the name into the submission depending
             // on name type and role.
             // FIXME: Move this to a dedicated adapter in the Author class.
             if (is_array($nameRoles)) {
                 switch ($nameType) {
                     // Authors
                     case 'personal':
                         // Only authors go into the submission.
                         if (in_array('aut', $nameRoles)) {
                             // Instantiate a new author object.
                             import($authorClassName);
                             $author = new Author();
                             // Family Name
                             $author->setLastName($nameDescription->getStatement('namePart[@type="family"]'));
                             // Given Names
                             $givenNames = $nameDescription->getStatement('namePart[@type="given"]');
                             if (!empty($givenNames)) {
                                 $givenNames = explode(' ', $givenNames, 2);
                                 if (isset($givenNames[0])) {
                                     $author->setFirstName($givenNames[0]);
                                 }
                                 if (isset($givenNames[1])) {
                                     $author->setMiddleName($givenNames[1]);
                                 }
                             }
                             // Affiliation
                             // NB: Our MODS mapping currently doesn't support translation for names.
                             // This can be added when required by data providers. We assume the cataloging
                             // language for the record.
                             $affiliation = $nameDescription->getStatement('affiliation');
                             if (!empty($affiliation)) {
                                 $author->setAffiliation($affiliation, $catalogingLocale);
                             }
                             // Terms of address (unmapped field)
                             $termsOfAddress = $nameDescription->getStatement('namePart[@type="termsOfAddress"]');
                             if ($termsOfAddress) {
                                 $author->setData('nlm34:namePart[@type="termsOfAddress"]', $termsOfAddress);
                             }
                             // Date (unmapped field)
                             $date = $nameDescription->getStatement('namePart[@type="date"]');
                             if ($date) {
                                 $author->setData('nlm34:namePart[@type="date"]', $date);
                             }
                             // Add the author to the submission.
                             $submission->addAuthor($author);
                             unset($author);
                         }
                         break;
                         // Sponsor
                         // NB: Our MODS mapping currently doesn't support translation for names.
                         // This can be added when required by data providers. We assume the cataloging
                         // language for the record.
                     // Sponsor
                     // NB: Our MODS mapping currently doesn't support translation for names.
                     // This can be added when required by data providers. We assume the cataloging
                     // language for the record.
                     case 'corporate':
                         // Only the first sponsor goes into the submission.
                         if (!$foundSponsor && in_array('spn', $nameRoles)) {
                             $foundSponsor = true;
                             $submission->setSponsor($nameDescription->getStatement('namePart'), $catalogingLocale);
                         }
                         break;
                 }
             }
             unset($nameDescription);
         }
     }
     // Creation date
     $dateSubmitted = $mods34Description->getStatement('originInfo/dateCreated[@encoding="w3cdtf"]');
     if ($dateSubmitted) {
         $submission->setDateSubmitted($dateSubmitted);
     }
     // Submission language
     $submissionLanguage = $mods34Description->getStatement('language/languageTerm[@type="code" @authority="iso639-2b"]');
     $submissionLocale = Locale::get2LetterFrom3LetterIsoLanguage($submissionLanguage);
     if ($submissionLocale) {
         $submission->setLanguage($submissionLocale);
     }
     // Pages (extent)
     $pages = $mods34Description->getStatement('physicalDescription/extent');
     if ($pages) {
         $submission->setPages($pages);
     }
     // Abstract
     $localizedAbstracts = $mods34Description->getStatementTranslations('abstract');
     if (is_array($localizedAbstracts)) {
         foreach ($localizedAbstracts as $locale => $abstract) {
             $submission->setAbstract($abstract, $locale);
         }
     }
     // Discipline, subject class and subject
     // FIXME: We currently ignore discipline, subject class and subject because we cannot
     // distinguish them within a list of MODS topic elements. Can we use several subject
     // statements with different authorities instead?
     // Geographical coverage
     $localizedCoverageGeos = $mods34Description->getStatementTranslations('subject/geographic');
     if (is_array($localizedCoverageGeos)) {
         foreach ($localizedCoverageGeos as $locale => $localizedCoverageGeo) {
             $submission->setCoverageGeo($localizedCoverageGeo, $locale);
         }
     }
     // Chronological coverage
     $localizedCoverageChrons = $mods34Description->getStatementTranslations('subject/temporal');
     if (is_array($localizedCoverageChrons)) {
         foreach ($localizedCoverageChrons as $locale => $localizedCoverageChron) {
             $submission->setCoverageChron($localizedCoverageChron, $locale);
         }
     }
     // Record identifier
     // NB: We currently don't override the submission id with the record identifier in MODS
     // to make sure that MODS records can be transported between different installations.
     // Handle unmapped fields.
     $this->injectUnmappedDataObjectMetadataFields($mods34Description, $submission);
     return $submission;
 }
 /**
  * @covers PKPLocale
  */
 public function testGetLocaleFrom3LetterIso()
 {
     // A locale that does not have to be disambiguated.
     self::assertEquals('en_US', Locale::getLocaleFrom3LetterIso('eng'));
     // The primary locale will be used if that helps
     // to disambiguate.
     Locale::setSupportedLocales(array('en_US' => 'English', 'pt_BR' => 'Portuguese (Brazil)', 'pt_PT' => 'Portuguese (Portugal)'));
     Locale::setPrimaryLocale('pt_BR');
     self::assertEquals('pt_BR', Locale::getLocaleFrom3LetterIso('por'));
     Locale::setPrimaryLocale('pt_PT');
     self::assertEquals('pt_PT', Locale::getLocaleFrom3LetterIso('por'));
     // If the primary locale doesn't help then use the first supported locale found.
     Locale::setPrimaryLocale('en_US');
     self::assertEquals('pt_BR', Locale::getLocaleFrom3LetterIso('por'));
     Locale::setSupportedLocales(array('en_US' => 'English', 'pt_PT' => 'Portuguese (Portugal)', 'pt_BR' => 'Portuguese (Brazil)'));
     self::assertEquals('pt_PT', Locale::getLocaleFrom3LetterIso('por'));
     // If the locale isn't even in the supported localse then use the first locale found.
     Locale::setSupportedLocales(array('en_US' => 'English'));
     self::assertEquals('pt_PT', Locale::getLocaleFrom3LetterIso('por'));
     // Unknown language.
     self::assertNull(Locale::getLocaleFrom3LetterIso('xxx'));
 }