TypedData.php 5.0 KB

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