/** * 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(); }
/** * 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; }