public function ContextHandler::applyContextMapping in Drupal 9
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Plugin/Context/ContextHandler.php \Drupal\Core\Plugin\Context\ContextHandler::applyContextMapping()
Prepares a plugin for evaluation.
Parameters
\Drupal\Core\Plugin\ContextAwarePluginInterface $plugin: A plugin about to be evaluated.
\Drupal\Core\Plugin\Context\ContextInterface[] $contexts: An array of contexts to set on the plugin. They will only be set if they match the plugin's context definitions.
array $mappings: (optional) A mapping of the expected assignment names to their context names. For example, if one of the $contexts is named 'current_user', but the plugin expects a context named 'user', then this map would contain 'user' => 'current_user'.
Throws
\Drupal\Component\Plugin\Exception\ContextException Thrown when a context assignment was not satisfied.
\Drupal\Component\Plugin\Exception\MissingValueContextException Thrown when a context is provided but has no value. Only thrown if no contexts are missing.
Overrides ContextHandlerInterface::applyContextMapping
File
- core/
lib/ Drupal/ Core/ Plugin/ Context/ ContextHandler.php, line 83
Class
- ContextHandler
- Provides methods to handle sets of contexts.
Namespace
Drupal\Core\Plugin\ContextCode
public function applyContextMapping(ContextAwarePluginInterface $plugin, $contexts, $mappings = []) {
/** @var \Drupal\Core\Plugin\Context\ContextInterface[] $contexts */
$mappings += $plugin
->getContextMapping();
// Loop through each of the expected contexts.
$missing_value = [];
foreach ($plugin
->getContextDefinitions() as $plugin_context_id => $plugin_context_definition) {
// If this context was given a specific name, use that.
$context_id = isset($mappings[$plugin_context_id]) ? $mappings[$plugin_context_id] : $plugin_context_id;
if (!empty($contexts[$context_id])) {
// This assignment has been used, remove it.
unset($mappings[$plugin_context_id]);
// Plugins have their on context objects, only the value is applied.
// They also need to know about the cacheability metadata of where that
// value is coming from, so pass them through to those objects.
$plugin_context = $plugin
->getContext($plugin_context_id);
if ($plugin_context instanceof ContextInterface && $contexts[$context_id] instanceof CacheableDependencyInterface) {
$plugin_context
->addCacheableDependency($contexts[$context_id]);
}
// Pass the value to the plugin if there is one.
if ($contexts[$context_id]
->hasContextValue()) {
$plugin
->setContext($plugin_context_id, $contexts[$context_id]);
}
elseif ($plugin_context_definition
->isRequired()) {
// Collect required contexts that exist but are missing a value.
$missing_value[] = $plugin_context_id;
}
// Proceed to the next definition.
continue;
}
try {
$context = $plugin
->getContext($context_id);
} catch (ContextException $e) {
$context = NULL;
}
if ($context && $context
->hasContextValue()) {
// Ignore mappings if the plugin has a value for a missing context.
unset($mappings[$plugin_context_id]);
continue;
}
if ($plugin_context_definition
->isRequired()) {
// Collect required contexts that are missing.
$missing_value[] = $plugin_context_id;
continue;
}
// Ignore mappings for optional missing context.
unset($mappings[$plugin_context_id]);
}
// If there are any mappings that were not satisfied, throw an exception.
// This is a more severe problem than missing values, so check and throw
// this first.
if (!empty($mappings)) {
throw new ContextException('Assigned contexts were not satisfied: ' . implode(',', array_keys($mappings)));
}
// If there are any required contexts without a value, throw an exception.
if ($missing_value) {
throw new MissingValueContextException($missing_value);
}
}