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

Breadcrumb

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

class ObjectConstraint

The ObjectConstraint Constraints, validates an object against a given schema

@author Robert Schönthal <seroscho@googlemail.com> @author Bruno Prieto Reis <bruno.p.reis@gmail.com>

Hierarchy

  • class \JsonSchema\Constraints\BaseConstraint
    • class \JsonSchema\Constraints\Constraint extends \JsonSchema\Constraints\BaseConstraint implements \JsonSchema\Constraints\ConstraintInterface
      • class \JsonSchema\Constraints\ObjectConstraint extends \JsonSchema\Constraints\Constraint

Expanded class hierarchy of ObjectConstraint

File

vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php, line 20

Namespace

JsonSchema\Constraints
View source
class ObjectConstraint extends Constraint {
    
    /**
     * @var array List of properties to which a default value has been applied
     */
    protected $appliedDefaults = array();
    
    /**
     * {@inheritdoc}
     */
    public function check(&$element, $schema = null, ?JsonPointer $path = null, $properties = null, $additionalProp = null, $patternProperties = null, $appliedDefaults = array()) {
        if ($element instanceof UndefinedConstraint) {
            return;
        }
        $this->appliedDefaults = $appliedDefaults;
        $matches = array();
        if ($patternProperties) {
            // validate the element pattern properties
            $matches = $this->validatePatternProperties($element, $path, $patternProperties);
        }
        if ($properties) {
            // validate the element properties
            $this->validateProperties($element, $properties, $path);
        }
        // validate additional element properties & constraints
        $this->validateElement($element, $matches, $schema, $path, $properties, $additionalProp);
    }
    public function validatePatternProperties($element, ?JsonPointer $path, $patternProperties) {
        $try = array(
            '/',
            '#',
            '+',
            '~',
            '%',
        );
        $matches = array();
        foreach ($patternProperties as $pregex => $schema) {
            $delimiter = '/';
            // Choose delimiter. Necessary for patterns like ^/ , otherwise you get error
            foreach ($try as $delimiter) {
                if (strpos($pregex, $delimiter) === false) {
                    // safe to use
                    break;
                }
            }
            // Validate the pattern before using it to test for matches
            if (@preg_match($delimiter . $pregex . $delimiter . 'u', '') === false) {
                $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array(
                    'pregex' => $pregex,
                ));
                continue;
            }
            foreach ($element as $i => $value) {
                if (preg_match($delimiter . $pregex . $delimiter . 'u', $i)) {
                    $matches[] = $i;
                    $this->checkUndefined($value, $schema ?: new \stdClass(), $path, $i, in_array($i, $this->appliedDefaults));
                }
            }
        }
        return $matches;
    }
    
    /**
     * Validates the element properties
     *
     * @param \StdClass        $element        Element to validate
     * @param array            $matches        Matches from patternProperties (if any)
     * @param \StdClass        $schema         ObjectConstraint definition
     * @param JsonPointer|null $path           Current test path
     * @param \StdClass        $properties     Properties
     * @param mixed            $additionalProp Additional properties
     */
    public function validateElement($element, $matches, $schema = null, ?JsonPointer $path = null, $properties = null, $additionalProp = null) {
        $this->validateMinMaxConstraint($element, $schema, $path);
        foreach ($element as $i => $value) {
            $definition = $this->getProperty($properties, $i);
            // no additional properties allowed
            if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) {
                $this->addError($path, 'The property ' . $i . ' is not defined and the definition does not allow additional properties', 'additionalProp');
            }
            // additional properties defined
            if (!in_array($i, $matches) && $additionalProp && !$definition) {
                if ($additionalProp === true) {
                    $this->checkUndefined($value, null, $path, $i, in_array($i, $this->appliedDefaults));
                }
                else {
                    $this->checkUndefined($value, $additionalProp, $path, $i, in_array($i, $this->appliedDefaults));
                }
            }
            // property requires presence of another
            $require = $this->getProperty($definition, 'requires');
            if ($require && !$this->getProperty($element, $require)) {
                $this->addError($path, 'The presence of the property ' . $i . ' requires that ' . $require . ' also be present', 'requires');
            }
            $property = $this->getProperty($element, $i, $this->factory
                ->createInstanceFor('undefined'));
            if (is_object($property)) {
                $this->validateMinMaxConstraint(!$property instanceof UndefinedConstraint ? $property : $element, $definition, $path);
            }
        }
    }
    
    /**
     * Validates the definition properties
     *
     * @param \stdClass        $element    Element to validate
     * @param \stdClass        $properties Property definitions
     * @param JsonPointer|null $path       Path?
     */
    public function validateProperties(&$element, $properties = null, ?JsonPointer $path = null) {
        $undefinedConstraint = $this->factory
            ->createInstanceFor('undefined');
        foreach ($properties as $i => $value) {
            $property =& $this->getProperty($element, $i, $undefinedConstraint);
            $definition = $this->getProperty($properties, $i);
            if (is_object($definition)) {
                // Undefined constraint will check for is_object() and quit if is not - so why pass it?
                $this->checkUndefined($property, $definition, $path, $i, in_array($i, $this->appliedDefaults));
            }
        }
    }
    
    /**
     * retrieves a property from an object or array
     *
     * @param mixed  $element  Element to validate
     * @param string $property Property to retrieve
     * @param mixed  $fallback Default value if property is not found
     *
     * @return mixed
     */
    protected function &getProperty(&$element, $property, $fallback = null) {
        if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element))) {
            return $element[$property];
        }
        elseif (is_object($element) && property_exists($element, $property)) {
            return $element->{$property};
        }
        return $fallback;
    }
    
    /**
     * validating minimum and maximum property constraints (if present) against an element
     *
     * @param \stdClass        $element          Element to validate
     * @param \stdClass        $objectDefinition ObjectConstraint definition
     * @param JsonPointer|null $path             Path to test?
     */
    protected function validateMinMaxConstraint($element, $objectDefinition, ?JsonPointer $path = null) {
        // Verify minimum number of properties
        if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) {
            if ($this->getTypeCheck()
                ->propertyCount($element) < $objectDefinition->minProperties) {
                $this->addError($path, 'Must contain a minimum of ' . $objectDefinition->minProperties . ' properties', 'minProperties', array(
                    'minProperties' => $objectDefinition->minProperties,
                ));
            }
        }
        // Verify maximum number of properties
        if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) {
            if ($this->getTypeCheck()
                ->propertyCount($element) > $objectDefinition->maxProperties) {
                $this->addError($path, 'Must contain no more than ' . $objectDefinition->maxProperties . ' properties', 'maxProperties', array(
                    'maxProperties' => $objectDefinition->maxProperties,
                ));
            }
        }
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
BaseConstraint::$errorMask protected property
BaseConstraint::$errors protected property
BaseConstraint::$factory protected property
BaseConstraint::addError public function
BaseConstraint::addErrors public function
BaseConstraint::arrayToObjectRecursive public static function Recursively cast an associative array to an object
BaseConstraint::getErrorMask public function Get the error mask
BaseConstraint::getErrors public function
BaseConstraint::isValid public function
BaseConstraint::numErrors public function
BaseConstraint::reset public function Clears any reported errors. Should be used between
multiple validation checks.
BaseConstraint::__construct public function
Constraint::$inlineSchemaProperty protected property
Constraint::checkArray protected function Validates an array
Constraint::checkEnum protected function Checks a enum element
Constraint::checkFormat protected function Checks format of an element
Constraint::checkNumber protected function Checks a number element
Constraint::checkObject protected function Validates an object
Constraint::checkString protected function Checks a string element
Constraint::checkType protected function Validates the type of a property
Constraint::checkUndefined protected function Checks a undefined element
Constraint::CHECK_MODE_APPLY_DEFAULTS constant
Constraint::CHECK_MODE_COERCE_TYPES constant
Constraint::CHECK_MODE_DISABLE_FORMAT constant
Constraint::CHECK_MODE_EXCEPTIONS constant
Constraint::CHECK_MODE_NONE constant
Constraint::CHECK_MODE_NORMAL constant
Constraint::CHECK_MODE_ONLY_REQUIRED_DEFAULTS constant
Constraint::CHECK_MODE_TYPE_CAST constant
Constraint::CHECK_MODE_VALIDATE_SCHEMA constant
Constraint::convertJsonPointerIntoPropertyPath protected function
Constraint::getTypeCheck protected function Get the type check based on the set check mode.
Constraint::incrementPath protected function Bubble down the path
ObjectConstraint::$appliedDefaults protected property
ObjectConstraint::check public function invokes the validation of an element Overrides ConstraintInterface::check
ObjectConstraint::getProperty protected function retrieves a property from an object or array
ObjectConstraint::validateElement public function Validates the element properties
ObjectConstraint::validateMinMaxConstraint protected function validating minimum and maximum property constraints (if present) against an element
ObjectConstraint::validatePatternProperties public function
ObjectConstraint::validateProperties public function Validates the definition properties

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal