TypedData.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. namespace Drupal\Core\TypedData;
  3. use Drupal\Component\Plugin\PluginInspectionInterface;
  4. use Drupal\Core\DependencyInjection\DependencySerializationTrait;
  5. use Drupal\Core\StringTranslation\StringTranslationTrait;
  6. /**
  7. * The abstract base class for typed data.
  8. *
  9. * Classes deriving from this base class have to declare $value
  10. * or override getValue() or setValue().
  11. *
  12. * @ingroup typed_data
  13. */
  14. abstract class TypedData implements TypedDataInterface, PluginInspectionInterface {
  15. use DependencySerializationTrait;
  16. use StringTranslationTrait;
  17. use TypedDataTrait;
  18. /**
  19. * The data definition.
  20. *
  21. * @var \Drupal\Core\TypedData\DataDefinitionInterface
  22. */
  23. protected $definition;
  24. /**
  25. * The property name.
  26. *
  27. * @var string
  28. */
  29. protected $name;
  30. /**
  31. * The parent typed data object.
  32. *
  33. * @var \Drupal\Core\TypedData\TraversableTypedDataInterface|null
  34. */
  35. protected $parent;
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public static function createInstance($definition, $name = NULL, TraversableTypedDataInterface $parent = NULL) {
  40. return new static($definition, $name, $parent);
  41. }
  42. /**
  43. * Constructs a TypedData object given its definition and context.
  44. *
  45. * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
  46. * The data definition.
  47. * @param string $name
  48. * (optional) The name of the created property, or NULL if it is the root
  49. * of a typed data tree. Defaults to NULL.
  50. * @param \Drupal\Core\TypedData\TypedDataInterface $parent
  51. * (optional) The parent object of the data property, or NULL if it is the
  52. * root of a typed data tree. Defaults to NULL.
  53. *
  54. * @see \Drupal\Core\TypedData\TypedDataManager::create()
  55. */
  56. public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
  57. $this->definition = $definition;
  58. $this->parent = $parent;
  59. $this->name = $name;
  60. }
  61. /**
  62. * {@inheritdoc}
  63. */
  64. public function getPluginId() {
  65. return $this->definition['type'];
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. public function getPluginDefinition() {
  71. return $this->getTypedDataManager()->getDefinition($this->definition->getDataType());
  72. }
  73. /**
  74. * {@inheritdoc}
  75. */
  76. public function getDataDefinition() {
  77. return $this->definition;
  78. }
  79. /**
  80. * {@inheritdoc}
  81. */
  82. public function getValue() {
  83. return $this->value;
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function setValue($value, $notify = TRUE) {
  89. $this->value = $value;
  90. // Notify the parent of any changes.
  91. if ($notify && isset($this->parent)) {
  92. $this->parent->onChange($this->name);
  93. }
  94. }
  95. /**
  96. * {@inheritdoc}
  97. */
  98. public function getString() {
  99. return (string) $this->getValue();
  100. }
  101. /**
  102. * {@inheritdoc}
  103. */
  104. public function getConstraints() {
  105. $constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager();
  106. $constraints = [];
  107. foreach ($this->definition->getConstraints() as $name => $options) {
  108. $constraints[] = $constraint_manager->create($name, $options);
  109. }
  110. return $constraints;
  111. }
  112. /**
  113. * {@inheritdoc}
  114. */
  115. public function validate() {
  116. return $this->getTypedDataManager()->getValidator()->validate($this);
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function applyDefaultValue($notify = TRUE) {
  122. // Default to no default value.
  123. $this->setValue(NULL, $notify);
  124. return $this;
  125. }
  126. /**
  127. * {@inheritdoc}
  128. */
  129. public function setContext($name = NULL, TraversableTypedDataInterface $parent = NULL) {
  130. $this->parent = $parent;
  131. $this->name = $name;
  132. }
  133. /**
  134. * {@inheritdoc}
  135. */
  136. public function getName() {
  137. return $this->name;
  138. }
  139. /**
  140. * {@inheritdoc}
  141. */
  142. public function getRoot() {
  143. if (isset($this->parent)) {
  144. return $this->parent->getRoot();
  145. }
  146. // If no parent is set, this is the root of the data tree.
  147. return $this;
  148. }
  149. /**
  150. * {@inheritdoc}
  151. */
  152. public function getPropertyPath() {
  153. if (isset($this->parent)) {
  154. // The property path of this data object is the parent's path appended
  155. // by this object's name.
  156. $prefix = $this->parent->getPropertyPath();
  157. return (strlen($prefix) ? $prefix . '.' : '') . $this->name;
  158. }
  159. // If no parent is set, this is the root of the data tree. Thus the property
  160. // path equals the name of this data object.
  161. elseif (isset($this->name)) {
  162. return $this->name;
  163. }
  164. return '';
  165. }
  166. /**
  167. * {@inheritdoc}
  168. */
  169. public function getParent() {
  170. return $this->parent;
  171. }
  172. }