ContextDefinition.php

Same filename in this branch
  1. 11.x core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
Same filename and directory in other branches
  1. 9 core/lib/Drupal/Core/Annotation/ContextDefinition.php
  2. 9 core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
  3. 8.9.x core/lib/Drupal/Core/Annotation/ContextDefinition.php
  4. 8.9.x core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php
  5. 10 core/lib/Drupal/Core/Annotation/ContextDefinition.php
  6. 10 core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php

Namespace

Drupal\Core\Annotation

File

core/lib/Drupal/Core/Annotation/ContextDefinition.php

View source
<?php

namespace Drupal\Core\Annotation;

use Drupal\Component\Annotation\Plugin;

/**
 * @defgroup plugin_context Annotation for context definition
 * @{
 * Describes how to use ContextDefinition annotation.
 *
 * When providing plugin annotations, contexts can be defined to support UI
 * interactions through providing limits, and mapping contexts to appropriate
 * plugins. Context definitions can be provided as such:
 * @code
 *   context_definitions = {
 *     "node" = @ContextDefinition("entity:node")
 *   }
 * @endcode
 *
 * To add a label to a context definition use the "label" key:
 * @code
 *   context_definitions = {
 *     "node" = @ContextDefinition("entity:node", label = @Translation("Node"))
 *   }
 * @endcode
 *
 * Contexts are required unless otherwise specified. To make an optional
 * context use the "required" key:
 * @code
 *   context_definitions = {
 *     "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node"))
 *   }
 * @endcode
 *
 * To define multiple contexts, simply provide different key names in the
 * context array:
 * @code
 *   context_definitions = {
 *     "artist" = @ContextDefinition("entity:node", label = @Translation("Artist")),
 *     "album" = @ContextDefinition("entity:node", label = @Translation("Album"))
 *   }
 * @endcode
 *
 * Specifying a default value for the context definition:
 * @code
 *   context_definitions = {
 *     "message" = @ContextDefinition("string",
 *       label = @Translation("Message"),
 *       default_value = @Translation("Checkout complete! Thank you for your purchase.")
 *     )
 *   }
 * @endcode
 *
 * @see annotation
 *
 * @}
 */

/**
 * Defines a context definition annotation object.
 *
 * Some plugins require various data contexts in order to function. This class
 * supports that need by allowing the contexts to be easily defined within an
 * annotation and return a ContextDefinitionInterface implementing class.
 *
 * @Annotation
 *
 * @ingroup plugin_context
 */
class ContextDefinition extends Plugin {
    
    /**
     * The ContextDefinitionInterface object.
     *
     * @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface
     */
    protected $definition;
    
    /**
     * Constructs a new context definition object.
     *
     * @param array $values
     *   An associative array with the following keys:
     *   - value: The required data type.
     *   - label: (optional) The UI label of this context definition.
     *   - required: (optional) Whether the context definition is required.
     *   - multiple: (optional) Whether the context definition is multivalue.
     *   - description: (optional) The UI description of this context definition.
     *   - default_value: (optional) The default value in case the underlying
     *     value is not set.
     *   - class: (optional) A custom ContextDefinitionInterface class.
     *
     * @throws \Exception
     *   Thrown when the class key is specified with a non
     *   ContextDefinitionInterface implementing class.
     */
    public function __construct(array $values) {
        $values += [
            'required' => TRUE,
            'multiple' => FALSE,
            'default_value' => NULL,
        ];
        // Annotation classes extract data from passed annotation classes directly
        // used in the classes they pass to.
        foreach ([
            'label',
            'description',
        ] as $key) {
            // @todo Remove this workaround in https://www.drupal.org/node/2362727.
            if (isset($values[$key]) && $values[$key] instanceof Translation) {
                $values[$key] = (string) $values[$key]->get();
            }
            else {
                $values[$key] = NULL;
            }
        }
        if (isset($values['class']) && !in_array('Drupal\\Core\\Plugin\\Context\\ContextDefinitionInterface', class_implements($values['class']))) {
            throw new \Exception('ContextDefinition class must implement \\Drupal\\Core\\Plugin\\Context\\ContextDefinitionInterface.');
        }
        $class = $this->getDefinitionClass($values);
        $this->definition = new $class($values['value'], $values['label'], $values['required'], $values['multiple'], $values['description'], $values['default_value']);
        if (isset($values['constraints'])) {
            foreach ($values['constraints'] as $constraint_name => $options) {
                $this->definition
                    ->addConstraint($constraint_name, $options);
            }
        }
    }
    
    /**
     * Determines the context definition class to use.
     *
     * If the annotation specifies a specific context definition class, we use
     * that. Otherwise, we use \Drupal\Core\Plugin\Context\EntityContextDefinition
     * if the data type starts with 'entity:', since it contains specialized logic
     * specific to entities. Otherwise, we fall back to the generic
     * \Drupal\Core\Plugin\Context\ContextDefinition class.
     *
     * @param array $values
     *   The annotation values.
     *
     * @return string
     *   The fully-qualified name of the context definition class.
     */
    protected function getDefinitionClass(array $values) {
        if (isset($values['class'])) {
            return $values['class'];
        }
        if (str_starts_with($values['value'], 'entity:')) {
            return 'Drupal\\Core\\Plugin\\Context\\EntityContextDefinition';
        }
        return 'Drupal\\Core\\Plugin\\Context\\ContextDefinition';
    }
    
    /**
     * Returns the value of an annotation.
     *
     * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface
     */
    public function get() {
        return $this->definition;
    }

}

Classes

Title Deprecated Summary
ContextDefinition Defines a context definition annotation object.

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