/**
  * @covers MetadataDescriptionDummyAdapter
  */
 public function testMetadataDescriptionDummyAdapter()
 {
     $schema = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema';
     // Instantiate a test description.
     $originalDescription = new MetadataDescription($schema, ASSOC_TYPE_CITATION);
     $originalDescription->addStatement('source', $originalTitle = 'original source');
     $originalDescription->addStatement('article-title', $originalTitle = 'original title');
     // Test constructor.
     $adapter = new MetadataDescriptionDummyAdapter($originalDescription);
     self::assertEquals(ASSOC_TYPE_CITATION, $adapter->getAssocType());
     self::assertEquals($schema, $adapter->getMetadataSchemaName());
     self::assertInstanceOf('Nlm30CitationSchema', $adapter->getMetadataSchema());
     // Test metadata injection.
     $sourceDescription = new MetadataDescription($schema, ASSOC_TYPE_CITATION);
     $sourceDescription->addStatement('article-title', $injectedTitle = 'injected title');
     $resultDescription =& $adapter->injectMetadataIntoDataObject($sourceDescription, $originalDescription);
     $expectedResult = array('source' => array('en_US' => 'original source'), 'article-title' => array('en_US' => 'injected title'));
     self::assertEquals($expectedResult, $resultDescription->getStatements());
     // Test meta-data extraction.
     $extractedDescription = $adapter->extractMetadataFromDataObject($originalDescription);
     self::assertEquals($originalDescription, $extractedDescription);
     // Test meta-data field names (only test one field of each
     // category (translated or not) so that the test doesn't
     // break when we expand the NLM schema).
     $fieldNames = $adapter->getMetadataFieldNames(false);
     self::assertTrue(in_array('date', $fieldNames));
     // NB: no namespace pre-fix in this case!
     $fieldNames = $adapter->getMetadataFieldNames(true);
     self::assertTrue(in_array('article-title', $fieldNames));
 }
 /**
  * Creates a test description in Openurl10 format
  * @return MetadataDescription
  */
 protected function getTestOpenurl10Description()
 {
     $citationData = array('aulast' => 'von Surname1', 'aufirst' => 'Given1 P', 'auinit1' => 'G', 'auinitm' => 'P', 'auinit' => 'GP', 'ausuffix' => 'suff', 'au' => array(0 => 'Surname1 suff, P. (Given1) von', 1 => 'Surname2, (Given2)'), 'genre' => 'article', 'jtitle' => 'Some Journal Title', 'atitle' => 'Some Article Title', 'date' => '2005-07-03', 'issn' => '0694760949645', 'spage' => 17, 'epage' => 33, 'volume' => '7', 'issue' => '5', 'eissn' => '3049674960475', 'artnum' => '45', 'coden' => 'coden', 'sici' => 'sici');
     $openurl10Description = new MetadataDescription('lib.pkp.plugins.metadata.openurl10.schema.Openurl10JournalSchema', ASSOC_TYPE_CITATION);
     self::assertTrue($openurl10Description->setStatements($citationData));
     return $openurl10Description;
 }
 private function serializeCitationDescription(MetadataDescription &$citationDescription)
 {
     // Prepare transformation tables for the output serialization:
     // - the following lines will be deleted from our output file
     static $linesToDelete = array('    [0-9]+ => ', '    array \\(', '      \'_data\' => ', '    \\),');
     // Transform person descriptions to arrays
     $citationDescriptionArray = $citationDescription->getStatements();
     $personDescriptionProperties = array('person-group[@person-group-type="author"]', 'person-group[@person-group-type="editor"]');
     foreach ($personDescriptionProperties as $personDescriptionProperty) {
         if (isset($citationDescriptionArray[$personDescriptionProperty])) {
             foreach ($citationDescriptionArray[$personDescriptionProperty] as &$person) {
                 $person = $person->getStatements();
             }
         }
     }
     // Transform the result into an array that we can serialize
     // in a human-readable form and also re-import as PHP-parsable code.
     $citationDescriptionOutput = var_export($citationDescriptionArray, true);
     $citationDescriptionOutputArray = explode("\n", $citationDescriptionOutput);
     foreach ($citationDescriptionOutputArray as $key => &$citationDescriptionOutputLine) {
         // Remove redundant lines
         foreach ($linesToDelete as $lineToDelete) {
             if (preg_match('/^' . $lineToDelete . '$/', $citationDescriptionOutputLine)) {
                 unset($citationDescriptionOutputArray[$key]);
             }
         }
         // Correctly indent the output line
         $citationDescriptionOutputLine = "\t\t\t" . preg_replace('/^\\t\\t\\t/', "\t\t", str_replace('  ', "\t", $citationDescriptionOutputLine));
     }
     // Create the final serialized format
     return implode("\n", $citationDescriptionOutputArray);
 }
 /**
  * @covers Nlm30CitationSchemaCitationAdapter
  */
 public function testNlm30CitationSchemaCitationAdapter()
 {
     // Test constructor.
     $adapter = new Nlm30CitationSchemaCitationAdapter(PersistableFilter::tempGroup('metadata::lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema(CITATION)', 'class::lib.pkp.classes.citation.Citation'));
     self::assertEquals(ASSOC_TYPE_CITATION, $adapter->getAssocType());
     self::assertType('Nlm30CitationSchema', $adapter->getMetadataSchema());
     self::assertEquals('Citation', $adapter->getDataObjectClass());
     // Instantiate a test description.
     $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR);
     $authorDescription->addStatement('surname', $surname = 'some surname');
     $citationDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('article-title', $articleTitle = 'article title');
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $authorDescription);
     // Instantiate test citation.
     $citation = new Citation();
     // Test metadata injection.
     $resultCitation =& $adapter->injectMetadataIntoDataObject($citationDescription, $citation);
     $expectedResult = array('rawCitation' => '', 'nlm30:person-group[@person-group-type="author"]' => array(array('surname' => 'some surname')), 'nlm30:article-title' => array('en_US' => 'article title'));
     self::assertEquals($expectedResult, $resultCitation->getAllData());
     // Instantiate and inject a second test description.
     $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR);
     $authorDescription->addStatement('surname', $anotherSurname = 'another surname');
     $secondDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', ASSOC_TYPE_CITATION);
     $secondDescription->addStatement('person-group[@person-group-type="author"]', $authorDescription);
     $secondDescription->addStatement('source', $source = 'some source');
     $resultCitation =& $adapter->injectMetadataIntoDataObject($secondDescription, $citation);
     $expectedResult = array('rawCitation' => '', 'nlm30:person-group[@person-group-type="author"]' => array(array('surname' => 'another surname')), 'nlm30:article-title' => array('en_US' => 'article title'), 'nlm30:source' => array('en_US' => 'some source'));
     self::assertEquals($expectedResult, $resultCitation->getAllData());
     // Test meta-data extraction.
     $adapter = new Nlm30CitationSchemaCitationAdapter(PersistableFilter::tempGroup('class::lib.pkp.classes.citation.Citation', 'metadata::lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema(CITATION)'));
     $extractedDescription =& $adapter->extractMetadataFromDataObject($resultCitation);
     $secondDescription->addStatement('article-title', $articleTitle = 'article title');
     self::assertEquals($secondDescription, $extractedDescription);
 }
 /**
  * @covers PKPSubmissionNlm30XmlFilter
  */
 public function testExecute()
 {
     // Instantiate test meta-data for a citation.
     import('lib.pkp.classes.metadata.MetadataDescription');
     $nameSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema';
     $nameDescription = new MetadataDescription($nameSchemaName, ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $citationSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema';
     $citationDescription = new MetadataDescription($citationSchemaName, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('date', $value = '2009-08-17');
     $citationDescription->addStatement('size', $value = 320);
     $citationDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     $citationDescription->addStatement('[@publication-type]', $value = 'book');
     $citation =& $this->getCitation($citationDescription);
     // Persist a few copies of the citation for testing.
     $citationDao =& $this->getCitationDao();
     for ($seq = 1; $seq <= 10; $seq++) {
         $citation->setSeq($seq);
         $citation->setCitationState(CITATION_APPROVED);
         $citationId = $citationDao->insertObject($citation);
         self::assertTrue(is_numeric($citationId));
         self::assertTrue($citationId > 0);
     }
     // Execute the filter and check the outcome.
     $mockSubmission =& $this->getTestSubmission();
     // FIXME: Add NLM 3.0 tag set schema validation as soon as we implement the full tag set, see #5648.
     $filter = new PKPSubmissionNlm30XmlFilter(PersistableFilter::tempGroup('class::lib.pkp.classes.submission.Submission', 'xml::*'));
     $nlm30Xml = $filter->execute($mockSubmission);
     self::assertXmlStringEqualsXmlFile('./lib/pkp/tests/plugins/metadata/nlm30/filter/sample-nlm30-citation.xml', $nlm30Xml);
 }
 /**
  * @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));
 }
예제 #7
0
 public function testCitationCrud()
 {
     $nameSchema = new NlmNameSchema();
     $nameDescription = new MetadataDescription($nameSchema, ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $citationSchema = new NlmCitationSchema();
     $citationDescription = new MetadataDescription($citationSchema, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in Kürze', 'de_DE');
     $citationDescription->addStatement('date', $value = '2009-08-17');
     $citationDescription->addStatement('size', $value = 320);
     $citationDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     $citation = new Citation('raw citation');
     $citation->setAssocType(ASSOC_TYPE_ARTICLE);
     $citation->setAssocId(5);
     $citation->setEditedCitation('edited citation');
     $citation->setParseScore(50);
     $citation->injectMetadata($citationDescription);
     $citationId = $this->citationDAO->insertCitation($citation);
     self::assertTrue(is_numeric($citationId));
     self::assertTrue($citationId > 0);
 }
 /**
  * @covers NlmNameSchemaPersonStringFilter::supports
  * @covers NlmNameSchemaPersonStringFilter::execute
  * @covers NlmNameSchemaPersonStringFilter::isValid
  * @covers NlmNameSchemaPersonStringFilter::_flattenPersonsDescriptions
  * @depends testExecuteWithSinglePersonDescription
  */
 public function testExecuteWithMultiplePersonDescriptions($personDescription1)
 {
     $nlmNameSchema = new NlmNameSchema();
     $personDescription2 = new MetadataDescription($nlmNameSchema, ASSOC_TYPE_AUTHOR);
     $personDescription2->addStatement('given-names', $givenNames1 = 'Bernardo');
     $personDescription2->addStatement('given-names', $givenNames2 = 'Antonio');
     $personDescription2->addStatement('surname', $surname = 'Elis');
     $personDescriptions = array($personDescription1, $personDescription2);
     $this->_nlmNameSchemaPersonStringFilter->setFilterMode(PERSON_STRING_FILTER_MULTIPLE);
     self::assertEquals('Assis Jr, (Machado) de; Elis, A. (Bernardo)', $this->_nlmNameSchemaPersonStringFilter->execute($personDescriptions));
     // Test template and delimiter
     $this->_nlmNameSchemaPersonStringFilter->setDelimiter(':');
     $this->_nlmNameSchemaPersonStringFilter->setTemplate('%firstname%%initials%%prefix% %surname%%suffix%');
     self::assertEquals('Machado de Assis Jr:Bernardo A. Elis', $this->_nlmNameSchemaPersonStringFilter->execute($personDescriptions));
 }
예제 #9
0
 public function testCitationCrud()
 {
     $nameSchema = new NlmNameSchema();
     $nameDescription = new MetadataDescription($nameSchema, ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $citationSchema = new NlmCitationSchema();
     $citationDescription = new MetadataDescription($citationSchema, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in Kürze', 'de_DE');
     $citationDescription->addStatement('date', $value = '2009-08-17');
     $citationDescription->addStatement('size', $value = 320);
     $citationDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     $citation = new Citation('raw citation');
     $citation->setAssocType(ASSOC_TYPE_ARTICLE);
     $citation->setAssocId(999999);
     $citation->setEditedCitation('edited citation');
     $citation->setParseScore(50);
     $citation->injectMetadata($citationDescription);
     // Create citation
     $citationId = $this->citationDAO->insertCitation($citation);
     self::assertTrue(is_numeric($citationId));
     self::assertTrue($citationId > 0);
     // Retrieve citation
     $citationById = $this->citationDAO->getCitation($citationId);
     $citationById->getMetadataFieldNames();
     // Initializes internal state for comparison.
     self::assertEquals($citation, $citationById);
     $citationsByAssocIdDaoFactory = $this->citationDAO->getCitationsByAssocId(ASSOC_TYPE_ARTICLE, 999999);
     $citationsByAssocId = $citationsByAssocIdDaoFactory->toArray();
     self::assertEquals(1, count($citationsByAssocId));
     $citationsByAssocId[0]->getMetadataFieldNames();
     // Initializes internal state for comparison.
     self::assertEquals($citation, $citationsByAssocId[0]);
     // Update citation
     $citationDescription->removeStatement('date');
     $citationDescription->addStatement('article-title', $value = 'PHPUnit rápido', 'pt_BR');
     $updatedCitation = new Citation('another raw citation');
     $updatedCitation->setId($citationId);
     $updatedCitation->setAssocType(ASSOC_TYPE_ARTICLE);
     $updatedCitation->setAssocId(999998);
     $updatedCitation->setEditedCitation('another edited citation');
     $updatedCitation->setParseScore(50);
     $updatedCitation->injectMetadata($citationDescription);
     $this->citationDAO->updateCitation($updatedCitation);
     $citationAfterUpdate = $this->citationDAO->getCitation($citationId);
     $citationAfterUpdate->getMetadataFieldNames();
     // Initializes internal state for comparison.
     self::assertEquals($updatedCitation, $citationAfterUpdate);
     // Delete citation
     $this->citationDAO->deleteCitationsByAssocId(ASSOC_TYPE_ARTICLE, 999998);
     self::assertNull($this->citationDAO->getCitation($citationId));
 }
예제 #10
0
 /**
  * This implementation of the CrosswalkFilter
  * simply removes statements from the incoming meta-data
  * description that are not in the target description's schema.
  * @see Filter::process()
  * @param $input MetadataDescription
  * @return MetadataDescription
  */
 function &process(&$input)
 {
     // Create the target description
     $output = new MetadataDescription($this->_toSchema);
     // Compare the property names of the incoming description with
     // the property names allowed in the target schema.
     $sourceProperties = $input->getSetPropertyNames();
     $targetProperties = $output->getPropertyNames();
     $propertiesToBeRemoved = array_diff($sourceProperties, $targetProperties);
     // Remove statements for properties that are not in the target schema.
     $statements =& $input->getStatements();
     foreach ($propertiesToBeRemoved as $propertyToBeRemoved) {
         assert(isset($statements[$propertyToBeRemoved]));
         unset($statements[$propertyToBeRemoved]);
     }
     // Set the remaining statements in the target description
     $success = $output->setStatements($statements);
     assert($success);
     return $output;
 }
 /**
  * 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.
     $outputSchema = new NlmCitationSchema();
     $output = new MetadataDescription($outputSchema, $input->getAssocType());
     // Parse au statements into name descriptions
     import('metadata.nlm.PersonStringNlmNameSchemaFilter');
     $personStringFilter = new PersonStringNlmNameSchemaFilter(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
     if ($input->hasStatement('genre')) {
         $genre = $input->getStatement('genre');
         $genreMap = $this->_getOpenUrlGenreTranslationMapping();
         $publicationType = isset($genreMap[$genre]) ? $genreMap[$genre] : $genre;
         $success = $output->addStatement('[@publication-type]', $publicationType);
         assert($success);
     }
     // Get NLM => OpenURL property mapping.
     $propertyMap =& $this->nlmOpenUrlMapping($publicationType, $input->getMetadataSchema());
     // Transfer mapped properties with default locale
     foreach ($propertyMap as $nlmProperty => $openUrlProperty) {
         if ($input->hasStatement($openUrlProperty)) {
             $success = $output->addStatement($nlmProperty, $input->getStatement($openUrlProperty));
             assert($success);
         }
     }
     return $output;
 }
예제 #12
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();
 }
 /**
  * @covers Nlm30Nlm23CrosswalkFilter
  */
 public function testExecute()
 {
     $this->markTestSkipped('Weird class interaction with ControlledVocabEntryDAO leads to failure');
     // Instantiate test meta-data for a citation. This must use the complete
     // available schema (although in practice this doesn't make sense) so that
     // we can make sure all tags are correctly converted.
     import('lib.pkp.classes.metadata.MetadataDescription');
     $nameSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema';
     $nameDescription = new MetadataDescription($nameSchemaName, ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $nameDescription->addStatement('suffix', $value = 'Jr');
     $citationSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema';
     $citationDescription = new MetadataDescription($citationSchemaName, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $citationDescription->addStatement('person-group[@person-group-type="editor"]', $nameDescription);
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('source', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('date', $value = '2009-08-17');
     $citationDescription->addStatement('date-in-citation[@content-type="access-date"]', $value = '2009-08');
     $citationDescription->addStatement('issue', $value = 5);
     $citationDescription->addStatement('volume', $value = 6);
     $citationDescription->addStatement('season', $value = 'Summer');
     $citationDescription->addStatement('chapter-title', $value = 'Introduction');
     $citationDescription->addStatement('edition', $value = '2nd edition');
     $citationDescription->addStatement('series', $value = 7);
     $citationDescription->addStatement('supplement', $value = 'Summer Special');
     $citationDescription->addStatement('conf-date', $value = '2009-08-17');
     $citationDescription->addStatement('conf-loc', $value = 'Helsinki');
     $citationDescription->addStatement('conf-name', $value = 'PHPUnit Hackfest');
     $citationDescription->addStatement('conf-sponsor', $value = 'Basti himself');
     $citationDescription->addStatement('institution', $value = 'PKP');
     $citationDescription->addStatement('fpage', $value = 9);
     $citationDescription->addStatement('lpage', $value = 312);
     $citationDescription->addStatement('size', $value = 320);
     $citationDescription->addStatement('publisher-loc', $value = 'Vancouver');
     $citationDescription->addStatement('publisher-name', $value = 'SFU');
     $citationDescription->addStatement('isbn', $value = '123456789');
     $citationDescription->addStatement('issn[@pub-type="ppub"]', $value = '987654321');
     $citationDescription->addStatement('issn[@pub-type="epub"]', $value = '111111111');
     $citationDescription->addStatement('pub-id[@pub-id-type="doi"]', $value = '10420/39406');
     $citationDescription->addStatement('pub-id[@pub-id-type="publisher-id"]', $value = 'xyz');
     $citationDescription->addStatement('pub-id[@pub-id-type="coden"]', $value = 'abc');
     $citationDescription->addStatement('pub-id[@pub-id-type="sici"]', $value = 'def');
     $citationDescription->addStatement('pub-id[@pub-id-type="pmid"]', $value = '999999');
     $citationDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     $citationDescription->addStatement('comment', $value = 'just nonsense');
     $citationDescription->addStatement('annotation', $value = 'more nonsense');
     $citationDescription->addStatement('[@publication-type]', $value = 'conf-proc');
     $citation =& $this->getCitation($citationDescription);
     // Persist one copy of the citation for testing.
     $citationDao =& $this->getCitationDao();
     $citation->setSeq(1);
     $citation->setCitationState(CITATION_APPROVED);
     $citationId = $citationDao->insertObject($citation);
     self::assertTrue(is_numeric($citationId));
     self::assertTrue($citationId > 0);
     // Construct the expected output.
     $expectedOutput = '';
     // Prepare NLM 3.0 input.
     $mockSubmission =& $this->getTestSubmission();
     import('lib.pkp.plugins.metadata.nlm30.filter.PKPSubmissionNlm30XmlFilter');
     $nlm30Filter = new PKPSubmissionNlm30XmlFilter(PersistableFilter::tempGroup('class::lib.pkp.classes.submission.Submission', 'xml::*'));
     $nlm30Xml = $nlm30Filter->execute($mockSubmission);
     // Test the downgrade filter.
     import('lib.pkp.classes.xslt.XSLTransformationFilter');
     // FIXME: Add NLM 2.3 and 3.0 tag set schema validation as soon as we implement the full tag set, see #5648.
     $downgradeFilter = new XSLTransformationFilter(PersistableFilter::tempGroup('xml::*', 'xml::*'), 'NLM 3.0 to 2.3 ref-list downgrade');
     $downgradeFilter->setXSLFilename('lib/pkp/plugins/metadata/nlm30/filter/nlm30-to-23-ref-list.xsl');
     $nlm30Xml = $downgradeFilter->execute($nlm30Xml);
     self::assertXmlStringEqualsXmlFile('./lib/pkp/tests/plugins/metadata/nlm30/filter/sample-nlm23-citation.xml', $nlm30Xml);
 }
 /**
  * @copydoc MetadataDataObjectAdapter::extractMetadataFromDataObject()
  * @param $dataObject Citation
  * @return MetadataDescription
  */
 function extractMetadataFromDataObject(&$dataObject)
 {
     $metadataDescription = $this->instantiateMetadataDescription();
     // Establish the association between the meta-data description
     // and the citation object.
     $metadataDescription->setAssocId($dataObject->getId());
     // Identify the length of the name space prefix
     $namespacePrefixLength = strlen($this->getMetadataNamespace()) + 1;
     // Get all meta-data field names
     $fieldNames = array_merge($this->getDataObjectMetadataFieldNames(false), $this->getDataObjectMetadataFieldNames(true));
     // Retrieve the statements from the data object
     $statements = array();
     foreach ($fieldNames as $fieldName) {
         if ($dataObject->hasData($fieldName)) {
             // Remove the name space prefix
             $propertyName = substr($fieldName, $namespacePrefixLength);
             if (in_array($propertyName, array('person-group[@person-group-type="author"]', 'person-group[@person-group-type="editor"]'))) {
                 // Retrieve the names array (must not be by-ref
                 // to protect the original citation object!)
                 $names = $dataObject->getData($fieldName);
                 // Convert key/value arrays to MetadataDescription objects.
                 foreach ($names as $key => $name) {
                     if (is_array($name)) {
                         // Construct a meta-data description from
                         // this name array.
                         switch ($propertyName) {
                             case 'person-group[@person-group-type="author"]':
                                 $assocType = ASSOC_TYPE_AUTHOR;
                                 break;
                             case 'person-group[@person-group-type="editor"]':
                                 $assocType = ASSOC_TYPE_EDITOR;
                                 break;
                         }
                         $nameDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', $assocType);
                         $nameDescription->setStatements($name);
                         $names[$key] =& $nameDescription;
                         unset($nameDescription);
                     } else {
                         // The only non-structured data allowed here
                         // is the et-al string.
                         import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30PersonStringFilter');
                         assert($name == PERSON_STRING_FILTER_ETAL);
                     }
                 }
                 $statements[$propertyName] =& $names;
                 unset($names);
             } else {
                 $statements[$propertyName] =& $dataObject->getData($fieldName);
             }
         }
     }
     // Set the statements in the meta-data description
     $success = $metadataDescription->setStatements($statements);
     assert($success);
     return $metadataDescription;
 }
 public function testExecuteWithConferenceProceeding()
 {
     $this->markTestSkipped('Weird class interaction with ControlledVocabEntryDAO leads to failure');
     $nameSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema';
     $citationSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema';
     // An author
     $personDescription = new MetadataDescription($nameSchemaName, ASSOC_TYPE_AUTHOR);
     $personDescription->addStatement('surname', $surname = 'Liu');
     $personDescription->addStatement('given-names', $givenName = 'Sen');
     // A conference paper found on the web
     $citationDescription = new MetadataDescription($citationSchemaName, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('[@publication-type]', $pubType = NLM30_PUBLICATION_TYPE_CONFPROC);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $personDescription);
     $citationDescription->addStatement('article-title', $articleTitle = 'Defending against business crises with the help of intelligent agent based early warning solutions');
     $citationDescription->addStatement('conf-name', $confName = 'The Seventh International Conference on Enterprise Information Systems');
     $citationDescription->addStatement('conf-loc', $confLoc = 'Miami, FL');
     $citationDescription->addStatement('date', $date = '2005-05');
     $citationDescription->addStatement('date-in-citation[@content-type="access-date"]', $accessDate = '2006-08-12');
     $citationDescription->addStatement('uri', $uri = 'http://www.iceis.org/iceis2005/abstracts_2005.htm');
     $citationOutputFilter = $this->getFilterInstance();
     $result = $citationOutputFilter->execute($citationDescription);
     $expectedResult = $this->getConfProcResult();
     self::assertEquals($expectedResult[0] . $this->getConfProcResultGoogleScholar() . $expectedResult[1], $result);
 }
 /**
  * Fills the given citation object with
  * meta-data retrieved from PubMed.
  * @param $pmid string
  * @return MetadataDescription
  */
 function &_lookup($pmid)
 {
     $nullVar = null;
     // Use eFetch to get XML metadata for the given PMID
     $lookupParams = array('db' => 'pubmed', 'mode' => 'xml', 'tool' => 'pkp-wal', 'id' => $pmid);
     if (!is_null($this->getEmail())) {
         $lookupParams['email'] = $this->getEmail();
     }
     // Call the eFetch URL and get an XML result
     if (is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_EFETCH, $lookupParams))) {
         return $nullVar;
     }
     $articleTitleNodes =& $resultDOM->getElementsByTagName("ArticleTitle");
     $articleTitleFirstNode =& $articleTitleNodes->item(0);
     $medlineTaNodes =& $resultDOM->getElementsByTagName("MedlineTA");
     $medlineTaFirstNode =& $medlineTaNodes->item(0);
     $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $articleTitleFirstNode->textContent, 'source' => $medlineTaFirstNode->textContent);
     $volumeNodes =& $resultDOM->getElementsByTagName("Volume");
     $issueNodes =& $resultDOM->getElementsByTagName("Issue");
     if ($volumeNodes->length > 0) {
         $volumeFirstNode =& $volumeNodes->item(0);
     }
     $metadata['volume'] = $volumeFirstNode->textContent;
     if ($issueNodes->length > 0) {
         $issueFirstNode =& $issueNodes->item(0);
     }
     $metadata['issue'] = $issueFirstNode->textContent;
     // Get list of author full names
     foreach ($resultDOM->getElementsByTagName("Author") as $authorNode) {
         if (!isset($metadata['person-group[@person-group-type="author"]'])) {
             $metadata['person-group[@person-group-type="author"]'] = array();
         }
         // Instantiate an NLM name description
         $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR);
         // Surname
         $lastNameNodes =& $authorNode->getElementsByTagName("LastName");
         $lastNameFirstNode =& $lastNameNodes->item(0);
         $authorDescription->addStatement('surname', $lastNameFirstNode->textContent);
         // Given names
         $givenNamesString = '';
         $firstNameNodes =& $authorNode->getElementsByTagName("FirstName");
         if ($firstNameNodes->length > 0) {
             $firstNameFirstNode =& $firstNameNodes->item(0);
             $givenNamesString = $firstNameFirstNode->textContent;
         } else {
             $foreNameNodes =& $authorNode->getElementsByTagName("ForeName");
             if ($foreNameNodes->length > 0) {
                 $foreNameFirstNode =& $foreNameNodes->item(0);
                 $givenNamesString = $foreNameFirstNode->textContent;
             }
         }
         if (!empty($givenNamesString)) {
             foreach (explode(' ', $givenNamesString) as $givenName) {
                 $authorDescription->addStatement('given-names', String::trimPunctuation($givenName));
             }
         }
         // Suffix
         $suffixNodes =& $authorNode->getElementsByTagName("Suffix");
         if ($suffixNodes->length > 0) {
             $suffixFirstNode =& $suffixNodes->item(0);
             $authorDescription->addStatement('suffix', $suffixFirstNode->textContent);
         }
         // Include collective names
         // FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation
         /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') {
         		}*/
         $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription;
         unset($authorDescription);
     }
     // Extract pagination
     $medlinePgnNodes =& $resultDOM->getElementsByTagName("MedlinePgn");
     $medlinePgnFirstNode =& $medlinePgnNodes->item(0);
     if (String::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $medlinePgnFirstNode->textContent, $pages)) {
         $fPage = (int) $pages['fpage'];
         $metadata['fpage'] = $fPage;
         if (!empty($pages['lpage'])) {
             $lPage = (int) $pages['lpage'];
             // Deal with shortcuts like '382-7'
             if ($lPage < $fPage) {
                 $lPage = (int) (String::substr($pages['fpage'], 0, -String::strlen($pages['lpage'])) . $pages['lpage']);
             }
             $metadata['lpage'] = $lPage;
         }
     }
     // Get publication date (can be in several places in PubMed).
     $dateNode = null;
     $articleDateNodes =& $resultDOM->getElementsByTagName("ArticleDate");
     if ($articleDateNodes->length > 0) {
         $dateNode =& $articleDateNodes->item(0);
     } else {
         $pubDateNodes =& $resultDOM->getElementsByTagName("PubDate");
         if ($pubDateNodes->length > 0) {
             $dateNode =& $pubDateNodes->item(0);
         }
     }
     // Retrieve the data parts and assemble date.
     if (!is_null($dateNode)) {
         $publicationDate = '';
         $requiresNormalization = false;
         foreach (array('Year' => 4, 'Month' => 2, 'Day' => 2) as $dateElement => $padding) {
             $dateElementNodes =& $dateNode->getElementsByTagName($dateElement);
             if ($dateElementNodes->length > 0) {
                 if (!empty($publicationDate)) {
                     $publicationDate .= '-';
                 }
                 $dateElementFirstNode =& $dateElementNodes->item(0);
                 $datePart = str_pad($dateElementFirstNode->textContent, $padding, '0', STR_PAD_LEFT);
                 if (!is_numeric($datePart)) {
                     $requiresNormalization = true;
                 }
                 $publicationDate .= $datePart;
             } else {
                 break;
             }
         }
         // Normalize the date to NLM standard if necessary.
         if ($requiresNormalization) {
             $dateFilter = new DateStringNormalizerFilter();
             $publicationDate = $dateFilter->execute($publicationDate);
         }
         if (!empty($publicationDate)) {
             $metadata['date'] = $publicationDate;
         }
     }
     // Get publication type
     $publicationTypeNodes =& $resultDOM->getElementsByTagName("PublicationType");
     if ($publicationTypeNodes->length > 0) {
         foreach ($publicationTypeNodes as $publicationType) {
             // The vast majority of items on PubMed are articles so catch these...
             if (String::strpos(String::strtolower($publicationType->textContent), 'article') !== false) {
                 $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_JOURNAL;
                 break;
             }
         }
     }
     // Get DOI if it exists
     $articleIdNodes =& $resultDOM->getElementsByTagName("ArticleId");
     foreach ($articleIdNodes as $idNode) {
         if ($idNode->getAttribute('IdType') == 'doi') {
             $metadata['pub-id[@pub-id-type="doi"]'] = $idNode->textContent;
         }
     }
     // Use eLink utility to find fulltext links
     $lookupParams = array('dbfrom' => 'pubmed', 'cmd' => 'llinks', 'tool' => 'pkp-wal', 'id' => $pmid);
     if (!is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_ELINK, $lookupParams))) {
         // Get a list of possible links
         foreach ($resultDOM->getElementsByTagName("ObjUrl") as $linkOut) {
             $attributes = '';
             foreach ($linkOut->getElementsByTagName("Attribute") as $attribute) {
                 $attributes .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::strpos($attributes, "fee") === false && $attributes != "") {
                 $urlNodes =& $linkOut->getElementsByTagName("Url");
                 $urlFirstNode =& $urlNodes->item(0);
                 $links[] = $urlFirstNode->textContent;
             }
         }
         // Take the first link if we have any left (presumably pubmed returns them in preferential order)
         if (isset($links[0])) {
             $metadata['uri'] = $links[0];
         }
     }
     return $this->getNlm30CitationDescriptionFromMetadataArray($metadata);
 }
 /**
  * @see MetadataDataObjectAdapter::extractMetadataFromDataObject()
  * @param $submission Submission
  * @return MetadataDescription
  */
 function extractMetadataFromDataObject(&$submission)
 {
     assert(is_a($submission, 'Submission'));
     $mods34Description = $this->instantiateMetadataDescription();
     // Retrieve the primary locale.
     $catalogingLocale = AppLocale::getPrimaryLocale();
     $catalogingLanguage = AppLocale::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"]', 'aut');
         // 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
     $language = $submission->getLanguage();
     if ($language) {
         $submissionLanguage = AppLocale::get3LetterFrom2LetterIsoLanguage($submission->getLanguage());
     } else {
         $submissionLanguage = null;
     }
     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
     $localizedSubjects = $submission->getSubject(null);
     // Localized
     $this->addLocalizedStatements($mods34Description, 'subject/topic', $localizedSubjects);
     // FIXME: Coverage not included
     // 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;
 }
 /**
  * Fills the given citation object with
  * meta-data retrieved from PubMed.
  * @param $pmid string
  * @param $citationDescription MetadataDescription
  * @return MetadataDescription
  */
 function &_lookup($pmid, &$citationDescription)
 {
     $nullVar = null;
     // Use eFetch to get XML metadata for the given PMID
     $lookupParams = array('db' => 'pubmed', 'mode' => 'xml', 'tool' => 'pkp-wal', 'id' => $pmid);
     if (!is_null($this->getEmail())) {
         $lookupParams['email'] = $this->getEmail();
     }
     // Call the eFetch URL and get an XML result
     if (is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_EFETCH, $lookupParams))) {
         return $nullVar;
     }
     $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $resultDOM->getElementsByTagName("ArticleTitle")->item(0)->textContent, 'source' => $resultDOM->getElementsByTagName("MedlineTA")->item(0)->textContent);
     if ($resultDOM->getElementsByTagName("Volume")->length > 0) {
         $metadata['volume'] = $resultDOM->getElementsByTagName("Volume")->item(0)->textContent;
     }
     if ($resultDOM->getElementsByTagName("Issue")->length > 0) {
         $metadata['issue'] = $resultDOM->getElementsByTagName("Issue")->item(0)->textContent;
     }
     // get list of author full names
     $nlmNameSchema = new NlmNameSchema();
     foreach ($resultDOM->getElementsByTagName("Author") as $authorNode) {
         if (!isset($metadata['person-group[@person-group-type="author"]'])) {
             $metadata['person-group[@person-group-type="author"]'] = array();
         }
         // Instantiate an NLM name description
         $authorDescription = new MetadataDescription($nlmNameSchema, ASSOC_TYPE_AUTHOR);
         // Surname
         $authorDescription->addStatement('surname', $authorNode->getElementsByTagName("LastName")->item(0)->textContent);
         // Given names
         $givenNamesString = '';
         if ($authorNode->getElementsByTagName("FirstName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("FirstName")->item(0)->textContent;
         } elseif ($authorNode->getElementsByTagName("ForeName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("ForeName")->item(0)->textContent;
         }
         if (!empty($givenNamesString)) {
             foreach (explode(' ', $givenNamesString) as $givenName) {
                 $authorDescription->addStatement('given-names', String::trimPunctuation($givenName));
             }
         }
         // Suffix
         if ($authorNode->getElementsByTagName("Suffix")->length > 0) {
             $authorDescription->addStatement('suffix', $authorNode->getElementsByTagName("Suffix")->item(0)->textContent);
         }
         // Include collective names
         /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') {
         			// FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation
         		}*/
         $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription;
         unset($authorDescription);
     }
     // Extract pagination
     if (String::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $resultDOM->getElementsByTagName("MedlinePgn")->item(0)->textContent, $pages)) {
         $fPage = (int) $pages['fpage'];
         $metadata['fpage'] = $fPage;
         if (!empty($pages['lpage'])) {
             $lPage = (int) $pages['lpage'];
             // Deal with shortcuts like '382-7'
             if ($lPage < $fPage) {
                 $lPage = (int) (String::substr($pages['fpage'], 0, -String::strlen($pages['lpage'])) . $pages['lpage']);
             }
             $metadata['lpage'] = $lPage;
         }
     }
     // Get publication date
     // TODO: The publication date could be in multiple places
     if ($resultDOM->getElementsByTagName("ArticleDate")->length > 0) {
         $publicationDate = $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Year")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Month")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Day")->item(0)->textContent;
         $metadata['date'] = $publicationDate;
     }
     // Get publication type
     if ($resultDOM->getElementsByTagName("PublicationType")->length > 0) {
         foreach ($resultDOM->getElementsByTagName("PublicationType") as $publicationType) {
             // The vast majority of items on PubMed are articles so catch these...
             if (String::strpos(String::strtolower($publicationType->textContent), 'article') !== false) {
                 $metadata['[@publication-type]'] = NLM_PUBLICATION_TYPE_JOURNAL;
                 break;
             }
         }
     }
     // Get DOI if it exists
     foreach ($resultDOM->getElementsByTagName("ArticleId") as $idNode) {
         if ($idNode->getAttribute('IdType') == 'doi') {
             $metadata['pub-id[@pub-id-type="doi"]'] = $idNode->textContent;
         }
     }
     // Use eLink utility to find fulltext links
     $lookupParams = array('dbfrom' => 'pubmed', 'cmd' => 'llinks', 'tool' => 'pkp-wal', 'id' => $pmid);
     if (!is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_ELINK, $lookupParams))) {
         // Get a list of possible links
         foreach ($resultDOM->getElementsByTagName("ObjUrl") as $linkOut) {
             $attributes = '';
             foreach ($linkOut->getElementsByTagName("Attribute") as $attribute) {
                 $attributes .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::strpos($attributes, "fee") === false && $attributes != "") {
                 $links[] = $linkOut->getElementsByTagName("Url")->item(0)->textContent;
             }
         }
         // Take the first link if we have any left (presumably pubmed returns them in preferential order)
         if (isset($links[0])) {
             $metadata['uri'] = $links[0];
         }
     }
     return $this->addMetadataArrayToNlmCitationDescription($metadata, $citationDescription);
 }
예제 #19
0
 /**
  * @covers CitationDAO
  */
 public function testCitationCrud()
 {
     $citationDao = DAORegistry::getDAO('CitationDAO');
     /* @var $citationDao CitationDAO */
     $nameSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema';
     $nameDescription = new MetadataDescription($nameSchemaName, ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $citationSchemaName = 'lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema';
     $citationDescription = new MetadataDescription($citationSchemaName, ASSOC_TYPE_CITATION);
     $citationDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $citationDescription->addStatement('article-title', $value = 'PHPUnit in Kürze', 'de_DE');
     $citationDescription->addStatement('date', $value = '2009-08-17');
     $citationDescription->addStatement('size', $value = 320);
     $citationDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     // Add a simple source description.
     $sourceDescription = new MetadataDescription($citationSchemaName, ASSOC_TYPE_CITATION);
     $sourceDescription->setDisplayName('test');
     $sourceDescription->addStatement('article-title', $value = 'a simple source description', 'en_US');
     $sourceDescription->setSeq(0);
     $citation = new Citation('raw citation');
     $citation->setAssocType(ASSOC_TYPE_ARTICLE);
     $citation->setAssocId(999999);
     $citation->setSeq(50);
     $citation->addSourceDescription($sourceDescription);
     $citation->injectMetadata($citationDescription);
     // Create citation.
     $citationId = $citationDao->insertObject($citation);
     self::assertTrue(is_numeric($citationId));
     self::assertTrue($citationId > 0);
     // Retrieve citation.
     $citationById = $citationDao->getObjectById($citationId);
     // Fix state differences for comparison.
     $citation->removeSupportedMetadataAdapter($citationSchemaName);
     $citationById->removeSupportedMetadataAdapter($citationSchemaName);
     $citationById->_extractionAdaptersLoaded = true;
     $citationById->_injectionAdaptersLoaded = true;
     $sourceDescription->setAssocId($citationId);
     $sourceDescription->removeSupportedMetadataAdapter($citationSchemaName);
     $sourceDescriptions = $citationById->getSourceDescriptions();
     $sourceDescriptions['test']->getMetadataSchema();
     // this will instantiate the meta-data schema internally.
     self::assertEquals($citation, $citationById);
     $citationsByAssocIdDaoFactory = $citationDao->getObjectsByAssocId(ASSOC_TYPE_ARTICLE, 999999);
     $citationsByAssocId = $citationsByAssocIdDaoFactory->toArray();
     self::assertEquals(1, count($citationsByAssocId));
     // Fix state differences for comparison.
     $citationsByAssocId[0]->_extractionAdaptersLoaded = true;
     $citationsByAssocId[0]->_injectionAdaptersLoaded = true;
     $citationsByAssocId[0]->removeSupportedMetadataAdapter($citationSchemaName);
     $sourceDescriptionsByAssocId = $citationsByAssocId[0]->getSourceDescriptions();
     $sourceDescriptionsByAssocId['test']->getMetadataSchema();
     // this will instantiate the meta-data schema internally.
     self::assertEquals($citation, $citationsByAssocId[0]);
     // Update citation.
     $citationDescription->removeStatement('date');
     $citationDescription->addStatement('article-title', $value = 'PHPUnit rápido', 'pt_BR');
     // Update source descriptions.
     $sourceDescription->addStatement('article-title', $value = 'edited source description', 'en_US', true);
     $updatedCitation = new Citation('another raw citation');
     $updatedCitation->setId($citationId);
     $updatedCitation->setAssocType(ASSOC_TYPE_ARTICLE);
     $updatedCitation->setAssocId(999998);
     $updatedCitation->setSeq(50);
     $updatedCitation->addSourceDescription($sourceDescription);
     $updatedCitation->injectMetadata($citationDescription);
     $citationDao->updateObject($updatedCitation);
     $citationAfterUpdate = $citationDao->getObjectById($citationId);
     // Fix state differences for comparison.
     $updatedCitation->removeSupportedMetadataAdapter($citationSchemaName);
     $citationAfterUpdate->removeSupportedMetadataAdapter($citationSchemaName);
     $citationAfterUpdate->_extractionAdaptersLoaded = true;
     $citationAfterUpdate->_injectionAdaptersLoaded = true;
     $sourceDescriptionsAfterUpdate = $citationAfterUpdate->getSourceDescriptions();
     $sourceDescriptionsAfterUpdate['test']->getMetadataSchema();
     // this will instantiate the meta-data schema internally.
     $sourceDescription->removeSupportedMetadataAdapter($citationSchemaName);
     self::assertEquals($updatedCitation, $citationAfterUpdate);
     // Delete citation
     $citationDao->deleteObjectsByAssocId(ASSOC_TYPE_ARTICLE, 999998);
     self::assertNull($citationDao->getObjectById($citationId));
 }
 /**
  * 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;
 }
 /**
  * Take an array of citation parse/lookup results and derive a citation
  * with one "best" set of values.
  *
  * We determine the best values within the citations that have a score above
  * the given threshold. Citations with a score below the threshold will be
  * ignored.
  *
  * For these citations we count the frequency of values per meta-data property.
  * The most frequent value will be chosen as "best" value.
  *
  * If two values have the same frequency then decide based on the score. If
  * this is still ambivalent then return the first of the remaining values.
  *
  * @param $scoredCitations
  * @param $scoreThreshold integer a number between 0 (=no threshold) and 100
  * @return Citation one citation with the "best" values set
  */
 function &_guessValues(&$scoredCitations, $scoreThreshold)
 {
     assert($scoreThreshold >= 0 && $scoreThreshold <= 100);
     // Create the target citation description.
     $targetDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', ASSOC_TYPE_CITATION);
     // Step 1: List all values and max scores that have been identified for a given element
     //         but only include values from results above a given scoring threshold
     // Initialize variables for the first step.
     $valuesByPropertyName = array();
     $maxScoresByPropertyNameAndValue = array();
     // Sort the scored citations by score with the highest score first.
     krsort($scoredCitations);
     foreach ($scoredCitations as $currentScore => $citationsForCurrentScore) {
         // Check whether the current score is below the threshold, if so
         // stop the loop. We've sorted our citations by score so the remaining
         // citations all have scores below the threshold and we can forget
         // about them.
         if ($currentScore < $scoreThreshold) {
             break;
         }
         foreach ($citationsForCurrentScore as $citationForCurrentScore) {
             $statements = $citationForCurrentScore->getStatements();
             // Add the property values and scores of this citation
             // to the overall property lists
             foreach ($statements as $propertyName => $value) {
                 // Initialize sub-arrays if necessary
                 if (!isset($valuesByPropertyName[$propertyName])) {
                     $valuesByPropertyName[$propertyName] = array();
                 }
                 if (!isset($maxScoresByPropertyNameAndValue[$propertyName])) {
                     $maxScoresByPropertyNameAndValue[$propertyName] = array();
                 }
                 // Add the value for the given property, as we want to count
                 // value frequencies later, we explicitly allow duplicates.
                 $serializedValue = serialize($value);
                 $valuesByPropertyName[$propertyName][] = $serializedValue;
                 // As we have ordered our citations descending by score, the
                 // first score found for a value is also the maximum score.
                 if (!isset($maxScoresByPropertyNameAndValue[$propertyName][$serializedValue])) {
                     $maxScoresByPropertyNameAndValue[$propertyName][$serializedValue] = $currentScore;
                 }
             }
         }
     }
     // Step 2: Find out the values that occur most frequently for each element
     //         and order these by score.
     foreach ($valuesByPropertyName as $propertyName => $values) {
         // Count the occurrences of each value within the given element
         $valueFrequencies = array_count_values($values);
         // Order the most frequent values to the beginning of the array
         arsort($valueFrequencies);
         // Get the most frequent values (may be several if there are more than one
         // with the same frequency).
         $scoresOfMostFrequentValues = array();
         $previousValueFrequency = 0;
         foreach ($valueFrequencies as $value => $valueFrequency) {
             // Only extract the most frequent values, jump out of the
             // loop when less frequent values start.
             if ($previousValueFrequency > $valueFrequency) {
                 break;
             }
             $previousValueFrequency = $valueFrequency;
             $scoresOfMostFrequentValues[$value] = $maxScoresByPropertyNameAndValue[$propertyName][$value];
         }
         // Now we can order the most frequent values by score, starting
         // with the highest score.
         arsort($scoresOfMostFrequentValues);
         // Now get the first key which represents the value with the
         // highest frequency and the highest score.
         reset($scoresOfMostFrequentValues);
         $bestValue = unserialize(key($scoresOfMostFrequentValues));
         // Set the found "best" element value in the result citation.
         $statements = array($propertyName => $bestValue);
         $success = $targetDescription->setStatements($statements);
         assert($success);
     }
     // Instantiate the target citation
     $targetCitation = new Citation();
     $targetCitation->injectMetadata($targetDescription);
     return $targetCitation;
 }
 /**
  * Adds the data of an array of property/value pairs
  * as statements to an NLM citation description.
  * If no citation description is given, a new one will
  * be instantiated.
  * @param $metadataArray array
  * @param $citationDescription MetadataDescription
  * @return MetadataDescription
  */
 function &addMetadataArrayToNlmCitationDescription(&$metadataArray, $citationDescription = null)
 {
     // Create a new citation description if no one was given
     if (is_null($citationDescription)) {
         $metadataSchema = new NlmCitationSchema();
         $citationDescription = new MetadataDescription($metadataSchema, ASSOC_TYPE_CITATION);
     }
     // Add the meta-data to the description
     if (!$citationDescription->setStatements($metadataArray)) {
         $nullVar = null;
         return $nullVar;
     }
     return $citationDescription;
 }
예제 #23
0
 /**
  * Save citation
  */
 function execute()
 {
     $citation =& $this->getCitation();
     $citation->setEditedCitation($this->getData('editedCitation'));
     if (in_array($this->getData('citationState'), Citation::_getSupportedCitationStates())) {
         $citation->setCitationState($this->getData('citationState'));
     }
     // Extract data from citation form fields and inject it into the citation
     $metadataAdapters = $citation->getSupportedMetadataAdapters();
     foreach ($metadataAdapters as $metadataAdapter) {
         // Instantiate a meta-data description for the given schema
         $metadataSchema =& $metadataAdapter->getMetadataSchema();
         import('metadata.MetadataDescription');
         $metadataDescription = new MetadataDescription($metadataSchema, ASSOC_TYPE_CITATION);
         // Set the meta-data statements
         $metadataSchemaNamespace = $metadataSchema->getNamespace();
         foreach ($metadataSchema->getProperties() as $propertyName => $property) {
             $fieldName = $metadataSchema->getNamespacedPropertyId($propertyName);
             $fieldValue = trim($this->getData($fieldName));
             if (empty($fieldValue)) {
                 $metadataDescription->removeStatement($propertyName);
             } else {
                 $foundValidType = false;
                 foreach ($property->getTypes() as $type) {
                     // Some property types need to be converted first
                     switch ($type) {
                         // We currently only support name composites
                         case array(METADATA_PROPERTY_TYPE_COMPOSITE => ASSOC_TYPE_AUTHOR):
                         case array(METADATA_PROPERTY_TYPE_COMPOSITE => ASSOC_TYPE_EDITOR):
                             import('metadata.nlm.PersonStringNlmNameSchemaFilter');
                             $personStringFilter = new PersonStringNlmNameSchemaFilter($type[METADATA_PROPERTY_TYPE_COMPOSITE], PERSON_STRING_FILTER_MULTIPLE);
                             assert($personStringFilter->supportsAsInput($fieldValue));
                             $fieldValue =& $personStringFilter->execute($fieldValue);
                             $foundValidType = true;
                             break;
                         case METADATA_PROPERTY_TYPE_INTEGER:
                             $fieldValue = array((int) $fieldValue);
                             $foundValidType = true;
                             break;
                         case METADATA_PROPERTY_TYPE_DATE:
                             import('metadata.DateStringNormalizerFilter');
                             $dateStringFilter = new DateStringNormalizerFilter();
                             assert($dateStringFilter->supportsAsInput($fieldValue));
                             $fieldValue = array($dateStringFilter->execute($fieldValue));
                             $foundValidType = true;
                             break;
                         default:
                             if ($property->isValid($fieldValue)) {
                                 $fieldValue = array($fieldValue);
                                 $foundValidType = true;
                                 break;
                             }
                     }
                     // Break the outer loop once we found a valid
                     // interpretation for our form field.
                     if ($foundValidType) {
                         break;
                     }
                 }
                 foreach ($fieldValue as $fieldValueStatement) {
                     $metadataDescription->addStatement($propertyName, $fieldValueStatement);
                     unset($fieldValueStatement);
                 }
             }
         }
         // Inject the meta-data into the citation
         $citation->injectMetadata($metadataDescription, true);
     }
     // Persist citation
     $citationDAO =& DAORegistry::getDAO('CitationDAO');
     if (is_numeric($citation->getId())) {
         $citationDAO->updateCitation($citation);
     } else {
         $citationDAO->insertCitation($citation);
     }
     return true;
 }
 /**
  * Instantiate an NLM name description from an array.
  * @param $personArray array
  * @param $assocType integer
  * @return MetadataDescription
  */
 private function &instantiateNlm30NameDescriptions(&$personArray, $assocType)
 {
     $personDescriptions = array();
     foreach ($personArray as $key => $person) {
         if ($person == PERSON_STRING_FILTER_ETAL) {
             $personDescription = 'et-al';
         } else {
             // Create a new NLM name description and fill it
             // with the values from the test array.
             $personDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', $assocType);
             self::assertTrue($personDescription->setStatements($person));
         }
         // Add the result to the descriptions list
         $personDescriptions[$key] = $personDescription;
     }
     return $personDescriptions;
 }
 /**
  * Converts a string with a single person
  * to an NLM name description.
  *
  * TODO: add initials from all given names to initials
  *       element
  *
  * @param $personString string
  * @param $title boolean true to parse for title
  * @param $degrees boolean true to parse for degrees
  * @return MetadataDescription an NLM name description or null
  *  if the string could not be converted
  */
 function &_parsePersonString($personString, $title, $degrees)
 {
     // Expressions to parse person strings, ported from CiteULike person
     // plugin, see http://svn.citeulike.org/svn/plugins/person.tcl
     static $personRegex = array('title' => '(?:His (?:Excellency|Honou?r)\\s+|Her (?:Excellency|Honou?r)\\s+|The Right Honou?rable\\s+|The Honou?rable\\s+|Right Honou?rable\\s+|The Rt\\.? Hon\\.?\\s+|The Hon\\.?\\s+|Rt\\.? Hon\\.?\\s+|Mr\\.?\\s+|Ms\\.?\\s+|M\\/s\\.?\\s+|Mrs\\.?\\s+|Miss\\.?\\s+|Dr\\.?\\s+|Sir\\s+|Dame\\s+|Prof\\.?\\s+|Professor\\s+|Doctor\\s+|Mister\\s+|Mme\\.?\\s+|Mast(?:\\.|er)?\\s+|Lord\\s+|Lady\\s+|Madam(?:e)?\\s+|Priv\\.-Doz\\.\\s+)+', 'degrees' => '(,\\s+(?:[A-Z\\.]+))+', 'initials' => '(?:(?:[A-Z]\\.){1,3}[A-Z]\\.?)|(?:(?:[A-Z]\\.\\s){1,3}[A-Z]\\.?)|(?:[A-Z]{1,4})|(?:(?:[A-Z]\\.-?){1,4})|(?:(?:[A-Z]\\.-?){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z])|(?:(?:[A-Z]\\s){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z]\\.?)', 'prefix' => 'Dell(?:[a|e])?(?:\\s|$)|Dalle(?:\\s|$)|D[a|e]ll\'(?:\\s|$)|Dela(?:\\s|$)|Del(?:\\s|$)|[Dd]e(?:\\s|$)(?:La(?:\\s|$)|Los(?:\\s|$))?|[Dd]e(?:\\s|$)|[Dd][a|i|u](?:\\s|$)|L[a|e|o](?:\\s|$)|[D|L|O]\'|St\\.?(?:\\s|$)|San(?:\\s|$)|[Dd]en(?:\\s|$)|[Vv]on(?:\\s|$)(?:[Dd]er(?:\\s|$))?|(?:[Ll][ea](?:\\s|$))?[Vv]an(?:\\s|$)(?:[Dd]e(?:n|r)?(?:\\s|$))?', 'givenName' => '(?:[^ \\t\\n\\r\\f\\v,.;()]{2,}|[^ \\t\\n\\r\\f\\v,.;()]{2,}\\-[^ \\t\\n\\r\\f\\v,.;()]{2,})');
     // The expressions for given name, suffix and surname are the same
     $personRegex['surname'] = $personRegex['suffix'] = $personRegex['givenName'];
     $personRegex['double-surname'] = "(?:" . $personRegex['surname'] . "\\s)*" . $personRegex['surname'];
     // Shortcut for prefixed surname
     $personRegexPrefixedSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['surname'] . ")";
     $personRegexPrefixedDoubleSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['double-surname'] . ")";
     // Instantiate the target person description
     $personDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', $this->_assocType);
     // Clean the person string
     $personString = trim($personString);
     // 1. Extract title and degree from the person string and use this as suffix
     $suffixString = '';
     $results = array();
     if ($title && String::regexp_match_get('/^(' . $personRegex['title'] . ')/i', $personString, $results)) {
         $suffixString = trim($results[1], ',:; ');
         $personString = String::regexp_replace('/^(' . $personRegex['title'] . ')/i', '', $personString);
     }
     if ($degrees && String::regexp_match_get('/(' . $personRegex['degrees'] . ')$/i', $personString, $results)) {
         $degreesArray = explode(',', trim($results[1], ','));
         foreach ($degreesArray as $key => $degree) {
             $degreesArray[$key] = String::trimPunctuation($degree);
         }
         $suffixString .= ' - ' . implode('; ', $degreesArray);
         $personString = String::regexp_replace('/(' . $personRegex['degrees'] . ')$/i', '', $personString);
     }
     if (!empty($suffixString)) {
         $personDescription->addStatement('suffix', $suffixString);
     }
     // Space initials when followed by a given name or last name.
     $personString = String::regexp_replace('/([A-Z])\\.([A-Z][a-z])/', '\\1. \\2', $personString);
     // 2. Extract names and initials from the person string
     // The parser expressions are ordered by specificity. The most specific expressions
     // come first. Only if these specific expressions don't work will we turn to less
     // specific ones. This avoids parsing errors. It also explains why we don't use the
     // ?-quantifier for optional elements like initials or middle name where they could
     // be misinterpreted.
     $personExpressions = array('/^' . $personRegexPrefixedSurname . '$/i', '/^(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedSurname . ',?\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',(?P<givenName>(?:\\s' . $personRegex['givenName'] . ')+)$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)' . $personRegexPrefixedSurname . '$/', '/^\\s*(?P<surname>' . $personRegex['surname'] . ')(?P<suffix>(?:\\s+' . $personRegex['suffix'] . ')?)\\s*,\\s*(?P<initials>(?:' . $personRegex['initials'] . ')?)\\s*\\((?P<givenName>(?:\\s*' . $personRegex['givenName'] . ')+)\\s*\\)\\s*(?P<prefix>(?:' . $personRegex['prefix'] . ')?)$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\.(?P<surname>' . $personRegex['double-surname'] . ')$/', '/^(?P<surname>.*)$/');
     $results = array();
     foreach ($personExpressions as $expressionId => $personExpression) {
         if ($nameFound = String::regexp_match_get($personExpression, $personString, $results)) {
             // Given names
             if (!empty($results['givenName'])) {
                 // Split given names
                 $givenNames = explode(' ', trim($results['givenName']));
                 foreach ($givenNames as $givenName) {
                     $personDescription->addStatement('given-names', $givenName);
                     unset($givenName);
                 }
             }
             // Initials (will also be saved as given names)
             if (!empty($results['initials'])) {
                 $results['initials'] = str_replace(array('.', '-', ' '), array('', '', ''), $results['initials']);
                 for ($initialNum = 0; $initialNum < String::strlen($results['initials']); $initialNum++) {
                     $initial = $results['initials'][$initialNum];
                     $personDescription->addStatement('given-names', $initial);
                     unset($initial);
                 }
             }
             // Surname
             if (!empty($results['surname'])) {
                 // Correct all-upper surname
                 if (strtoupper($results['surname']) == $results['surname']) {
                     $results['surname'] = ucwords(strtolower($results['surname']));
                 }
                 $personDescription->addStatement('surname', $results['surname']);
             }
             // Prefix/Suffix
             foreach (array('prefix', 'suffix') as $propertyName) {
                 if (!empty($results[$propertyName])) {
                     $results[$propertyName] = trim($results[$propertyName]);
                     $personDescription->addStatement($propertyName, $results[$propertyName]);
                 }
             }
             break;
         }
     }
     return $personDescription;
 }
 /**
  * @see Filter::process()
  * @param $citationString string
  * @return MetadataDescription
  */
 function &process($citationString)
 {
     $nullVar = null;
     // Check the availability of perl
     $perlCommand = Config::getVar('cli', 'perl');
     if (empty($perlCommand) || !file_exists($perlCommand)) {
         return $nullVar;
     }
     // Convert to ASCII - Paracite doesn't handle UTF-8 well
     $citationString = String::utf8_to_ascii($citationString);
     // Call the paracite parser
     $wrapperScript = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'paracite.pl';
     $paraciteCommand = $perlCommand . ' ' . escapeshellarg($wrapperScript) . ' ' . $this->getCitationModule() . ' ' . escapeshellarg($citationString);
     $xmlResult = shell_exec($paraciteCommand);
     if (empty($xmlResult)) {
         return $nullVar;
     }
     if (Config::getVar('i18n', 'charset_normalization') == 'On' && !String::utf8_compliant($xmlResult)) {
         $xmlResult = String::utf8_normalize($xmlResult);
     }
     // Create a temporary DOM document
     $resultDOM = new DOMDocument();
     $resultDOM->recover = true;
     $resultDOM->loadXML($xmlResult);
     // Extract the parser results as an array
     $xmlHelper = new XMLHelper();
     $metadata = $xmlHelper->xmlToArray($resultDOM->documentElement);
     // We have to merge subtitle and title as neither OpenURL
     // nor NLM can handle subtitles.
     if (isset($metadata['subtitle'])) {
         $metadata['title'] .= '. ' . $metadata['subtitle'];
         unset($metadata['subtitle']);
     }
     // Break up the authors field
     if (isset($metadata['authors'])) {
         $metadata['authors'] = String::trimPunctuation($metadata['authors']);
         $metadata['authors'] = String::iterativeExplode(array(':', ';'), $metadata['authors']);
     }
     // Convert pages to integers
     foreach (array('spage', 'epage') as $pageProperty) {
         if (isset($metadata[$pageProperty])) {
             $metadata[$pageProperty] = (int) $metadata[$pageProperty];
         }
     }
     // Convert titles to title case
     foreach (array('title', 'chapter', 'publication') as $titleProperty) {
         if (isset($metadata[$titleProperty])) {
             $metadata[$titleProperty] = String::titleCase($metadata[$titleProperty]);
         }
     }
     // Map ParaCite results to OpenURL - null means
     // throw the value away.
     $metadataMapping = array('genre' => 'genre', '_class' => null, 'any' => null, 'authors' => 'au', 'aufirst' => 'aufirst', 'aufull' => null, 'auinit' => 'auinit', 'aulast' => 'aulast', 'atitle' => 'atitle', 'cappublication' => null, 'captitle' => null, 'date' => 'date', 'epage' => 'epage', 'featureID' => null, 'id' => null, 'issue' => 'issue', 'jnl_epos' => null, 'jnl_spos' => null, 'match' => null, 'marked' => null, 'num_of_fig' => null, 'pages' => 'pages', 'publisher' => 'pub', 'publoc' => 'place', 'ref' => null, 'rest_text' => null, 'spage' => 'spage', 'targetURL' => 'url', 'text' => null, 'ucpublication' => null, 'uctitle' => null, 'volume' => 'volume', 'year' => 'date');
     // Ignore 'year' if 'date' is set
     if (isset($metadata['date'])) {
         $metadataMapping['year'] = null;
     }
     // Set default genre
     if (empty($metadata['genre'])) {
         $metadata['genre'] = OPENURL_GENRE_ARTICLE;
     }
     // Handle title, chapter and publication depending on
     // the (inferred) genre. Also instantiate the target schema.
     switch ($metadata['genre']) {
         case OPENURL_GENRE_BOOK:
         case OPENURL_GENRE_BOOKITEM:
         case OPENURL_GENRE_REPORT:
         case OPENURL_GENRE_DOCUMENT:
             $metadataMapping += array('publication' => 'btitle', 'chapter' => 'atitle');
             if (isset($metadata['title'])) {
                 if (!isset($metadata['publication'])) {
                     $metadata['publication'] = $metadata['title'];
                 } elseif (!isset($metadata['chapter'])) {
                     $metadata['chapter'] = $metadata['title'];
                 }
                 unset($metadata['title']);
             }
             $openUrlSchemaName = 'lib.pkp.classes.metadata.openurl.OpenUrlBookSchema';
             $openUrlSchemaClass = 'OpenUrlBookSchema';
             break;
         case OPENURL_GENRE_ARTICLE:
         case OPENURL_GENRE_JOURNAL:
         case OPENURL_GENRE_ISSUE:
         case OPENURL_GENRE_CONFERENCE:
         case OPENURL_GENRE_PROCEEDING:
         case OPENURL_GENRE_PREPRINT:
         default:
             $metadataMapping += array('publication' => 'jtitle');
             if (isset($metadata['title'])) {
                 if (!isset($metadata['publication'])) {
                     $metadata['publication'] = $metadata['title'];
                 } elseif (!isset($metadata['atitle'])) {
                     $metadata['atitle'] = $metadata['title'];
                 }
                 unset($metadata['title']);
             }
             $openUrlSchemaName = 'lib.pkp.classes.metadata.openurl.OpenUrlJournalSchema';
             $openUrlSchemaClass = 'OpenUrlJournalSchema';
             break;
     }
     // Instantiate an OpenURL description
     $openUrlDescription = new MetadataDescription($openUrlSchemaName, ASSOC_TYPE_CITATION);
     $openUrlSchema = new $openUrlSchemaClass();
     // Map the ParaCite result to OpenURL
     foreach ($metadata as $paraciteElementName => $paraciteValue) {
         if (!empty($paraciteValue)) {
             // Trim punctuation
             if (is_string($paraciteValue)) {
                 $paraciteValue = String::trimPunctuation($paraciteValue);
             }
             // Transfer the value to the OpenURL result array
             assert(array_key_exists($paraciteElementName, $metadataMapping));
             $openUrlPropertyName = $metadataMapping[$paraciteElementName];
             if (!is_null($openUrlPropertyName) && $openUrlSchema->hasProperty($openUrlPropertyName)) {
                 if (is_array($paraciteValue)) {
                     foreach ($paraciteValue as $singleValue) {
                         $success = $openUrlDescription->addStatement($openUrlPropertyName, $singleValue);
                         assert($success);
                     }
                 } else {
                     $success = $openUrlDescription->addStatement($openUrlPropertyName, $paraciteValue);
                     assert($success);
                 }
             }
         }
     }
     // Crosswalk to NLM
     $crosswalkFilter = new OpenUrlNlmCitationSchemaCrosswalkFilter();
     $nlmDescription =& $crosswalkFilter->execute($openUrlDescription);
     assert(is_a($nlmDescription, 'MetadataDescription'));
     // Add 'rest_text' as NLM comment (if given)
     if (isset($metadata['rest_text'])) {
         $nlmDescription->addStatement('comment', String::trimPunctuation($metadata['rest_text']));
     }
     // Set display name and sequence id in the meta-data description
     // to the corresponding values from the filter. This is important
     // so that we later know which result came from which filter.
     $nlmDescription->setDisplayName($this->getDisplayName());
     $nlmDescription->setSeq($this->getSeq());
     return $nlmDescription;
 }
 /**
  * @see MetadataDataObjectAdapter::extractMetadataFromDataObject()
  * @param $dataObject Citation
  * @return MetadataDescription
  */
 function &extractMetadataFromDataObject(&$dataObject)
 {
     $metadataDescription =& $this->instantiateMetadataDescription();
     // Identify the length of the name space prefix
     $namespacePrefixLength = strlen($this->getMetadataNamespace()) + 1;
     // Get all meta-data field names
     $fieldNames = array_merge($this->getDataObjectMetadataFieldNames(false), $this->getDataObjectMetadataFieldNames(true));
     // Retrieve the statements from the data object
     $statements = array();
     $nameSchema = new NlmNameSchema();
     foreach ($fieldNames as $fieldName) {
         if ($dataObject->hasData($fieldName)) {
             // Remove the name space prefix
             $propertyName = substr($fieldName, $namespacePrefixLength);
             if (in_array($propertyName, array('person-group[@person-group-type="author"]', 'person-group[@person-group-type="editor"]'))) {
                 // Convert key/value arrays to MetadataDescription objects.
                 $names =& $dataObject->getData($fieldName);
                 foreach ($names as $key => $name) {
                     switch ($propertyName) {
                         case 'person-group[@person-group-type="author"]':
                             $assocType = ASSOC_TYPE_AUTHOR;
                             break;
                         case 'person-group[@person-group-type="editor"]':
                             $assocType = ASSOC_TYPE_EDITOR;
                             break;
                     }
                     $nameDescription = new MetadataDescription($nameSchema, $assocType);
                     $nameDescription->setStatements($name);
                     $names[$key] =& $nameDescription;
                     unset($nameDescription);
                 }
                 $statements[$propertyName] =& $names;
             } else {
                 $statements[$propertyName] =& $dataObject->getData($fieldName);
             }
         }
     }
     // Set the statements in the meta-data description
     $metadataDescription->setStatements($statements);
     return $metadataDescription;
 }
 /**
  * @covers MetadataDescriptionDAO
  *
  * FIXME: The test data used here and in the CitationDAOTest
  * are very similar. We should find a way to not duplicate this
  * test data.
  */
 public function testMetadataDescriptionCrud()
 {
     $metadataDescriptionDao = DAORegistry::getDAO('MetadataDescriptionDAO');
     $nameDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR);
     $nameDescription->addStatement('given-names', $value = 'Peter');
     $nameDescription->addStatement('given-names', $value = 'B');
     $nameDescription->addStatement('surname', $value = 'Bork');
     $nameDescription->addStatement('prefix', $value = 'Mr.');
     $testDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', ASSOC_TYPE_CITATION);
     $testDescription->setAssocId(999999);
     $testDescription->setDisplayName('test meta-data description');
     $testDescription->setSeq(5);
     $testDescription->addStatement('person-group[@person-group-type="author"]', $nameDescription);
     $testDescription->addStatement('article-title', $value = 'PHPUnit in a nutshell', 'en_US');
     $testDescription->addStatement('article-title', $value = 'PHPUnit in Kürze', 'de_DE');
     $testDescription->addStatement('date', $value = '2009-08-17');
     $testDescription->addStatement('size', $value = 320);
     $testDescription->addStatement('uri', $value = 'http://phpunit.org/nutshell');
     // Create meta-data description
     $metadataDescriptionId = $metadataDescriptionDao->insertObject($testDescription);
     self::assertTrue(is_numeric($metadataDescriptionId));
     self::assertTrue($metadataDescriptionId > 0);
     // Retrieve meta-data description by id
     $metadataDescriptionById = $metadataDescriptionDao->getObjectById($metadataDescriptionId);
     $testDescription->removeSupportedMetadataAdapter('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema');
     // Required for comparison
     $metadataDescriptionById->getMetadataSchema();
     // Instantiates the internal metadata-schema.
     self::assertEquals($testDescription, $metadataDescriptionById);
     $metadataDescriptionsByAssocIdDaoFactory = $metadataDescriptionDao->getObjectsByAssocId(ASSOC_TYPE_CITATION, 999999);
     $metadataDescriptionsByAssocId = $metadataDescriptionsByAssocIdDaoFactory->toArray();
     self::assertEquals(1, count($metadataDescriptionsByAssocId));
     $metadataDescriptionsByAssocId[0]->getMetadataSchema();
     // Instantiates the internal metadata-schema.
     self::assertEquals($testDescription, $metadataDescriptionsByAssocId[0]);
     // Update meta-data description
     $testDescription->removeStatement('date');
     $testDescription->addStatement('article-title', $value = 'PHPUnit rápido', 'pt_BR');
     $metadataDescriptionDao->updateObject($testDescription);
     $testDescription->removeSupportedMetadataAdapter('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema');
     // Required for comparison
     $metadataDescriptionAfterUpdate = $metadataDescriptionDao->getObjectById($metadataDescriptionId);
     $metadataDescriptionAfterUpdate->getMetadataSchema();
     // Instantiates the internal metadata-schema.
     self::assertEquals($testDescription, $metadataDescriptionAfterUpdate);
     // Delete meta-data description
     $metadataDescriptionDao->deleteObjectsByAssocId(ASSOC_TYPE_CITATION, 999999);
     self::assertNull($metadataDescriptionDao->getObjectById($metadataDescriptionId));
 }
 /**
  * Creates a new NLM citation description and adds the data
  * of an array of property/value pairs as statements.
  * @param $metadataArray array
  * @return MetadataDescription
  */
 function &getNlm30CitationDescriptionFromMetadataArray(&$metadataArray)
 {
     // Create a new citation description
     $citationDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30CitationSchema', ASSOC_TYPE_CITATION);
     // Add the meta-data to the description
     $metadataArray = arrayClean($metadataArray);
     if (!$citationDescription->setStatements($metadataArray)) {
         $translationParams = array('filterName' => $this->getDisplayName());
         $this->addError(__('submission.citations.filter.invalidMetadata', $translationParams));
         $nullVar = null;
         return $nullVar;
     }
     // Set display name in the meta-data description
     // to the corresponding value from the filter. This is important
     // so that we later know which result came from which filter.
     $citationDescription->setDisplayName($this->getDisplayName());
     return $citationDescription;
 }
 /**
  * Prepare a MODS description that covers as much data as possible.
  * @return MetadataDescription
  */
 public function getMods34Description()
 {
     // Author
     $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.mods34.schema.Mods34NameSchema', ASSOC_TYPE_AUTHOR);
     self::assertTrue($authorDescription->addStatement('[@type]', $nameType = 'personal'));
     self::assertTrue($authorDescription->addStatement('namePart[@type="family"]', $familyName = 'some family name'));
     self::assertTrue($authorDescription->addStatement('namePart[@type="given"]', $givenName = 'given names'));
     self::assertTrue($authorDescription->addStatement('namePart[@type="termsOfAddress"]', $terms = 'Jr'));
     self::assertTrue($authorDescription->addStatement('namePart[@type="date"]', $date = '1900-1988'));
     self::assertTrue($authorDescription->addStatement('affiliation', $affiliation = 'affiliation'));
     self::assertTrue($authorDescription->addStatement('role/roleTerm[@type="code" @authority="marcrelator"]', $authorRole = 'aut'));
     // Sponsor
     $sponsorDescription = new MetadataDescription('lib.pkp.plugins.metadata.mods34.schema.Mods34NameSchema', ASSOC_TYPE_AUTHOR);
     self::assertTrue($sponsorDescription->addStatement('[@type]', $nameType = 'corporate'));
     self::assertTrue($sponsorDescription->addStatement('namePart', $namePart = 'Some Sponsor'));
     self::assertTrue($sponsorDescription->addStatement('role/roleTerm[@type="code" @authority="marcrelator"]', $sponsorRole = 'spn'));
     $mods34Description = new MetadataDescription('plugins.metadata.mods34.schema.Mods34Schema', ASSOC_TYPE_CITATION);
     self::assertTrue($mods34Description->addStatement('titleInfo/nonSort', $titleNonSort = 'the'));
     self::assertTrue($mods34Description->addStatement('titleInfo/title', $title = 'new submission title'));
     self::assertTrue($mods34Description->addStatement('titleInfo/subTitle', $subTitle = 'subtitle'));
     self::assertTrue($mods34Description->addStatement('titleInfo/partNumber', $partNumber = 'part I'));
     self::assertTrue($mods34Description->addStatement('titleInfo/partName', $partName = 'introduction'));
     self::assertTrue($mods34Description->addStatement('titleInfo/nonSort', $titleNonSort = 'ein', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('titleInfo/title', $title = 'neuer Titel', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('titleInfo/subTitle', $subTitle = 'Subtitel', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('titleInfo/partNumber', $partNumber = 'Teil I', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('titleInfo/partName', $partName = 'Einführung', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('name', $authorDescription));
     self::assertTrue($mods34Description->addStatement('name', $sponsorDescription));
     self::assertTrue($mods34Description->addStatement('typeOfResource', $typeOfResource = 'text'));
     self::assertTrue($mods34Description->addStatement('genre[@authority="marcgt"]', $marcGenre = 'book'));
     self::assertTrue($mods34Description->addStatement('originInfo/place/placeTerm[@type="text"]', $publisherPlace = 'Vancouver'));
     self::assertTrue($mods34Description->addStatement('originInfo/place/placeTerm[@type="code" @authority="iso3166"]', $publisherCountry = 'CA'));
     self::assertTrue($mods34Description->addStatement('originInfo/publisher', $publisherName = 'Public Knowledge Project'));
     self::assertTrue($mods34Description->addStatement('originInfo/dateIssued[@keyDate="yes" @encoding="w3cdtf"]', $publicationDate = '2010-09'));
     self::assertTrue($mods34Description->addStatement('originInfo/dateCreated[@encoding="w3cdtf"]', $publisherName = '2010-07-07'));
     self::assertTrue($mods34Description->addStatement('originInfo/copyrightDate[@encoding="w3cdtf"]', $publisherName = '2010'));
     self::assertTrue($mods34Description->addStatement('originInfo/edition', $edition = 'second revised edition'));
     self::assertTrue($mods34Description->addStatement('originInfo/edition', $edition = 'zweite überarbeitete Ausgabe', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('language/languageTerm[@type="code" @authority="iso639-2b"]', $submissionLanguage = 'eng'));
     self::assertTrue($mods34Description->addStatement('physicalDescription/form[@authority="marcform"]', $publicationForm = 'electronic'));
     self::assertTrue($mods34Description->addStatement('physicalDescription/internetMediaType', $mimeType = 'application/pdf'));
     self::assertTrue($mods34Description->addStatement('physicalDescription/extent', $pages = 215));
     self::assertTrue($mods34Description->addStatement('abstract', $abstract1 = 'some abstract'));
     self::assertTrue($mods34Description->addStatement('abstract', $abstract2 = 'eine Zusammenfassung', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('note', $note1 = 'some note'));
     self::assertTrue($mods34Description->addStatement('note', $note2 = 'another note'));
     self::assertTrue($mods34Description->addStatement('note', $note3 = 'übersetzte Anmerkung', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('subject/topic', $topic1 = 'some subject'));
     self::assertTrue($mods34Description->addStatement('subject/topic', $topic2 = 'some other subject'));
     self::assertTrue($mods34Description->addStatement('subject/topic', $topic3 = 'ein Thema', 'de_DE'));
     self::assertTrue($mods34Description->addStatement('subject/geographic', $geography = 'some geography'));
     self::assertTrue($mods34Description->addStatement('subject/temporal[@encoding="w3cdtf" @point="start"]', $timeStart = '1950'));
     self::assertTrue($mods34Description->addStatement('subject/temporal[@encoding="w3cdtf" @point="end"]', $timeEnd = '1954'));
     self::assertTrue($mods34Description->addStatement('identifier[@type="isbn"]', $isbn = '01234567890123'));
     self::assertTrue($mods34Description->addStatement('identifier[@type="doi"]', $doi = '40/2010ff'));
     self::assertTrue($mods34Description->addStatement('identifier[@type="uri"]', $uri = 'urn://xyz.resolver.org/12345'));
     self::assertTrue($mods34Description->addStatement('location/url[@usage="primary display"]', $url = 'http://www.sfu.ca/test-article'));
     self::assertTrue($mods34Description->addStatement('recordInfo/recordCreationDate[@encoding="w3cdtf"]', $recordDate = '2010-12-24'));
     self::assertTrue($mods34Description->addStatement('recordInfo/recordIdentifier[@source="pkp"]', $articleId = '3049'));
     self::assertTrue($mods34Description->addStatement('recordInfo/languageOfCataloging/languageTerm[@authority="iso639-2b"]', $languageOfCataloging = 'eng'));
     return $mods34Description;
 }