Pull merge.
[yaffs-website] / web / core / lib / Drupal / Core / Plugin / Context / Context.php
1 <?php
2
3 namespace Drupal\Core\Plugin\Context;
4
5 use Drupal\Component\Plugin\Context\Context as ComponentContext;
6 use Drupal\Component\Plugin\Exception\ContextException;
7 use Drupal\Core\Cache\CacheableDependencyInterface;
8 use Drupal\Core\Cache\CacheableMetadata;
9 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
10 use Drupal\Core\TypedData\TypedDataInterface;
11 use Drupal\Core\TypedData\TypedDataTrait;
12
13 /**
14  * A Drupal specific context wrapper class.
15  */
16 class Context extends ComponentContext implements ContextInterface {
17
18   use TypedDataTrait;
19   use DependencySerializationTrait;
20
21   /**
22    * The data associated with the context.
23    *
24    * @var \Drupal\Core\TypedData\TypedDataInterface
25    */
26   protected $contextData;
27
28   /**
29    * The definition to which a context must conform.
30    *
31    * @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface
32    */
33   protected $contextDefinition;
34
35   /**
36    * The cacheability metadata.
37    *
38    * @var \Drupal\Core\Cache\CacheableMetadata
39    */
40   protected $cacheabilityMetadata;
41
42   /**
43    * Create a context object.
44    *
45    * @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context_definition
46    *   The context definition.
47    * @param mixed|null $context_value
48    *   The context value object.
49    */
50   public function __construct(ContextDefinitionInterface $context_definition, $context_value = NULL) {
51     parent::__construct($context_definition, NULL);
52     $this->cacheabilityMetadata = new CacheableMetadata();
53     if (!is_null($context_value)) {
54       $this->setContextValue($context_value);
55     }
56   }
57
58   /**
59    * {@inheritdoc}
60    */
61   public function getContextValue() {
62     if (!isset($this->contextData)) {
63       $definition = $this->getContextDefinition();
64       $default_value = $definition->getDefaultValue();
65
66       if (isset($default_value)) {
67         // Keep the default value here so that subsequent calls don't have to
68         // look it up again.
69         $this->setContextValue($default_value);
70       }
71       elseif ($definition->isRequired()) {
72         $type = $definition->getDataType();
73         throw new ContextException("The '$type' context is required and not present.");
74       }
75       return $default_value;
76     }
77     return $this->getTypedDataManager()->getCanonicalRepresentation($this->contextData);
78   }
79
80   /**
81    * {@inheritdoc}
82    */
83   public function hasContextValue() {
84     return (bool) $this->contextData || parent::hasContextValue();
85   }
86
87   /**
88    * Sets the context value.
89    *
90    * @param mixed $value
91    *   The value of this context, matching the context definition.
92    */
93   protected function setContextValue($value) {
94     // Add the value as a cacheable dependency only if implements the interface
95     // to prevent it from disabling caching with a max-age 0.
96     if ($value instanceof CacheableDependencyInterface) {
97       $this->addCacheableDependency($value);
98     }
99     if ($value instanceof TypedDataInterface) {
100       $this->contextData = $value;
101     }
102     else {
103       $this->contextData = $this->getTypedDataManager()->create($this->contextDefinition->getDataDefinition(), $value);
104     }
105   }
106
107   /**
108    * {@inheritdoc}
109    */
110   public function getConstraints() {
111     return $this->contextDefinition->getConstraints();
112   }
113
114   /**
115    * {@inheritdoc}
116    */
117   public function getContextData() {
118     if (!isset($this->contextData)) {
119       $definition = $this->getContextDefinition();
120       $default_value = $definition->getDefaultValue();
121       // Store the default value so that subsequent calls don't have to look
122       // it up again.
123       $this->contextData = $this->getTypedDataManager()->create($definition->getDataDefinition(), $default_value);
124     }
125     return $this->contextData;
126   }
127
128   /**
129    * {@inheritdoc}
130    */
131   public function getContextDefinition() {
132     return $this->contextDefinition;
133   }
134
135   /**
136    * {@inheritdoc}
137    */
138   public function validate() {
139     return $this->getContextData()->validate();
140   }
141
142   /**
143    * {@inheritdoc}
144    */
145   public function addCacheableDependency($dependency) {
146     $this->cacheabilityMetadata = $this->cacheabilityMetadata->merge(CacheableMetadata::createFromObject($dependency));
147     return $this;
148   }
149
150   /**
151    * {@inheritdoc}
152    */
153   public function getCacheContexts() {
154     return $this->cacheabilityMetadata->getCacheContexts();
155   }
156
157   /**
158    * {@inheritdoc}
159    */
160   public function getCacheTags() {
161     return $this->cacheabilityMetadata->getCacheTags();
162   }
163
164   /**
165    * {@inheritdoc}
166    */
167   public function getCacheMaxAge() {
168     return $this->cacheabilityMetadata->getCacheMaxAge();
169   }
170
171   /**
172    * {@inheritdoc}
173    */
174   public static function createFromContext(ContextInterface $old_context, $value) {
175     $context = new static($old_context->getContextDefinition(), $value);
176     $context->addCacheableDependency($old_context);
177     if (method_exists($old_context, 'getTypedDataManager')) {
178       $context->setTypedDataManager($old_context->getTypedDataManager());
179     }
180     return $context;
181   }
182
183 }