/**
  * @covers Nlm30NameSchemaPersonStringFilter
  * @covers Nlm30PersonStringFilter
  * @depends testExecuteWithSinglePersonDescription
  */
 public function testExecuteWithMultiplePersonDescriptions($personDescription1)
 {
     $personDescription2 = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR);
     $personDescription2->addStatement('given-names', $givenNames1 = 'Bernardo');
     $personDescription2->addStatement('given-names', $givenNames2 = 'Antonio');
     $personDescription2->addStatement('surname', $surname = 'Elis');
     $personDescriptions = array($personDescription1, $personDescription2, PERSON_STRING_FILTER_ETAL);
     $nlm30NameSchemaPersonStringFilter = new Nlm30NameSchemaPersonStringFilter(PERSON_STRING_FILTER_MULTIPLE);
     self::assertEquals('Assis Jr, (Machado) de; Elis, A. (Bernardo); et al', $nlm30NameSchemaPersonStringFilter->execute($personDescriptions));
     // Test template and delimiter
     $nlm30NameSchemaPersonStringFilter->setDelimiter(':');
     $nlm30NameSchemaPersonStringFilter->setTemplate('%firstname%%initials%%prefix% %surname%%suffix%');
     self::assertEquals('Machado de Assis Jr:Bernardo A. Elis:et al', $nlm30NameSchemaPersonStringFilter->execute($personDescriptions));
 }
