class ContextDefinition

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

Defines a class for context definitions.

Hierarchy

Expanded class hierarchy of ContextDefinition

37 files declare their use of ContextDefinition
ConditionTestNoExistingType.php in core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestNoExistingType.php
ContextAwarePluginTraitTest.php in core/tests/Drupal/KernelTests/Core/Plugin/Context/ContextAwarePluginTraitTest.php
ContextDefinitionIsSatisfiedTest.php in core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionIsSatisfiedTest.php
ContextDefinitionTest.php in core/tests/Drupal/KernelTests/Core/Plugin/Annotation/ContextDefinitionTest.php
ContextDefinitionTest.php in core/tests/Drupal/KernelTests/Core/Plugin/ContextDefinitionTest.php

... See full list

File

core/lib/Drupal/Core/Plugin/Context/ContextDefinition.php, line 12

Namespace

Drupal\Core\Plugin\Context
View source
class ContextDefinition implements ContextDefinitionInterface {
    use DependencySerializationTrait;
    use TypedDataTrait;
    
    /**
     * The data type of the data.
     *
     * @var string
     *   The data type.
     */
    protected $dataType;
    
    /**
     * The human-readable label.
     *
     * @var string
     *   The label.
     */
    protected $label;
    
    /**
     * The human-readable description.
     *
     * @var string|null
     *   The description, or NULL if no description is available.
     */
    protected $description;
    
    /**
     * Whether the data is multi-valued, i.e. a list of data items.
     *
     * @var bool
     */
    protected $isMultiple = FALSE;
    
    /**
     * Determines whether a data value is required.
     *
     * @var bool
     *   Whether a data value is required.
     */
    protected $isRequired = TRUE;
    
    /**
     * The default value.
     *
     * @var mixed
     */
    protected $defaultValue;
    
    /**
     * An array of constraints.
     *
     * @var array[]
     */
    protected $constraints = [];
    
    /**
     * Creates a new context definition.
     *
     * @param string $data_type
     *   The data type for which to create the context definition. Defaults to
     *   'any'.
     *
     * @return static
     *   The created context definition object.
     */
    public static function create($data_type = 'any') {
        if (str_starts_with($data_type, 'entity:')) {
            return new EntityContextDefinition($data_type);
        }
        return new static($data_type);
    }
    
    /**
     * Constructs a new context definition object.
     *
     * @param string $data_type
     *   The required data type.
     * @param string|null|\Stringable $label
     *   The label of this context definition for the UI.
     * @param bool $required
     *   Whether the context definition is required.
     * @param bool $multiple
     *   Whether the context definition is multivalue.
     * @param string|null $description
     *   The description of this context definition for the UI.
     * @param mixed $default_value
     *   The default value of this definition.
     * @param array $constraints
     *   An array of constraints keyed by the constraint name and a value of an
     *   array constraint options or a NULL.
     */
    public function __construct($data_type = 'any', $label = NULL, $required = TRUE, $multiple = FALSE, $description = NULL, $default_value = NULL, array $constraints = []) {
        $this->dataType = $data_type;
        $this->label = $label;
        $this->isRequired = $required;
        $this->isMultiple = $multiple;
        $this->description = $description;
        $this->defaultValue = $default_value;
        foreach ($constraints as $constraint_name => $options) {
            $this->addConstraint($constraint_name, $options);
        }
        assert(!str_starts_with($data_type, 'entity:') || $this instanceof EntityContextDefinition);
    }
    
