/**
  * @covers ValidatorControlledVocab
  */
 public function testValidatorControlledVocab()
 {
     // Mock a ControlledVocab object
     $mockControlledVocab = $this->getMock('ControlledVocab', array('enumerate'));
     $mockControlledVocab->setId(1);
     $mockControlledVocab->setAssocType(ASSOC_TYPE_CITATION);
     $mockControlledVocab->setAssocId(333);
     $mockControlledVocab->setSymbolic('testVocab');
     // Set up the mock enumerate() method
     $mockControlledVocab->expects($this->any())->method('enumerate')->will($this->returnValue(array(1 => 'vocab1', 2 => 'vocab2')));
     // Mock the ControlledVocabDAO
     $mockControlledVocabDAO = $this->getMock('ControlledVocabDAO', array('getBySymbolic'));
     // Set up the mock getBySymbolic() method
     $mockControlledVocabDAO->expects($this->any())->method('getBySymbolic')->with('testVocab', ASSOC_TYPE_CITATION, 333)->will($this->returnValue($mockControlledVocab));
     DAORegistry::registerDAO('ControlledVocabDAO', $mockControlledVocabDAO);
     $validator = new ValidatorControlledVocab('testVocab', ASSOC_TYPE_CITATION, 333);
     self::assertTrue($validator->isValid('1'));
     self::assertTrue($validator->isValid('2'));
     self::assertFalse($validator->isValid('3'));
 }
 /**
  * Validate a given input against the property specification
  *
  * The given value must validate against at least one of the
  * allowed types. The first allowed type id will be returned as
  * validation result. If the given value fits none of the allowed
  * types, then we'll return 'false'.
  *
  * @param $value mixed the input to be validated
  * @param $locale string the locale to be used for validation
  * @return array|boolean an array with a single entry of the format
  *  "type => additional type parameter" against which the value
  *  validated or boolean false if not validated at all.
  */
 function isValid($value, $locale = null)
 {
     // We never accept null values or arrays.
     if (is_null($value) || is_array($value)) {
         return false;
     }
     // Translate the locale.
     if (is_null($locale)) {
         $locale = '';
     }
     // MetadataProperty::getSupportedTypes() returns an ordered
     // list of possible meta-data types with the most specific
     // type coming first so that we always correctly identify
     // specializations (e.g. a date is a specialized string).
     $allowedTypes = $this->getAllowedTypes();
     foreach (MetadataProperty::getSupportedTypes() as $testedType) {
         if (isset($allowedTypes[$testedType])) {
             foreach ($allowedTypes[$testedType] as $allowedTypeParam) {
                 // Type specific validation
                 switch ($testedType) {
                     case METADATA_PROPERTY_TYPE_COMPOSITE:
                         // Composites can either be represented by a meta-data description
                         // or by a string of the form AssocType:AssocId if the composite
                         // has already been persisted in the database.
                         switch (true) {
                             // Test for MetadataDescription format
                             case is_a($value, 'MetadataDescription'):
                                 $assocType = $value->getAssocType();
                                 break;
                                 // Test for AssocType:AssocId format
                             // Test for AssocType:AssocId format
                             case is_string($value):
                                 $valueParts = explode(':', $value);
                                 if (count($valueParts) != 2) {
                                     break 2;
                                 }
                                 // break the outer switch
                                 list($assocType, $assocId) = $valueParts;
                                 if (!(is_numeric($assocType) && is_numeric($assocId))) {
                                     break 2;
                                 }
                                 // break the outer switch
                                 $assocType = (int) $assocType;
                                 break;
                             default:
                                 // None of the allowed types
                                 break;
                         }
                         // Check that the association type matches
                         // with the allowed association type (which
                         // is configured as an additional type parameter).
                         if (isset($assocType) && $assocType === $allowedTypeParam) {
                             return array(METADATA_PROPERTY_TYPE_COMPOSITE => $assocType);
                         }
                         break;
                     case METADATA_PROPERTY_TYPE_VOCABULARY:
                         // Interpret the type parameter of this type like this:
                         // symbolic[:assoc-type:assoc-id]. If no assoc type/id are
                         // given then we assume :0:0 to represent site-wide vocabs.
                         $vocabNameParts = explode(':', $allowedTypeParam);
                         $vocabNamePartsCount = count($vocabNameParts);
                         switch ($vocabNamePartsCount) {
                             case 1:
                                 // assume a site-wide vocabulary
                                 $symbolic = $allowedTypeParam;
                                 $assocType = $assocId = 0;
                                 break;
                             case 3:
                                 // assume a context-specific vocabulary
                                 list($symbolic, $assocType, $assocId) = $vocabNameParts;
                                 break;
                             default:
                                 // Invalid configuration
                                 assert(false);
                         }
                         if (is_string($value)) {
                             // Try to translate the string value into a controlled vocab entry
                             $controlledVocabEntryDao =& DAORegistry::getDao('ControlledVocabEntryDAO');
                             /* @var $controlledVocabEntryDao ControlledVocabEntryDAO */
                             if (!is_null($controlledVocabEntryDao->getBySetting($value, $symbolic, $assocType, $assocId, 'name', $locale))) {
                                 // The string was successfully translated so mark it as "valid".
                                 return array(METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam);
                             }
                         }
                         if (is_integer($value)) {
                             // Validate with controlled vocabulary validator
                             import('lib.pkp.classes.validation.ValidatorControlledVocab');
                             $validator = new ValidatorControlledVocab($symbolic, $assocType, $assocId);
                             if ($validator->isValid($value)) {
                                 return array(METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam);
                             }
                         }
                         break;
                     case METADATA_PROPERTY_TYPE_URI:
                         // Validate with the URI validator
                         import('lib.pkp.classes.validation.ValidatorUri');
                         $validator = new ValidatorUri();
                         if ($validator->isValid($value)) {
                             return array(METADATA_PROPERTY_TYPE_URI => null);
                         }
                         break;
                     case METADATA_PROPERTY_TYPE_DATE:
                         // We allow the following patterns:
                         // YYYY-MM-DD, YYYY-MM and YYYY
                         $datePattern = '/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/';
                         if (!preg_match($datePattern, $value)) {
                             break;
                         }
                         // Check whether the given string is really a valid date
                         $dateParts = explode('-', $value);
                         // Set the day and/or month to 1 if not set
                         $dateParts = array_pad($dateParts, 3, 1);
                         // Extract the date parts
                         list($year, $month, $day) = $dateParts;
                         // Validate the date (only leap days will pass unnoticed ;-) )
                         // Who invented this argument order?
                         if (checkdate($month, $day, $year)) {
                             return array(METADATA_PROPERTY_TYPE_DATE => null);
                         }
                         break;
                     case METADATA_PROPERTY_TYPE_INTEGER:
                         if (is_integer($value)) {
                             return array(METADATA_PROPERTY_TYPE_INTEGER => null);
                         }
                         break;
                     case METADATA_PROPERTY_TYPE_STRING:
                         if (is_string($value)) {
                             return array(METADATA_PROPERTY_TYPE_STRING => null);
                         }
                         break;
                     default:
                         // Unknown type. As we validate type in the setter, this
                         // should be unreachable code.
                         assert(false);
                 }
             }
         }
     }
     // Return false if the value didn't validate against any
     // of the allowed types.
     return false;
 }