Пример #2
0
 /**
  * Take a structured meta-data statement and transform it into a
  * plain text value that can be displayed to the end-user.
  *
  * @param $property MetadataProperty
  * @param $value mixed
  * @return string
  */
 function _getStringValueFromMetadataStatement(&$property, &$value)
 {
     if ($property->getCardinality() == METADATA_PROPERTY_CARDINALITY_MANY && !empty($value)) {
         $allowedTypes = $property->getAllowedTypes();
         if (isset($allowedTypes[METADATA_PROPERTY_TYPE_COMPOSITE])) {
             // We currently only can transform composite
             // name arrays to strings.
             $allowedAssocTypes = $allowedTypes[METADATA_PROPERTY_TYPE_COMPOSITE];
             assert(in_array(ASSOC_TYPE_AUTHOR, $allowedAssocTypes) || in_array(ASSOC_TYPE_EDITOR, $allowedAssocTypes));
             import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30NameSchemaPersonStringFilter');
             $personStringFilter = new Nlm30NameSchemaPersonStringFilter(PERSON_STRING_FILTER_MULTIPLE);
             assert($personStringFilter->supportsAsInput($value));
             $stringValue = $personStringFilter->execute($value);
         } else {
             // We currently can't transform properties of
             // cardinality "many" to strings.
             assert(is_array($value) && count($value) <= 1);
             $stringValue = $value[0];
         }
     } else {
         $stringValue = (string) $value;
     }
     return $stringValue;
 }
 /**
  * Construct an array of search strings from a citation
  * description and an array of search templates.
  * The templates may contain the placeholders
  *  %aulast%: the first author's surname
  *  %au%:     the first author full name
  *  %title%:  the article-title (if it exists),
  *            otherwise the source
  *  %date%:   the publication year
  *  %isbn%:   ISBN
  * @param $searchTemplates an array of templates
  * @param $citationDescription MetadataDescription
  * @return array
  */
 function constructSearchStrings(&$searchTemplates, &$citationDescription)
 {
     // Convert first authors' name description to a string
     import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30NameSchemaPersonStringFilter');
     $personStringFilter = new Nlm30NameSchemaPersonStringFilter();
     // Retrieve the authors
     $firstAuthorSurname = $firstAuthor = '';
     $authors = $citationDescription->getStatement('person-group[@person-group-type="author"]');
     if (is_array($authors) && count($authors)) {
         $firstAuthorSurname = (string) $authors[0]->getStatement('surname');
         $firstAuthor = $personStringFilter->execute($authors[0]);
     }
     // Retrieve the editors
     $firstEditorSurname = $firstEditor = '';
     $editors = $citationDescription->getStatement('person-group[@person-group-type="editor"]');
     if (is_array($editors) && count($editors)) {
         $firstEditorSurname = (string) $editors[0]->getStatement('surname');
         $firstEditor = $personStringFilter->execute($editors[0]);
     }
     // Retrieve (default language) title
     $title = (string) ($citationDescription->hasStatement('article-title') ? $citationDescription->getStatement('article-title') : $citationDescription->getStatement('source'));
     // Extract the year from the publication date
     $year = (string) $citationDescription->getStatement('date');
     $year = String::strlen($year) > 4 ? String::substr($year, 0, 4) : $year;
     // Retrieve ISBN
     $isbn = (string) $citationDescription->getStatement('isbn');
     // Replace the placeholders in the templates
     $searchStrings = array();
     foreach ($searchTemplates as $searchTemplate) {
         // Try editors and authors separately
         $searchStrings[] = str_replace(array('%aulast%', '%au%', '%title%', '%date%', '%isbn%'), array($firstAuthorSurname, $firstAuthor, $title, $year, $isbn), $searchTemplate);
         $searchStrings[] = str_replace(array('%aulast%', '%au%', '%title%', '%date%', '%isbn%'), array($firstEditorSurname, $firstEditor, $title, $year, $isbn), $searchTemplate);
     }
     // Remove empty or duplicate searches
     $searchStrings = array_map(array('String', 'trimPunctuation'), $searchStrings);
     $searchStrings = array_unique($searchStrings);
     $searchStrings = arrayClean($searchStrings);
     return $searchStrings;
 }
 /**
  * Map NLM properties to OpenURL properties.
  * NB: OpenURL has no i18n so we use the default
  * locale when mapping.
  * @see Filter::process()
  * @param $input MetadataDescription
  * @return MetadataDescription
  */
 function &process(&$input)
 {
     $nullVar = null;
     // Identify the genre of the target record and
     // instantiate the target description.
     $publicationType = $input->getStatement('[@publication-type]');
     switch ($publicationType) {
         case NLM30_PUBLICATION_TYPE_JOURNAL:
         case NLM30_PUBLICATION_TYPE_CONFPROC:
             $outputSchemaName = 'lib.pkp.plugins.metadata.openurl10.schema.Openurl10JournalSchema';
             break;
         case NLM30_PUBLICATION_TYPE_BOOK:
             $outputSchemaName = 'lib.pkp.plugins.metadata.openurl10.schema.Openurl10BookSchema';
             break;
         case NLM30_PUBLICATION_TYPE_THESIS:
             $outputSchemaName = 'lib.pkp.plugins.metadata.openurl10.schema.Openurl10DissertationSchema';
             break;
         default:
             // Unsupported type
             return $nullVar;
     }
     // Create the target description
     $output = new MetadataDescription($outputSchemaName, $input->getAssocType());
     // Transform authors
     import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30NameSchemaPersonStringFilter');
     $personStringFilter = new Nlm30NameSchemaPersonStringFilter();
     $authors =& $input->getStatement('person-group[@person-group-type="author"]');
     if (is_array($authors) && count($authors)) {
         $aulast = $authors[0]->hasStatement('prefix') ? $authors[0]->getStatement('prefix') . ' ' : '';
         $aulast .= $authors[0]->getStatement('surname');
         if (!empty($aulast)) {
             $success = $output->addStatement('aulast', $aulast);
             assert($success);
         }
         $givenNames = $authors[0]->getStatement('given-names');
         if (is_array($givenNames) && count($givenNames)) {
             $aufirst = implode(' ', $givenNames);
             if (!empty($aufirst)) {
                 $success = $output->addStatement('aufirst', $aufirst);
                 assert($success);
             }
             $initials = array();
             foreach ($givenNames as $givenName) {
                 $initials[] = substr($givenName, 0, 1);
             }
             $auinit1 = array_shift($initials);
             if (!empty($auinit1)) {
                 $success = $output->addStatement('auinit1', $auinit1);
                 assert($success);
             }
             $auinitm = implode('', $initials);
             if (!empty($auinitm)) {
                 $success = $output->addStatement('auinitm', $auinitm);
                 assert($success);
             }
             $auinit = $auinit1 . $auinitm;
             if (!empty($auinit)) {
                 $success = $output->addStatement('auinit', $auinit);
                 assert($success);
             }
         }
         $ausuffix = $authors[0]->getStatement('suffix');
         if (!empty($ausuffix)) {
             $success = $output->addStatement('ausuffix', $ausuffix);
             assert($success);
         }
         foreach ($authors as $author) {
             if ($author == PERSON_STRING_FILTER_ETAL) {
                 $au = $author;
             } else {
                 $au = $personStringFilter->execute($author);
             }
             $success = $output->addStatement('au', $au);
             assert($success);
             unset($au);
         }
     }
     // Genre: Guesswork
     if (is_a($output->getMetadataSchema(), 'Openurl10JournalBookBaseSchema')) {
         switch ($publicationType) {
             case NLM30_PUBLICATION_TYPE_JOURNAL:
                 $genre = $input->hasProperty('article-title') ? OPENURL10_GENRE_ARTICLE : OPENURL10_GENRE_JOURNAL;
                 break;
             case NLM30_PUBLICATION_TYPE_CONFPROC:
                 $genre = $input->hasProperty('article-title') ? OPENURL10_GENRE_PROCEEDING : OPENURL10_GENRE_CONFERENCE;
                 break;
             case NLM30_PUBLICATION_TYPE_BOOK:
                 $genre = $input->hasProperty('article-title') ? OPENURL10_GENRE_BOOKITEM : OPENURL10_GENRE_BOOK;
                 break;
         }
         assert(!empty($genre));
         $success = $output->addStatement('genre', $genre);
         assert($success);
     }
     // Map remaining properties (NLM => OpenURL)
     $propertyMap =& $this->nlmOpenurl10Mapping($publicationType, $output->getMetadataSchema());
     // Transfer mapped properties with default locale
     foreach ($propertyMap as $nlm30Property => $openurl10Property) {
         if ($input->hasStatement($nlm30Property)) {
             $success = $output->addStatement($openurl10Property, $input->getStatement($nlm30Property));
             assert($success);
         }
     }
     return $output;
 }
 /**
  * @see Filter::process()
  * @param $citationDescription MetadataDescription
  * @return MetadataDescription
  */
 function &process(&$citationDescription)
 {
     $pmid = $citationDescription->getStatement('pub-id[@pub-id-type="pmid"]');
     // If the citation does not have a PMID, try to get one from eSearch
     // otherwise skip directly to eFetch.
     if (empty($pmid)) {
         // Initialize search result arrays.
         $pmidArrayFromAuthorsSearch = $pmidArrayFromTitleSearch = $pmidArrayFromStrictSearch = array();
         // 1) Try a "loose" search based on the author list.
         //    (This works surprisingly well for pubmed.)
         $authors =& $citationDescription->getStatement('person-group[@person-group-type="author"]');
         if (is_array($authors)) {
             import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30NameSchemaPersonStringFilter');
             $personNameFilter = new Nlm30NameSchemaPersonStringFilter(PERSON_STRING_FILTER_MULTIPLE, '%firstname%%initials%%prefix% %surname%%suffix%', ', ');
             $authorsString = (string) $personNameFilter->execute($authors);
             if (!empty($authorsString)) {
                 $pmidArrayFromAuthorsSearch =& $this->_search($authorsString);
             }
         }
         // 2) Try a "loose" search based on the article title
         $articleTitle = (string) $citationDescription->getStatement('article-title');
         if (!empty($articleTitle)) {
             $pmidArrayFromTitleSearch =& $this->_search($articleTitle);
         }
         // 3) Try a "strict" search based on as much information as possible
         $searchProperties = array('article-title' => '', 'person-group[@person-group-type="author"]' => '[Auth]', 'source' => '[Jour]', 'date' => '[DP]', 'volume' => '[VI]', 'issue' => '[IP]', 'fpage' => '[PG]');
         $searchTerms = '';
         $statements = $citationDescription->getStatements();
         foreach ($searchProperties as $nlm30Property => $pubmedProperty) {
             if (isset($statements[$nlm30Property])) {
                 if (!empty($searchTerms)) {
                     $searchTerms .= ' AND ';
                 }
                 // Special treatment for authors
                 if ($nlm30Property == 'person-group[@person-group-type="author"]') {
                     assert(isset($statements['person-group[@person-group-type="author"]'][0]));
                     $firstAuthor =& $statements['person-group[@person-group-type="author"]'][0];
                     // Add surname
                     $searchTerms .= (string) $firstAuthor->getStatement('surname');
                     // Add initial of the first given name
                     $givenNames = $firstAuthor->getStatement('given-names');
                     if (is_array($givenNames)) {
                         $searchTerms .= ' ' . String::substr($givenNames[0], 0, 1);
                     }
                 } else {
                     $searchTerms .= $citationDescription->getStatement($nlm30Property);
                 }
                 $searchTerms .= $pubmedProperty;
             }
         }
         $pmidArrayFromStrictSearch =& $this->_search($searchTerms);
         // TODO: add another search like strict, but without article title
         // e.g.  ...term=Baumgart+Dc[Auth]+AND+Lancet[Jour]+AND+2005[DP]+AND+366[VI]+AND+9492[IP]+AND+1210[PG]
         // Compare the arrays to try to narrow it down to one PMID
         switch (true) {
             // strict search has a single result
             case count($pmidArrayFromStrictSearch) == 1:
                 $pmid = $pmidArrayFromStrictSearch[0];
                 break;
                 // 3-way union
             // 3-way union
             case count($intersect = array_intersect($pmidArrayFromTitleSearch, $pmidArrayFromAuthorsSearch, $pmidArrayFromStrictSearch)) == 1:
                 $pmid = current($intersect);
                 break;
                 // 2-way union: title / strict
             // 2-way union: title / strict
             case count($pmid_2way1 = array_intersect($pmidArrayFromTitleSearch, $pmidArrayFromStrictSearch)) == 1:
                 $pmid = current($pmid_2way1);
                 break;
                 // 2-way union: authors / strict
             // 2-way union: authors / strict
             case count($pmid_2way2 = array_intersect($pmidArrayFromAuthorsSearch, $pmidArrayFromStrictSearch)) == 1:
                 $pmid = current($pmid_2way2);
                 break;
                 // 2-way union: authors / title
             // 2-way union: authors / title
             case count($pmid_2way3 = array_intersect($pmidArrayFromAuthorsSearch, $pmidArrayFromTitleSearch)) == 1:
                 $pmid = current($pmid_2way3);
                 break;
                 // we only have one result for title
             // we only have one result for title
             case count($pmidArrayFromTitleSearch) == 1:
                 $pmid = $pmidArrayFromTitleSearch[0];
                 break;
                 // we only have one result for authors
             // we only have one result for authors
             case count($pmidArrayFromAuthorsSearch) == 1:
                 $pmid = $pmidArrayFromAuthorsSearch[0];
                 break;
                 // we were unable to find a PMID
             // we were unable to find a PMID
             default:
                 $pmid = '';
         }
     }
     // If we have a PMID, get a metadata array for it
     if (!empty($pmid)) {
         $citationDescription =& $this->_lookup($pmid);
         return $citationDescription;
     }
     // Nothing found
     $nullVar = null;
     return $nullVar;
 }