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