Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Composite.php

class Composite

Same name in this branch
  1. 11.1.x vendor/open-telemetry/sdk/Resource/Detectors/Composite.php \OpenTelemetry\SDK\Resource\Detectors\Composite

A constraint that is composed of other constraints.

You should never use the nested constraint instances anywhere else, because their groups are adapted when passed to the constructor of this class.

If you want to create your own composite constraint, extend this class and let {@link getCompositeOption()} return the name of the property which contains the nested constraints.

@author Bernhard Schussek <bschussek@gmail.com>

Hierarchy

  • class \Symfony\Component\Validator\Constraint
    • class \Symfony\Component\Validator\Constraints\Composite extends \Symfony\Component\Validator\Constraint

Expanded class hierarchy of Composite

3 files declare their use of Composite
ClassMetadata.php in vendor/symfony/validator/Mapping/ClassMetadata.php
MemberMetadata.php in vendor/symfony/validator/Mapping/MemberMetadata.php
RecursiveContextualValidator.php in vendor/symfony/validator/Validator/RecursiveContextualValidator.php

File

vendor/symfony/validator/Constraints/Composite.php, line 29

Namespace

Symfony\Component\Validator\Constraints
View source
abstract class Composite extends Constraint {
    
    /**
     * The groups of the composite and its nested constraints are made
     * consistent using the following strategy:
     *
     *   - If groups are passed explicitly to the composite constraint, but
     *     not to the nested constraints, the options of the composite
     *     constraint are copied to the nested constraints;
     *
     *   - If groups are passed explicitly to the nested constraints, but not
     *     to the composite constraint, the groups of all nested constraints
     *     are merged and used as groups for the composite constraint;
     *
     *   - If groups are passed explicitly to both the composite and its nested
     *     constraints, the groups of the nested constraints must be a subset
     *     of the groups of the composite constraint. If not, a
     *     {@link ConstraintDefinitionException} is thrown.
     *
     * All this is done in the constructor, because constraints can then be
     * cached. When constraints are loaded from the cache, no more group
     * checks need to be done.
     */
    public function __construct(mixed $options = null, ?array $groups = null, mixed $payload = null) {
        parent::__construct($options, $groups, $payload);
        $this->initializeNestedConstraints();
        
        /* @var Constraint[] $nestedConstraints */
        $compositeOption = $this->getCompositeOption();
        $nestedConstraints = $this->{$compositeOption};
        if (!\is_array($nestedConstraints)) {
            $nestedConstraints = [
                $nestedConstraints,
            ];
        }
        foreach ($nestedConstraints as $constraint) {
            if (!$constraint instanceof Constraint) {
                if (\is_object($constraint)) {
                    $constraint = $constraint::class;
                }
                throw new ConstraintDefinitionException(\sprintf('The value "%s" is not an instance of Constraint in constraint "%s".', $constraint, static::class));
            }
            if ($constraint instanceof Valid) {
                throw new ConstraintDefinitionException(\sprintf('The constraint Valid cannot be nested inside constraint "%s". You can only declare the Valid constraint directly on a field or method.', static::class));
            }
        }
        if (!isset(((array) $this)['groups'])) {
            $mergedGroups = [];
            foreach ($nestedConstraints as $constraint) {
                foreach ($constraint->groups as $group) {
                    $mergedGroups[$group] = true;
                }
            }
            // prevent empty composite constraint to have empty groups
            $this->groups = array_keys($mergedGroups) ?: [
                self::DEFAULT_GROUP,
            ];
            $this->{$compositeOption} = $nestedConstraints;
            return;
        }
        foreach ($nestedConstraints as $constraint) {
            if (isset(((array) $constraint)['groups'])) {
                $excessGroups = array_diff($constraint->groups, $this->groups);
                if (\count($excessGroups) > 0) {
                    throw new ConstraintDefinitionException(\sprintf('The group(s) "%s" passed to the constraint "%s" should also be passed to its containing constraint "%s".', implode('", "', $excessGroups), get_debug_type($constraint), static::class));
                }
            }
            else {
                $constraint->groups = $this->groups;
            }
        }
        $this->{$compositeOption} = $nestedConstraints;
    }
    
    /**
     * Implicit group names are forwarded to nested constraints.
     */
    public function addImplicitGroupName(string $group) : void {
        parent::addImplicitGroupName($group);
        
        /** @var Constraint[] $nestedConstraints */
        $nestedConstraints = $this->{$this->getCompositeOption()};
        foreach ($nestedConstraints as $constraint) {
            $constraint->addImplicitGroupName($group);
        }
    }
    
    /**
     * Returns the name of the property that contains the nested constraints.
     */
    protected abstract function getCompositeOption() : string;
    
    /**
     * @internal Used by metadata
     *
     * @return Constraint[]
     */
    public function getNestedConstraints() : array {
        
        /* @var Constraint[] $nestedConstraints */
        return $this->{$this->getCompositeOption()};
    }
    
    /**
     * Initializes the nested constraints.
     *
     * This method can be overwritten in subclasses to clean up the nested
     * constraints passed to the constructor.
     *
     * @see Collection::initializeNestedConstraints()
     */
    protected function initializeNestedConstraints() : void {
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
Composite::addImplicitGroupName public function Implicit group names are forwarded to nested constraints. Overrides Constraint::addImplicitGroupName
Composite::getCompositeOption abstract protected function Returns the name of the property that contains the nested constraints. 7
Composite::getNestedConstraints public function @internal Used by metadata
Composite::initializeNestedConstraints protected function Initializes the nested constraints. 1
Composite::__construct public function The groups of the composite and its nested constraints are made
consistent using the following strategy:
Overrides Constraint::__construct 6
Constraint::$groups public property The groups that the constraint belongs to.
Constraint::$payload public property Domain-specific data attached to a constraint.
Constraint::CLASS_CONSTRAINT public constant Marks a constraint that can be put onto classes.
Constraint::DEFAULT_GROUP public constant The name of the group given to all constraints with no explicit group.
Constraint::ERROR_NAMES protected constant Maps error codes to the names of their constants. 59
Constraint::getDefaultOption public function Returns the name of the default option. 28
Constraint::getErrorName public static function Returns the name of the given error code.
Constraint::getRequiredOptions public function Returns the name of the required options. 22
Constraint::getTargets public function Returns whether the constraint can be put onto classes, properties or
both.
8
Constraint::normalizeOptions protected function
Constraint::PROPERTY_CONSTRAINT public constant Marks a constraint that can be put onto properties.
Constraint::validatedBy public function Returns the name of the class that validates this constraint. 9
Constraint::__get public function Returns the value of a lazily initialized option. 2
Constraint::__isset public function 1
Constraint::__set public function Sets the value of a lazily initialized option. 1
Constraint::__sleep public function Optimizes the serialized value to minimize storage space.
RSS feed
Powered by Drupal