Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / lib / Drupal / Core / Plugin / Context / ContextHandler.php
1 <?php
2
3 namespace Drupal\Core\Plugin\Context;
4
5 use Drupal\Component\Plugin\Exception\ContextException;
6 use Drupal\Core\Cache\CacheableDependencyInterface;
7 use Drupal\Core\Plugin\ContextAwarePluginInterface;
8
9 /**
10  * Provides methods to handle sets of contexts.
11  */
12 class ContextHandler implements ContextHandlerInterface {
13
14   /**
15    * {@inheritdoc}
16    */
17   public function filterPluginDefinitionsByContexts(array $contexts, array $definitions) {
18     return array_filter($definitions, function ($plugin_definition) use ($contexts) {
19       // If this plugin doesn't need any context, it is available to use.
20       if (!isset($plugin_definition['context'])) {
21         return TRUE;
22       }
23
24       // Check the set of contexts against the requirements.
25       return $this->checkRequirements($contexts, $plugin_definition['context']);
26     });
27   }
28
29   /**
30    * {@inheritdoc}
31    */
32   public function checkRequirements(array $contexts, array $requirements) {
33     foreach ($requirements as $requirement) {
34       if ($requirement->isRequired() && !$this->getMatchingContexts($contexts, $requirement)) {
35         return FALSE;
36       }
37     }
38     return TRUE;
39   }
40
41   /**
42    * {@inheritdoc}
43    */
44   public function getMatchingContexts(array $contexts, ContextDefinitionInterface $definition) {
45     return array_filter($contexts, function (ContextInterface $context) use ($definition) {
46       return $definition->isSatisfiedBy($context);
47     });
48   }
49
50   /**
51    * {@inheritdoc}
52    */
53   public function applyContextMapping(ContextAwarePluginInterface $plugin, $contexts, $mappings = []) {
54     /** @var $contexts \Drupal\Core\Plugin\Context\ContextInterface[] */
55     $mappings += $plugin->getContextMapping();
56     // Loop through each of the expected contexts.
57
58     $missing_value = [];
59
60     foreach ($plugin->getContextDefinitions() as $plugin_context_id => $plugin_context_definition) {
61       // If this context was given a specific name, use that.
62       $context_id = isset($mappings[$plugin_context_id]) ? $mappings[$plugin_context_id] : $plugin_context_id;
63       if (!empty($contexts[$context_id])) {
64         // This assignment has been used, remove it.
65         unset($mappings[$plugin_context_id]);
66
67         // Plugins have their on context objects, only the value is applied.
68         // They also need to know about the cacheability metadata of where that
69         // value is coming from, so pass them through to those objects.
70         $plugin_context = $plugin->getContext($plugin_context_id);
71         if ($plugin_context instanceof ContextInterface && $contexts[$context_id] instanceof CacheableDependencyInterface) {
72           $plugin_context->addCacheableDependency($contexts[$context_id]);
73         }
74
75         // Pass the value to the plugin if there is one.
76         if ($contexts[$context_id]->hasContextValue()) {
77           $plugin->setContextValue($plugin_context_id, $contexts[$context_id]->getContextData());
78         }
79         elseif ($plugin_context_definition->isRequired()) {
80           // Collect required contexts that exist but are missing a value.
81           $missing_value[] = $plugin_context_id;
82         }
83       }
84       elseif ($plugin_context_definition->isRequired()) {
85         // Collect required contexts that are missing.
86         $missing_value[] = $plugin_context_id;
87       }
88       else {
89         // Ignore mappings for optional missing context.
90         unset($mappings[$plugin_context_id]);
91       }
92     }
93
94     // If there are any required contexts without a value, throw an exception.
95     if ($missing_value) {
96       throw new ContextException(sprintf('Required contexts without a value: %s.', implode(', ', $missing_value)));
97     }
98
99     // If there are any mappings that were not satisfied, throw an exception.
100     if (!empty($mappings)) {
101       throw new ContextException('Assigned contexts were not satisfied: ' . implode(',', array_keys($mappings)));
102     }
103   }
104
105 }