function ContextHandler::applyContextMapping

Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Plugin/Context/ContextHandler.php \Drupal\Core\Plugin\Context\ContextHandler::applyContextMapping()
  2. 10 core/lib/Drupal/Core/Plugin/Context/ContextHandler.php \Drupal\Core\Plugin\Context\ContextHandler::applyContextMapping()
  3. 11.x core/lib/Drupal/Core/Plugin/Context/ContextHandler.php \Drupal\Core\Plugin\Context\ContextHandler::applyContextMapping()

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\Context

Code

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 = $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);
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.