Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
MetadataDescription.inc.php
1 <?php
2 
101 import('lib.pkp.classes.core.DataObject');
102 
103 define('METADATA_DESCRIPTION_REPLACE_ALL', 0x01);
104 define('METADATA_DESCRIPTION_REPLACE_PROPERTIES', 0x02);
105 define('METADATA_DESCRIPTION_REPLACE_NOTHING', 0x03);
106 
107 define('METADATA_DESCRIPTION_UNKNOWN_LOCALE', 'unknown');
108 
112 
115 
117  var $_assocType;
118 
121 
127 
132  var $_seq;
133 
137  function MetadataDescription($metadataSchemaName, $assocType) {
138  assert(is_string($metadataSchemaName) && is_integer($assocType));
139  parent::DataObject();
140  $this->_metadataSchemaName = $metadataSchemaName;
141  $this->_assocType = $assocType;
142  }
143 
144  //
145  // Get/set methods
146  //
151  function getMetadataSchemaName() {
153  }
154 
159  function &getMetadataSchema() {
160  // Lazy-load the meta-data schema if this has
161  // not been done before.
162  if (is_null($this->_metadataSchema)) {
163  $this->_metadataSchema =& instantiate($this->getMetadataSchemaName(), 'MetadataSchema');
164  assert(is_object($this->_metadataSchema));
165  }
166  return $this->_metadataSchema;
167  }
168 
173  function getAssocType() {
174  return $this->_assocType;
175  }
176 
181  function getAssocId() {
182  return $this->_assocId;
183  }
184 
189  function setAssocId($assocId) {
190  $this->_assocId = $assocId;
191  }
192 
199  function getAssoc() {
200  $assocType = $this->getAssocType();
201  $assocId = $this->getAssocId();
202  assert(isset($assocType) && isset($assocId));
203  return $assocType.':'.$assocId;
204  }
205 
210  function setDisplayName($displayName) {
211  $this->_displayName = $displayName;
212  }
213 
218  function getDisplayName() {
219  return $this->_displayName;
220  }
221 
226  function setSeq($seq) {
227  $this->_seq = $seq;
228  }
229 
234  function getSeq() {
235  return $this->_seq;
236  }
237 
249  function addStatement($propertyName, $value, $locale = null, $replace = false) {
250  // Check the property
251  $property =& $this->getProperty($propertyName);
252  if (is_null($property)) return false;
253  assert(is_a($property, 'MetadataProperty'));
254 
255  // Check that the property is allowed for the described resource
256  if (!in_array($this->_assocType, $property->getAssocTypes())) return false;
257 
258  // Handle translation
259  $translated = $property->getTranslated();
260  if (isset($locale) && !$translated) return false;
261  if (!isset($locale) && $translated) {
262  // Retrieve the current locale
263  $locale = AppLocale::getLocale();
264  }
265 
266  // Check that the value is compliant with the property specification
267  if ($property->isValid($value, $locale) === false) return false;
268 
269  // Handle cardinality
270  $existingValue =& $this->getStatement($propertyName, $locale);
271  switch ($property->getCardinality()) {
272  case METADATA_PROPERTY_CARDINALITY_ONE:
273  if (isset($existingValue) && !$replace) return false;
274  $newValue = $value;
275  break;
276 
277  case METADATA_PROPERTY_CARDINALITY_MANY:
278  if (isset($existingValue) && !$replace) {
279  assert(is_array($existingValue));
280  $newValue = $existingValue;
281  array_push($newValue, $value);
282  } else {
283  $newValue = array($value);
284  }
285  break;
286 
287  default:
288  assert(false);
289  }
290 
291  // Add the value
292  $this->setData($propertyName, $newValue, $locale);
293  return true;
294  }
295 
305  function removeStatement($propertyName, $locale = null) {
306  // Remove the statement if it exists
307  if (isset($propertyName) && $this->hasData($propertyName, $locale)) {
308  $this->setData($propertyName, null, $locale);
309  return true;
310  }
311 
312  return false;
313  }
314 
319  function &getStatements() {
320  // Do not retrieve the data by-ref
321  // otherwise the following unset()
322  // will change internal state.
323  $allData = $this->getAllData();
324 
325  // Unset data variables that are not statements
326  unset($allData['id']);
327  return $allData;
328  }
329 
337  function &getStatement($propertyName, $locale = null) {
338  // Check the property
339  $property =& $this->getProperty($propertyName);
340  assert(isset($property) && is_a($property, 'MetadataProperty'));
341 
342  // Handle translation
343  $translated = $property->getTranslated();
344  if (!$translated) assert(is_null($locale));
345  if ($translated && !isset($locale)) {
346  // Retrieve the current locale
347  $locale = AppLocale::getLocale();
348  }
349 
350  // Retrieve the value
351  return $this->getData($propertyName, $locale);
352  }
353 
362  function &getStatementTranslations($propertyName) {
363  assert($this->isTranslatedProperty($propertyName));
364  return $this->getData($propertyName);
365  }
366 
381  function setStatements(&$statements, $replace = METADATA_DESCRIPTION_REPLACE_PROPERTIES) {
382  assert(in_array($replace, $this->_allowedReplaceLevels()));
383 
384  // Make a backup copy of all existing statements.
385  $statementsBackup = $this->getAllData();
386 
387  if ($replace == METADATA_DESCRIPTION_REPLACE_ALL) {
388  // Delete existing statements
389  $emptyArray = array();
390  $this->setAllData($emptyArray);
391  }
392 
393  // Add statements one by one to detect invalid values.
394  foreach($statements as $propertyName => $content) {
395  assert(!empty($content));
396 
397  // Transform scalars or translated fields to arrays so that
398  // we can handle properties with different cardinalities in
399  // the same way.
400  if (is_scalar($content) || is_string(key($content))) {
401  $values = array(&$content);
402  } else {
403  $values =& $content;
404  }
405 
406  if ($replace == METADATA_DESCRIPTION_REPLACE_PROPERTIES) {
407  $replaceProperty = true;
408  } else {
409  $replaceProperty = false;
410  }
411 
412  $valueIndex = 0;
413  foreach($values as $value) {
414  $firstValue = ($valueIndex == 0) ? true : false;
415  // Is this a translated property?
416  if (is_array($value)) {
417  foreach($value as $locale => $translation) {
418  // Handle cardinality many and one in the same way
419  if (is_scalar($translation)) {
420  $translationValues = array(&$translation);
421  } else {
422  $translationValues =& $translation;
423  }
424  $translationIndex = 0;
425  foreach($translationValues as $translationValue) {
426  $firstTranslation = ($translationIndex == 0) ? true : false;
427  // Add a statement (replace existing statement if any)
428  if (!($this->addStatement($propertyName, $translationValue, $locale, $firstTranslation && $replaceProperty))) {
429  $this->setAllData($statementsBackup);
430  return false;
431  }
432  unset($translationValue);
433  $translationIndex++;
434  }
435  unset($translationValues);
436  }
437  unset($translation);
438  } else {
439  // Add a statement (replace existing statement if any)
440  if (!($this->addStatement($propertyName, $value, null, $firstValue && $replaceProperty))) {
441  $this->setAllData($statementsBackup);
442  return false;
443  }
444  }
445  unset($value);
446  $valueIndex++;
447  }
448  unset($values);
449  }
450  return true;
451  }
452 
458  function &getProperties() {
459  $metadataSchema =& $this->getMetadataSchema();
460  return $metadataSchema->getProperties();
461  }
462 
469  function &getProperty($propertyName) {
470  $metadataSchema =& $this->getMetadataSchema();
471  return $metadataSchema->getProperty($propertyName);
472  }
473 
480  function getNamespacedPropertyId($propertyName) {
481  $metadataSchema =& $this->getMetadataSchema();
482  return $metadataSchema->getNamespacedPropertyId($propertyName);
483  }
484 
490  function getPropertyNames() {
491  $metadataSchema =& $this->getMetadataSchema();
492  return $metadataSchema->getPropertyNames();
493  }
494 
501  function getPropertyNamesByType($propertyType) {
502  $metadataSchema =& $this->getMetadataSchema();
503  return $metadataSchema->getPropertyNamesByType($propertyType);
504  }
505 
511  function getSetPropertyNames() {
512  return array_keys($this->getStatements());
513  }
514 
521  function hasProperty($propertyName) {
522  $metadataSchema =& $this->getMetadataSchema();
523  return $metadataSchema->hasProperty($propertyName);
524  }
525 
531  function hasStatement($propertyName) {
532  $statements =& $this->getStatements();
533  return (isset($statements[$propertyName]));
534  }
535 
542  function isTranslatedProperty($propertyName) {
543  $property = $this->getProperty($propertyName);
544  assert(is_a($property, 'MetadataProperty'));
545  return $property->getTranslated();
546  }
547 
548 
549  //
550  // Private helper methods
551  //
556  static function _allowedReplaceLevels() {
557  static $allowedReplaceLevels = array(
558  METADATA_DESCRIPTION_REPLACE_ALL,
559  METADATA_DESCRIPTION_REPLACE_PROPERTIES,
560  METADATA_DESCRIPTION_REPLACE_NOTHING
561  );
562  return $allowedReplaceLevels;
563  }
564 }
565 
566 ?>
removeStatement($propertyName, $locale=null)
& getStatementTranslations($propertyName)
setAllData(&$data)
& getData($key, $locale=null)
static getLocale()
getNamespacedPropertyId($propertyName)
addStatement($propertyName, $value, $locale=null, $replace=false)
setStatements(&$statements, $replace=METADATA_DESCRIPTION_REPLACE_PROPERTIES)
Any class with an associated DAO should extend this class.
setData($key, $value, $locale=null)
MetadataDescription($metadataSchemaName, $assocType)
getPropertyNamesByType($propertyType)
hasData($key, $locale=null)
Class modeling a description (DCMI abstract model) or subject- predicate-object graph (RDF)...
& getStatement($propertyName, $locale=null)