    /**
     * {@inheritdoc}
     */
    public function getDataType() {
        return $this->dataType;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setDataType($data_type) {
        $this->dataType = $data_type;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getLabel() {
        return $this->label;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setLabel($label) {
        $this->label = $label;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getDescription() {
        return $this->description;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setDescription($description) {
        $this->description = $description;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function isMultiple() {
        return $this->isMultiple;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setMultiple($multiple = TRUE) {
        $this->isMultiple = $multiple;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function isRequired() {
        return $this->isRequired;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setRequired($required = TRUE) {
        $this->isRequired = $required;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getDefaultValue() {
        return $this->defaultValue;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setDefaultValue($default_value) {
        $this->defaultValue = $default_value;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getConstraints() {
        // @todo Apply defaults.
        return $this->constraints;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getConstraint($constraint_name) {
        $constraints = $this->getConstraints();
        return $constraints[$constraint_name] ?? NULL;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setConstraints(array $constraints) {
        $this->constraints = $constraints;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function addConstraint($constraint_name, $options = NULL) {
        $this->constraints[$constraint_name] = $options;
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getDataDefinition() {
        if ($this->isMultiple()) {
            $definition = $this->getTypedDataManager()
                ->createListDataDefinition($this->getDataType());
        }
        else {
            $definition = $this->getTypedDataManager()
                ->createDataDefinition($this->getDataType());
        }
        if (!$definition) {
            throw new \Exception("The data type '{$this->getDataType()}' is invalid");
        }
        $definition->setLabel($this->getLabel())
            ->setDescription($this->getDescription())
            ->setRequired($this->isRequired());
        $constraints = $definition->getConstraints() + $this->getConstraints();
        $definition->setConstraints($constraints);
        return $definition;
    }
    
    /**
     * Checks if this definition's data type matches that of the given context.
     *
     * @param \Drupal\Core\Plugin\Context\ContextInterface $context
     *   The context to test against.
     *
     * @return bool
     *   TRUE if the data types match, otherwise FALSE.
     */
    protected function dataTypeMatches(ContextInterface $context) {
        $this_type = $this->getDataType();
        $that_type = $context->getContextDefinition()
            ->getDataType();
        return $this_type === 'any' || $this_type === $that_type || str_starts_with($that_type, "{$this_type}:");
    }
    
    /**
     * {@inheritdoc}
     */
    public function isSatisfiedBy(ContextInterface $context) {
        $definition = $context->getContextDefinition();
        if (!$this->dataTypeMatches($context)) {
            return FALSE;
        }
        // Get the value for this context, either directly if possible or by
        // introspecting the definition.
        if ($context->hasContextValue()) {
            $values = [
                $context->getContextData(),
            ];
        }
        elseif ($definition instanceof self) {
            $values = $definition->getSampleValues();
        }
        else {
            $values = [];
        }
        $validator = $this->getTypedDataManager()
            ->getValidator();
        foreach ($values as $value) {
            $constraints = array_values($this->getConstraintObjects());
            if ($definition->isMultiple()) {
                $violations = new ConstraintViolationList();
                foreach ($value as $item) {
                    $violations->addAll($validator->validate($item, $constraints));
                }
            }
            else {
                $violations = $validator->validate($value, $constraints);
            }
            foreach ($violations as $delta => $violation) {
                // Remove any violation that does not correspond to the constraints.
                if (!in_array($violation->getConstraint(), $constraints)) {
                    $violations->remove($delta);
                }
            }
            // If a value has no violations then the requirement is satisfied.
            if (!$violations->count()) {
                return TRUE;
            }
        }
        return FALSE;
    }
    
    /**
     * Returns typed data objects representing this context definition.
     *
     * This should return as many objects as needed to reflect the variations of
     * the constraints it supports.
     *
     * @yield \Drupal\Core\TypedData\TypedDataInterface
     *   The set of typed data object.
     */
    protected function getSampleValues() {
        (yield $this->getTypedDataManager()
            ->create($this->getDataDefinition()));
    }
    
    /**
     * Extracts an array of constraints for a context definition object.
     *
     * @return \Symfony\Component\Validator\Constraint[]
     *   A list of applied constraints for the context definition.
     */
    protected function getConstraintObjects() {
        $constraint_definitions = $this->getConstraints();
        $validation_constraint_manager = $this->getTypedDataManager()
            ->getValidationConstraintManager();
        $constraints = [];
        foreach ($constraint_definitions as $constraint_name => $constraint_definition) {
            $constraints[$constraint_name] = $validation_constraint_manager->create($constraint_name, $constraint_definition);
        }
        return $constraints;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
ContextDefinition::$constraints protected property An array of constraints.
ContextDefinition::$dataType protected property The data type of the data.
ContextDefinition::$defaultValue protected property The default value.
ContextDefinition::$description protected property The human-readable description.
ContextDefinition::$isMultiple protected property Whether the data is multi-valued, i.e. a list of data items.
ContextDefinition::$isRequired protected property Determines whether a data value is required.
ContextDefinition::$label protected property The human-readable label.
ContextDefinition::addConstraint public function Overrides ContextDefinitionInterface::addConstraint
ContextDefinition::create public static function Creates a new context definition.
ContextDefinition::dataTypeMatches protected function Checks if this definition's data type matches that of the given context.
ContextDefinition::getConstraint public function Overrides ContextDefinitionInterface::getConstraint
ContextDefinition::getConstraintObjects protected function Extracts an array of constraints for a context definition object. 1
ContextDefinition::getConstraints public function Overrides ContextDefinitionInterface::getConstraints
ContextDefinition::getDataDefinition public function Overrides ContextDefinitionInterface::getDataDefinition
ContextDefinition::getDataType public function Overrides ContextDefinitionInterface::getDataType
ContextDefinition::getDefaultValue public function Overrides ContextDefinitionInterface::getDefaultValue
ContextDefinition::getDescription public function Overrides ContextDefinitionInterface::getDescription
ContextDefinition::getLabel public function Overrides ContextDefinitionInterface::getLabel
ContextDefinition::getSampleValues protected function Returns typed data objects representing this context definition. 1
ContextDefinition::isMultiple public function Overrides ContextDefinitionInterface::isMultiple
ContextDefinition::isRequired public function Overrides ContextDefinitionInterface::isRequired
ContextDefinition::isSatisfiedBy public function Overrides ContextDefinitionInterface::isSatisfiedBy
ContextDefinition::setConstraints public function Overrides ContextDefinitionInterface::setConstraints
ContextDefinition::setDataType public function Overrides ContextDefinitionInterface::setDataType
ContextDefinition::setDefaultValue public function Overrides ContextDefinitionInterface::setDefaultValue
ContextDefinition::setDescription public function Overrides ContextDefinitionInterface::setDescription
ContextDefinition::setLabel public function Overrides ContextDefinitionInterface::setLabel
ContextDefinition::setMultiple public function Overrides ContextDefinitionInterface::setMultiple
ContextDefinition::setRequired public function Overrides ContextDefinitionInterface::setRequired
ContextDefinition::__construct public function Constructs a new context definition object. 1
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
TypedDataTrait::$typedDataManager protected property The typed data manager used for creating the data types.
TypedDataTrait::getTypedDataManager public function Gets the typed data manager. 2
TypedDataTrait::setTypedDataManager public function Sets the typed data manager. 2

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