34 define(
'METADATA_PROPERTY_TYPE_STRING', 0x01);
37 define(
'METADATA_PROPERTY_TYPE_DATE', 0x02);
38 define(
'METADATA_PROPERTY_TYPE_INTEGER', 0x03);
41 define(
'METADATA_PROPERTY_TYPE_VOCABULARY', 0x04);
44 define(
'METADATA_PROPERTY_TYPE_URI', 0x05);
47 define(
'METADATA_PROPERTY_TYPE_COMPOSITE', 0x06);
50 define(
'METADATA_PROPERTY_CARDINALITY_ONE', 0x01);
51 define(
'METADATA_PROPERTY_CARDINALITY_MANY', 0x02);
90 function __construct($name, $assocTypes = array(), $allowedTypes = METADATA_PROPERTY_TYPE_STRING,
91 $translated =
false, $cardinality = METADATA_PROPERTY_CARDINALITY_ONE, $displayName =
null, $validationMessage =
null, $mandatory =
false) {
94 if (!is_string($name))
throw new InvalidArgumentException(
'$name should be a string.');
95 if (!is_array($assocTypes))
throw new InvalidArgumentException(
'$assocTypes should be an array.');
100 if (is_scalar($allowedTypes) || count($allowedTypes) == 1) {
101 $allowedTypes = array($allowedTypes);
105 $canonicalizedTypes = array();
106 foreach($allowedTypes as $allowedType) {
107 if (is_array($allowedType)) {
110 assert(count($allowedType) == 1);
114 $allowedTypeId = key($allowedType);
115 $allowedTypeParam = current($allowedType);
118 $allowedTypeId = $allowedType;
119 $allowedTypeParam =
null;
128 $canonicalizedTypes[$allowedTypeId][] = $allowedTypeParam;
131 switch($allowedTypeId) {
132 case METADATA_PROPERTY_TYPE_COMPOSITE:
134 if (!is_integer($allowedTypeParam))
throw new InvalidArgumentException(
'Allowed type parameter should be an integer.');
136 if ($translated)
throw new InvalidArgumentException(
'Properties that allow composite types cannot be translated.');
139 case METADATA_PROPERTY_TYPE_VOCABULARY:
141 if (!is_string($allowedTypeParam))
throw new InvalidArgumentException(
'Allowed type parameter should be a string.');
146 if (!is_null($allowedTypeParam))
throw new InvalidArgumentException(
'An additional parameter was supplied for an unsupported metadata property type.');
151 if (!is_bool($translated))
throw new InvalidArgumentException(
'$translated must be a boolean');
155 if (is_null($displayName)) $displayName =
'metadata.property.displayName.'.$name;
156 if (!is_string($displayName))
throw new InvalidArgumentException(
'$displayName must be a string.');
159 if (is_null($validationMessage)) $validationMessage =
'metadata.property.validationMessage.'.$name;
160 if (!is_string($validationMessage))
throw new InvalidArgumentException(
'$validationMessage must be a string.');
164 $this->_name = (string)$name;
165 $this->_assocTypes =& $assocTypes;
166 $this->_allowedTypes =& $canonicalizedTypes;
167 $this->_translated = (boolean)$translated;
168 $this->_cardinality = (integer)$cardinality;
169 $this->_displayName = (string)$displayName;
170 $this->_validationMessage = (string)$validationMessage;
171 $this->_mandatory = (boolean)$mandatory;
192 '[',
']',
'@',
'"',
'='
197 $propertyId = trim(str_replace($from, $to, $this->
getName()),
'-');
280 function isValid($value, $locale =
null) {
282 if (is_null($value) || is_array($value))
return false;
285 if (is_null($locale)) $locale =
'';
293 if (isset($allowedTypes[$testedType])) {
294 foreach ($allowedTypes[$testedType] as $allowedTypeParam) {
296 switch ($testedType) {
297 case METADATA_PROPERTY_TYPE_COMPOSITE:
303 case is_a($value,
'MetadataDescription'):
304 $assocType = $value->getAssocType();
308 case is_string($value):
309 $valueParts = explode(
':', $value);
310 if (count($valueParts) != 2)
break 2;
311 list($assocType, $assocId) = $valueParts;
312 if (!(is_numeric($assocType) && is_numeric($assocId)))
break 2;
313 $assocType = (integer)$assocType;
324 if (isset($assocType) && $assocType === $allowedTypeParam)
return array(METADATA_PROPERTY_TYPE_COMPOSITE => $assocType);
327 case METADATA_PROPERTY_TYPE_VOCABULARY:
331 $vocabNameParts = explode(
':', $allowedTypeParam);
332 $vocabNamePartsCount = count($vocabNameParts);
333 switch ($vocabNamePartsCount) {
336 $symbolic = $allowedTypeParam;
337 $assocType = $assocId = 0;
342 list($symbolic, $assocType, $assocId) = $vocabNameParts;
350 if (is_string($value)) {
353 if (!is_null($controlledVocabEntryDao->getBySetting($value, $symbolic, $assocType, $assocId,
'name', $locale))) {
355 return array(METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam);
359 if (is_integer($value)) {
361 import(
'lib.pkp.classes.validation.ValidatorControlledVocab');
363 if ($validator->isValid($value)) {
364 return array(METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam);
370 case METADATA_PROPERTY_TYPE_URI:
371 import(
'lib.pkp.classes.validation.ValidatorFactory');
373 array(
'uri' => $value),
374 array(
'uri' =>
'url')
376 if (!$validator->fails()) {
377 return array(METADATA_PROPERTY_TYPE_URI =>
null);
381 case METADATA_PROPERTY_TYPE_DATE:
384 $datePattern =
'/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/';
385 if (!preg_match($datePattern, $value))
break;
388 $dateParts = explode(
'-', $value);
390 $dateParts = array_pad($dateParts, 3, 1);
392 list($year, $month, $day) = $dateParts;
395 if (checkdate($month, $day, $year))
return array(METADATA_PROPERTY_TYPE_DATE =>
null);
398 case METADATA_PROPERTY_TYPE_INTEGER:
399 if (is_integer($value))
return array(METADATA_PROPERTY_TYPE_INTEGER =>
null);
402 case METADATA_PROPERTY_TYPE_STRING:
403 if (is_string($value))
return array(METADATA_PROPERTY_TYPE_STRING =>
null);
435 static $_supportedTypes = array(
436 METADATA_PROPERTY_TYPE_COMPOSITE,
437 METADATA_PROPERTY_TYPE_VOCABULARY,
438 METADATA_PROPERTY_TYPE_URI,
439 METADATA_PROPERTY_TYPE_DATE,
440 METADATA_PROPERTY_TYPE_INTEGER,
441 METADATA_PROPERTY_TYPE_STRING
443 return $_supportedTypes;
451 static $_supportedCardinalities = array(
452 METADATA_PROPERTY_CARDINALITY_ONE,
453 METADATA_PROPERTY_CARDINALITY_MANY
455 return $_supportedCardinalities;