Inheritance: extends Nlm30PersonStringFilter
 /**
  * @covers PersonStringNlm30NameSchemaFilter
  * @covers Nlm30PersonStringFilter
  * @depends testExecuteWithSinglePersonString
  */
 public function testExecuteWithMultiplePersonsStrings()
 {
     $personsString = 'MULLER:IFC Peterberg:Peters HC:Yu QK:Hans Peter B. Sperling:et al';
     $expectedResults = array(array(null, null, null, 'Muller'), array(null, array('I', 'F', 'C'), null, 'Peterberg'), array(null, array('H', 'C'), null, 'Peters'), array(null, array('Q', 'K'), null, 'Yu'), array(null, array('Hans', 'Peter', 'B'), null, 'Sperling'));
     $personStringNlm30NameSchemaFilter = new PersonStringNlm30NameSchemaFilter(ASSOC_TYPE_AUTHOR, PERSON_STRING_FILTER_MULTIPLE);
     $personDescriptions =& $personStringNlm30NameSchemaFilter->execute($personsString);
     // The last description should be an 'et-al' string
     self::assertEquals(PERSON_STRING_FILTER_ETAL, array_pop($personDescriptions));
     foreach ($personDescriptions as $testNumber => $personDescription) {
         $this->assertPerson($expectedResults[$testNumber], $personDescription, $testNumber);
     }
     // Test again, this time with title and degrees
     $personsString = 'Dr. MULLER; IFC Peterberg; Prof. Peters HC, MSc.; Yu QK;Hans Peter B. Sperling; etal';
     $expectedResults = array(array('Dr.', null, null, 'Muller'), array(null, array('I', 'F', 'C'), null, 'Peterberg'), array('Prof. - MSc', array('H', 'C'), null, 'Peters'), array(null, array('Q', 'K'), null, 'Yu'), array(null, array('Hans', 'Peter', 'B'), null, 'Sperling'));
     $personStringNlm30NameSchemaFilter->setFilterTitle(true);
     $personStringNlm30NameSchemaFilter->setFilterDegrees(true);
     $personDescriptions =& $personStringNlm30NameSchemaFilter->execute($personsString);
     // The last description should be an 'et-al' string
     self::assertEquals(PERSON_STRING_FILTER_ETAL, array_pop($personDescriptions));
     foreach ($personDescriptions as $testNumber => $personDescription) {
         $this->assertPerson($expectedResults[$testNumber], $personDescription, $testNumber);
     }
     // Test whether Vancouver style comma separation works correctly
     $personsString = 'Peterberg IFC, Peters HC, Sperling HP';
     $expectedResults = array(array(null, array('I', 'F', 'C'), null, 'Peterberg'), array(null, array('H', 'C'), null, 'Peters'), array(null, array('H', 'P'), null, 'Sperling'));
     $personStringNlm30NameSchemaFilter->setFilterTitle(false);
     $personStringNlm30NameSchemaFilter->setFilterDegrees(false);
     $personDescriptions =& $personStringNlm30NameSchemaFilter->execute($personsString);
     foreach ($personDescriptions as $testNumber => $personDescription) {
         $this->assertPerson($expectedResults[$testNumber], $personDescription, $testNumber);
     }
     // Single name strings should not be cut when separated by comma.
     $personsString = 'Willinsky, John';
     $expectedResult = array(null, array('John'), null, 'Willinsky');
     $personDescriptions =& $personStringNlm30NameSchemaFilter->execute($personsString);
     $this->assertEquals(1, count($personDescriptions));
     $this->assertPerson($expectedResult, $personDescriptions[0], $testNumber);
     // Test APA style author tokenization.
     $singleAuthor = array(1 => 'Berndt, T. J.');
     $twoAuthors = array(2 => 'Wegener-Prent, D. T., & Petty, R. E.');
     $threeToSevenAuthors = array(6 => 'Kernis Wettelberger, M. H., Cornell, D. P., Sun, C. R., Berry, A., Harlow, T., & Bach, J. S.');
     $moreThanSevenAuthors = array(7 => 'Miller, F. H., Choi, M.J., Angeli, L. L., Harland, A. A., Stamos, J. A., Thomas, S. T., . . . Rubin, L. H.');
     $singleEditor = array(1 => 'A. Editor');
     $twoEditors = array(2 => 'A. Editor-Double & B. Editor');
     $threeToSevenEditors = array(6 => 'M.H. Kernis Wettelberger, D. P. Cornell, C.R. Sun, A. Berry, T. Harlow & J.S. Bach');
     $moreThanSevenEditors = array(7 => 'F. H. Miller, M. J. Choi, L. L. Angeli, A. A. Harland, J. A. Stamos, S. T. Thomas . . . L. H. Rubin');
     foreach (array($singleAuthor, $twoAuthors, $threeToSevenAuthors, $moreThanSevenAuthors, $singleEditor, $twoEditors, $threeToSevenEditors, $moreThanSevenEditors) as $test) {
         $expectedNumber = key($test);
         $testString = current($test);
         $personDescriptions =& $personStringNlm30NameSchemaFilter->execute($testString);
         $this->assertEquals($expectedNumber, count($personDescriptions), 'Offending string: ' . $testString);
     }
 }
 /**
  * Map OpenURL properties to NLM 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;
     // Instantiate the target description.
     $output = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', $input->getAssocType());
     // Parse au statements into name descriptions
     import('lib.pkp.plugins.metadata.nlm30.filter.PersonStringNlm30NameSchemaFilter');
     $personStringFilter = new PersonStringNlm30NameSchemaFilter(ASSOC_TYPE_AUTHOR);
     $authors =& $input->getStatement('au');
     if (is_array($authors) && count($authors)) {
         // TODO: We might improve results here by constructing the
         // first author from aufirst, aulast fields.
         foreach ($authors as $author) {
             $authorDescription =& $personStringFilter->execute($author);
             $success = $output->addStatement('person-group[@person-group-type="author"]', $authorDescription);
             assert($success);
             unset($authorDescription);
         }
     }
     // Publication type
     $publicationType = null;
     if ($input->hasStatement('genre')) {
         $genre = $input->getStatement('genre');
         $genreMap = $this->_getOpenurl10GenreTranslationMapping();
         $publicationType = isset($genreMap[$genre]) ? $genreMap[$genre] : $genre;
         $success = $output->addStatement('[@publication-type]', $publicationType);
         assert($success);
     }
     // Get NLM => OpenURL property mapping.
     $propertyMap =& $this->nlmOpenurl10Mapping($publicationType, $input->getMetadataSchema());
     // Transfer mapped properties with default locale
     foreach ($propertyMap as $nlm30Property => $openurl10Property) {
         if ($input->hasStatement($openurl10Property)) {
             $success = $output->addStatement($nlm30Property, $input->getStatement($openurl10Property));
             assert($success);
         }
     }
     return $output;
 }
Ejemplo n.º 3
0
 /**
  * Custom implementation of Form::validate() that validates
  * meta-data form data and injects it into the internal citation
  * object.
  *
  * NB: The configuration of the internal citation object
  * would normally be done in readInputData(). Validation and
  * injection can easily be done in one step. It therefore avoids
  * code duplication and improves performance to do both here.
  */
 function validate()
 {
     // Make sure that this method is not called twice which
     // would corrupt internal state.
     assert(empty($this->_metadataDescriptions));
     parent::validate();
     // Validate form data and inject it into
     // the associated citation object.
     $citation =& $this->getCitation();
     $citation->setRawCitation($this->getData('rawCitation'));
     if ($this->getData('citationApproved') == 'citationApproved') {
         // Editor's shortcut to the approved state, e.g. for manually edited citations.
         $citation->setCitationState(CITATION_APPROVED);
     } elseif (in_array($this->getData('citationState'), Citation::_getSupportedCitationStates())) {
         // Reset citation state if necessary
         if ($this->getData('citationState') == CITATION_APPROVED) {
             $this->setData('citationState', CITATION_LOOKED_UP);
         }
         $citation->setCitationState($this->getData('citationState'));
     }
     // Extract data from citation form fields and inject it into the citation
     import('lib.pkp.classes.metadata.MetadataDescription');
     $metadataSchemas = $citation->getSupportedMetadataSchemas();
     foreach ($metadataSchemas as $metadataSchema) {
         /* @var $metadataSchema MetadataSchema */
         // Instantiate a meta-data description for the given schema
         $metadataDescription = new MetadataDescription($metadataSchema->getClassName(), ASSOC_TYPE_CITATION);
         // Set the meta-data statements
         foreach ($metadataSchema->getProperties() as $propertyName => $property) {
             $fieldName = $metadataSchema->getNamespacedPropertyId($propertyName);
             $fieldValue = trim($this->getData($fieldName));
             if (empty($fieldValue)) {
                 // Delete empty statements so that previously set
                 // statements (if any) will be deleted.
                 $metadataDescription->removeStatement($propertyName);
                 if ($property->getMandatory()) {
                     // A mandatory field is missing - add a validation error.
                     $this->addError($fieldName, __($property->getValidationMessage()));
                     $this->addErrorField($fieldName);
                 }
             } else {
                 // Try to convert the field value to (a) strongly
                 // typed object(s) if applicable. Start with the most
                 // specific allowed type so that we always get the
                 // most strongly typed result possible.
                 $allowedTypes = $property->getAllowedTypes();
                 switch (true) {
                     case isset($allowedTypes[METADATA_PROPERTY_TYPE_VOCABULARY]) && is_numeric($fieldValue):
                     case isset($allowedTypes[METADATA_PROPERTY_TYPE_INTEGER]) && is_numeric($fieldValue):
                         $typedFieldValues = array((int) $fieldValue);
                         break;
                     case isset($allowedTypes[METADATA_PROPERTY_TYPE_DATE]):
                         import('lib.pkp.classes.metadata.DateStringNormalizerFilter');
                         $dateStringFilter = new DateStringNormalizerFilter();
                         assert($dateStringFilter->supportsAsInput($fieldValue));
                         $typedFieldValues = array($dateStringFilter->execute($fieldValue));
                         break;
                     case isset($allowedTypes[METADATA_PROPERTY_TYPE_COMPOSITE]):
                         // We currently only support name composites
                         $allowedAssocIds = $allowedTypes[METADATA_PROPERTY_TYPE_COMPOSITE];
                         if (in_array(ASSOC_TYPE_AUTHOR, $allowedAssocIds)) {
                             $assocType = ASSOC_TYPE_AUTHOR;
                         } elseif (in_array(ASSOC_TYPE_EDITOR, $allowedAssocIds)) {
                             $assocType = ASSOC_TYPE_EDITOR;
                         } else {
                             assert(false);
                         }
                         // Try to transform the field to a name composite.
                         import('lib.pkp.plugins.metadata.nlm30.filter.PersonStringNlm30NameSchemaFilter');
                         $personStringFilter = new PersonStringNlm30NameSchemaFilter($assocType, PERSON_STRING_FILTER_MULTIPLE);
                         assert($personStringFilter->supportsAsInput($fieldValue));
                         $typedFieldValues =& $personStringFilter->execute($fieldValue);
                         break;
                     default:
                         $typedFieldValues = array($fieldValue);
                 }
                 // Inject data into the meta-data description and thereby
                 // implicitly validate the field value.
                 foreach ($typedFieldValues as $typedFieldValue) {
                     if (!$metadataDescription->addStatement($propertyName, $typedFieldValue)) {
                         // Add form field error
                         $this->addError($fieldName, __($property->getValidationMessage()));
                         $this->addErrorField($fieldName);
                     }
                     unset($typedFieldValue);
                 }
                 unset($typedFieldValues);
             }
         }
         // Inject the meta-data into the citation.
         $citation->injectMetadata($metadataDescription);
         // Save the meta-data description for later usage.
         $this->_metadataDescriptions[] =& $metadataDescription;
         unset($metadataDescription);
     }
     return $this->isValid();
 }
 /**
  * Post processes an NLM meta-data array
  * @param $preliminaryNlm30Array array
  * @return array
  */
 function &postProcessMetadataArray(&$preliminaryNlm30Array)
 {
     // Clean array
     $preliminaryNlm30Array = arrayClean($preliminaryNlm30Array);
     // Trim punctuation
     $preliminaryNlm30Array =& $this->_recursivelyTrimPunctuation($preliminaryNlm30Array);
     // Parse (=filter) author/editor strings into NLM name descriptions
     foreach (array('author' => ASSOC_TYPE_AUTHOR, 'editor' => ASSOC_TYPE_EDITOR) as $personType => $personAssocType) {
         if (isset($preliminaryNlm30Array[$personType])) {
             // Get the author/editor strings from the result
             $personStrings = $preliminaryNlm30Array[$personType];
             unset($preliminaryNlm30Array[$personType]);
             // Parse the author/editor strings into NLM name descriptions
             // Interpret a scalar as a textual authors list
             if (is_scalar($personStrings)) {
                 $personStringFilter = new PersonStringNlm30NameSchemaFilter($personAssocType, PERSON_STRING_FILTER_MULTIPLE);
                 $persons =& $personStringFilter->execute($personStrings);
             } else {
                 $personStringFilter = new PersonStringNlm30NameSchemaFilter($personAssocType, PERSON_STRING_FILTER_SINGLE);
                 $persons =& array_map(array($personStringFilter, 'execute'), $personStrings);
             }
             $preliminaryNlm30Array['person-group[@person-group-type="' . $personType . '"]'] = $persons;
             unset($persons);
         }
     }
     // Join comments
     if (isset($preliminaryNlm30Array['comment']) && is_array($preliminaryNlm30Array['comment'])) {
         // Implode comments from the result into a single string
         // as required by the NLM citation schema.
         $preliminaryNlm30Array['comment'] = implode("\n", $preliminaryNlm30Array['comment']);
     }
     // Normalize date strings
     foreach (array('date', 'conf-date', 'access-date') as $dateProperty) {
         if (isset($preliminaryNlm30Array[$dateProperty])) {
             $dateFilter = new DateStringNormalizerFilter();
             $preliminaryNlm30Array[$dateProperty] = $dateFilter->execute($preliminaryNlm30Array[$dateProperty]);
         }
     }
     // Cast strings to integers where necessary
     foreach (array('fpage', 'lpage', 'size') as $integerProperty) {
         if (isset($preliminaryNlm30Array[$integerProperty]) && is_numeric($preliminaryNlm30Array[$integerProperty])) {
             $preliminaryNlm30Array[$integerProperty] = (int) $preliminaryNlm30Array[$integerProperty];
         }
     }
     // Rename elements that are stored in attributes in NLM citation
     $elementToAttributeMap = array('access-date' => 'date-in-citation[@content-type="access-date"]', 'issn-ppub' => 'issn[@pub-type="ppub"]', 'issn-epub' => 'issn[@pub-type="epub"]', 'pub-id-doi' => 'pub-id[@pub-id-type="doi"]', 'pub-id-publisher-id' => 'pub-id[@pub-id-type="publisher-id"]', 'pub-id-coden' => 'pub-id[@pub-id-type="coden"]', 'pub-id-sici' => 'pub-id[@pub-id-type="sici"]', 'pub-id-pmid' => 'pub-id[@pub-id-type="pmid"]', 'publication-type' => '[@publication-type]');
     foreach ($elementToAttributeMap as $elementName => $nlm30PropertyName) {
         if (isset($preliminaryNlm30Array[$elementName])) {
             $preliminaryNlm30Array[$nlm30PropertyName] = $preliminaryNlm30Array[$elementName];
             unset($preliminaryNlm30Array[$elementName]);
         }
     }
     // Guess a publication type if none has been set by the
     // citation service.
     $this->_guessPublicationType($preliminaryNlm30Array);
     // Some services return the title as article-title although
     // the publication type is a book.
     if (isset($preliminaryNlm30Array['[@publication-type]']) && $preliminaryNlm30Array['[@publication-type]'] == 'book') {
         if (isset($preliminaryNlm30Array['article-title']) && !isset($preliminaryNlm30Array['source'])) {
             $preliminaryNlm30Array['source'] = $preliminaryNlm30Array['article-title'];
             unset($preliminaryNlm30Array['article-title']);
         }
     }
     return $preliminaryNlm30Array;
 }