Beispiel #3
0
 /**
  * Validate a given input against the property specification
  *
  * @param $value mixed the input to be validated
  * @return boolean validation success
  */
 function isValid($value)
 {
     // We never accept null values or arrays.
     if (is_null($value) || is_array($value)) {
         return false;
     }
     // The value must validate against at least one type
     $isValid = false;
     foreach ($this->getTypes() as $type) {
         // Extract data from composite type
         if (is_array($type)) {
             assert(count($type) == 1 && key($type) == METADATA_PROPERTY_TYPE_COMPOSITE);
             $compositeType = $type[METADATA_PROPERTY_TYPE_COMPOSITE];
             $type = METADATA_PROPERTY_TYPE_COMPOSITE;
         }
         // Type specific validation
         switch ($type) {
             case METADATA_PROPERTY_TYPE_STRING:
                 if (is_string($value)) {
                     $isValid = true;
                 }
                 break;
             case METADATA_PROPERTY_TYPE_VOCABULARY:
                 // Interpret the name of this property as a controlled vocabulary triple
                 $vocabNameParts = explode(':', $this->getName());
                 assert(count($vocabNameParts) == 3);
                 list($symbolic, $assocType, $assocId) = $vocabNameParts;
                 // Validate with controlled vocabulary validator
                 import('validation.ValidatorControlledVocab');
                 $validator = new ValidatorControlledVocab($symbolic, $assocType, $assocId);
                 if ($validator->isValid($value)) {
                     $isValid = true;
                 }
                 break;
             case METADATA_PROPERTY_TYPE_URI:
                 // Validate with the URI validator
                 import('validation.ValidatorUri');
                 $validator = new ValidatorUri();
                 if ($validator->isValid($value)) {
                     $isValid = true;
                 }
                 break;
             case METADATA_PROPERTY_TYPE_DATE:
                 // We allow the following patterns:
                 // YYYY-MM-DD, YYYY-MM and YYYY
                 $datePattern = '/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/';
                 if (!preg_match($datePattern, $value)) {
                     break;
                 }
                 // Check whether the given string is really a valid date
                 $dateParts = explode('-', $value);
                 // Set the day and/or month to 1 if not set
                 $dateParts = array_pad($dateParts, 3, 1);
                 // Extract the date parts
                 list($year, $month, $day) = $dateParts;
                 // Validate the date (only leap days will pass unnoticed ;-) )
                 // Who invented this argument order?
                 if (checkdate($month, $day, $year)) {
                     $isValid = true;
                 }
                 break;
             case METADATA_PROPERTY_TYPE_INTEGER:
                 if (is_integer($value)) {
                     $isValid = true;
                 }
                 break;
             case METADATA_PROPERTY_TYPE_COMPOSITE:
                 // Composites can either be represented by a meta-data description
                 // or by a string of the form AssocType:AssocId if the composite
                 // has already been persisted in the database.
                 switch (true) {
                     // Test for MetadataDescription format
                     case is_a($value, 'MetadataDescription'):
                         $assocType = $value->getAssocType();
                         break;
                         // Test for AssocType:AssocId format
                     // Test for AssocType:AssocId format
                     case is_string($value):
                         $valueParts = explode(':', $value);
                         if (count($valueParts) != 2) {
                             break 2;
                         }
                         // break the outer switch
                         list($assocType, $assocId) = $valueParts;
                         if (!(is_numeric($assocType) && is_numeric($assocId))) {
                             break 2;
                         }
                         // break the outer switch
                         $assocType = (int) $assocType;
                         break;
                     default:
                         // None of the allowed types
                         break;
                 }
                 // Check that the association type matches
                 if (isset($assocType) && $assocType === $compositeType) {
                     $isValid = true;
                 }
                 break;
             default:
                 // Unknown type. As we validate type in the setter, this
                 // should be unreachable code.
                 assert(false);
         }
         // The value only has to validate against one of the given
         // types: No need to validate against subsequent allowed types.
         if ($isValid) {
             break;
         }
     }
     // Will return false if the value didn't validate against any
     // of the types, otherwise true.
     return $isValid;
 }