/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if (!is_string($instance)) { $context->addViolation('should be a string'); } elseif ($schema->format === 'date-time') { // PHP support for RFC3339 doesn't include fractional time // (milliseconds) so we must add another check if needed if (!$this->isDateTimeValid($instance, DATE_RFC3339) && !$this->isDateTimeValid($instance, 'Y-m-d\\TH:i:s.uP')) { $context->addViolation('should be a valid date-time (RFC3339)'); } } elseif ($schema->format === 'email') { if (!filter_var($instance, FILTER_VALIDATE_EMAIL)) { $context->addViolation('should be a valid email'); } } elseif ($schema->format === 'hostname') { if (!preg_match(self::HOSTNAME_REGEX, $instance)) { $context->addViolation('should be a valid hostname'); } } elseif ($schema->format === 'ipv4') { if (!filter_var($instance, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $context->addViolation('should be a valid IPv4 address'); } } elseif ($schema->format === 'ipv6') { if (!filter_var($instance, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $context->addViolation('should be a valid IPv6 address'); } } elseif ($schema->format === 'uri') { if (!preg_match(self::URI_REGEX, $instance)) { $context->addViolation('should be a valid URI (RFC3986)'); } } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if ($schema->exclusiveMaximum === false) { if ($instance > $schema->maximum) { $context->addViolation('should be lesser than or equal to %s', [$schema->maximum]); } } elseif ($instance >= $schema->maximum) { $context->addViolation('should be lesser than %s', [$schema->maximum]); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if (is_string($schema->type)) { if (!Types::isA($instance, $schema->type)) { $context->addViolation('instance must be of type %s', [$schema->type]); } } else { if (!Types::isOneOf($instance, $schema->type)) { $context->addViolation('instance does not match any of the expected types'); } } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $length = extension_loaded('mbstring') ? mb_strlen($instance, mb_detect_encoding($instance)) : strlen($instance); if ($length > $schema->maxLength) { $context->addViolation('should be lesser than or equal to %s characters', [$schema->maxLength]); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { // implementation of the algorithms described in 5.4.4.4 and in 8.3 foreach ($instance as $property => $value) { $schemas = []; if (isset($schema->properties->{$property})) { $schemas[] = $schema->properties->{$property}; } foreach ($schema->patternProperties as $regex => $propertySchema) { if (Utils::matchesRegex($property, $regex)) { $schemas[] = $propertySchema; } } if (empty($schemas)) { if (is_object($schema->additionalProperties)) { $schemas[] = $schema->additionalProperties; } elseif ($schema->additionalProperties === false) { $context->addViolation('additional property "%s" is not allowed', [$property]); } } $context->enterNode($property); foreach ($schemas as $childSchema) { $walker->applyConstraints($value, $childSchema, $context); } $context->leaveNode(); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $accumulatingContext = $context->duplicate(false); $hasMatch = false; $hasDoubleMatch = false; foreach ($schema->oneOf as $subSchema) { $subContext = $context->duplicate(false); $walker->applyConstraints($instance, $subSchema, $subContext); if ($subContext->countViolations() === 0) { if (!$hasMatch) { $hasMatch = true; } else { $hasDoubleMatch = true; break; } } else { $accumulatingContext->mergeViolations($subContext); } } if (!$hasMatch) { $context->mergeViolations($accumulatingContext); } if (!$hasMatch || $hasDoubleMatch) { $context->addViolation('instance must match exactly one of the schemas listed in oneOf'); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { foreach ($schema->required as $property) { if (!property_exists($instance, $property)) { $context->addViolation('property "%s" is missing', [$property]); } } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $altContext = $context->duplicate(); $walker->applyConstraints($instance, $schema->not, $altContext); if ($altContext->countViolations() === $context->countViolations()) { $context->addViolation('should not match schema in "not"'); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $hasMatch = false; foreach ($schema->enum as $value) { if (Utils::areEqual($instance, $value)) { $hasMatch = true; break; } } if (!$hasMatch) { $context->addViolation('should match one element in enum'); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if ($schema->uniqueItems === true) { foreach ($instance as $i => $aItem) { foreach ($instance as $j => $bItem) { if ($i !== $j && Utils::areEqual($aItem, $bItem)) { $context->addViolation('elements must be unique'); break 2; } } } } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $divider = $schema->multipleOf; $modulus = fmod($instance, $divider); $precision = abs(1.0E-10); $diff = (double) ($modulus - $divider); if (-$precision < $diff && $diff < $precision) { $fMod = 0.0; } else { $decimals1 = mb_strpos($instance, '.') ? mb_strlen($instance) - mb_strpos($instance, '.') - 1 : 0; $decimals2 = mb_strpos($divider, '.') ? mb_strlen($divider) - mb_strpos($divider, '.') - 1 : 0; $fMod = (double) round($modulus, max($decimals1, $decimals2)); } if ($fMod != 0) { $context->addViolation('should be a multiple of %s', [$divider]); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { $accumulatingContext = $context->duplicate(); $hasMatch = false; foreach ($schema->anyOf as $subSchema) { $originalCount = $accumulatingContext->countViolations(); $walker->applyConstraints($instance, $subSchema, $accumulatingContext); if ($accumulatingContext->countViolations() === $originalCount) { $hasMatch = true; break; } } if (!$hasMatch) { $context->mergeViolations($accumulatingContext); $context->addViolation('instance must match at least one of the schemas listed in anyOf'); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if (!Utils::matchesRegex($instance, $schema->pattern)) { $context->addViolation('should match regex "%s"', [$schema->pattern]); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if (count(get_object_vars($instance)) < $schema->minProperties) { $context->addViolation('number of properties should be greater than or equal to %s', [$schema->minProperties]); } }
/** * {@inheritdoc} */ public function apply($instance, stdClass $schema, Context $context, Walker $walker) { if (count($instance) < $schema->minItems) { $context->addViolation('number of items should be greater than or equal to %s', [$schema->minItems]); } }