/**
  * 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');
     $metadataAdapters = $citation->getSupportedMetadataAdapters();
     foreach ($metadataAdapters as $metadataAdapter) {
         // Instantiate a meta-data description for the given schema
         $metadataDescription = new MetadataDescription($metadataAdapter->getMetadataSchemaName(), ASSOC_TYPE_CITATION);
         // Set the meta-data statements
         $metadataSchema =& $metadataAdapter->getMetadataSchema();
         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.classes.metadata.nlm.PersonStringNlmNameSchemaFilter');
                         $personStringFilter = new PersonStringNlmNameSchemaFilter($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, true);
         // Save the meta-data description for later usage.
         $this->_metadataDescriptions[] =& $metadataDescription;
         unset($metadataDescription);
     }
     return $this->isValid();
 }
示例#2
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;
 }