loader = $loader ?? new SchemaLoader(new SchemaParser(), new SchemaResolver(), true); $this->maxErrors = $max_errors; } /** * @param $data * @param bool|string|Uri|Schema|object $schema * @param array|null $globals * @param array|null $slots * @return ValidationResult */ public function validate($data, $schema, ?array $globals = null, ?array $slots = null): ValidationResult { if (is_string($schema)) { if ($uri = Uri::parse($schema, true)) { $schema = $uri; } else { $schema = json_decode($schema, false); } } $error = null; if (is_bool($schema)) { $error = $this->dataValidation($data, $schema, $globals, $slots); } elseif (is_object($schema)) { if ($schema instanceof Uri) { $error = $this->uriValidation($data, $schema, $globals, $slots); } elseif ($schema instanceof Schema) { $error = $this->schemaValidation($data, $schema, $globals, $slots); } else { $error = $this->dataValidation($data, $schema, $globals, $slots); } } else { throw new InvalidArgumentException("Invalid schema"); } return new ValidationResult($error); } /** * @param $data * @param Uri|string $uri * @param array|null $globals * @param array|null $slots * @return null|ValidationError */ public function uriValidation($data, $uri, ?array $globals = null, ?array $slots = null): ?ValidationError { if (is_string($uri)) { $uri = Uri::parse($uri, true); } if (!($uri instanceof Uri)) { throw new InvalidArgumentException("Invalid uri"); } if ($uri->fragment() === null) { $uri = Uri::merge($uri, null, true); } $schema = $this->loader->loadSchemaById($uri); if ($schema === null) { throw new RuntimeException("Schema not found: $uri"); } return $this->schemaValidation($data, $schema, $globals, $slots); } /** * @param $data * @param string|object|bool $schema * @param array|null $globals * @param array|null $slots * @param string|null $id * @param string|null $draft * @return ValidationError|null */ public function dataValidation( $data, $schema, ?array $globals = null, ?array $slots = null, ?string $id = null, ?string $draft = null ): ?ValidationError { if (is_string($schema)) { $schema = json_decode($schema, false); } if ($schema === true) { return null; } if ($schema === false) { $schema = $this->loader->loadBooleanSchema(false, $id, $draft); } else { if (!is_object($schema)) { throw new InvalidArgumentException("Invalid schema"); } $schema = $this->loader->loadObjectSchema($schema, $id, $draft); } return $this->schemaValidation($data, $schema, $globals, $slots); } /** * @param $data * @param Schema $schema * @param array|null $globals * @param array|null $slots * @return null|ValidationError */ public function schemaValidation( $data, Schema $schema, ?array $globals = null, ?array $slots = null ): ?ValidationError { return $schema->validate($this->createContext($data, $globals, $slots)); } /** * @param $data * @param array|null $globals * @param array|null $slots * @return ValidationContext */ public function createContext($data, ?array $globals = null, ?array $slots = null): ValidationContext { if ($slots) { $slots = $this->parseSlots($slots); } return new ValidationContext($data, $this->loader, null, null, $globals ?? [], $slots, $this->maxErrors); } /** * @return SchemaParser */ public function parser(): SchemaParser { return $this->loader->parser(); } /** * @param SchemaParser $parser * @return Validator */ public function setParser(SchemaParser $parser): self { $this->loader->setParser($parser); return $this; } /** * @return SchemaResolver|null */ public function resolver(): ?SchemaResolver { return $this->loader->resolver(); } /** * @param SchemaResolver|null $resolver * @return Validator */ public function setResolver(?SchemaResolver $resolver): self { $this->loader->setResolver($resolver); return $this; } /** * @return SchemaLoader */ public function loader(): SchemaLoader { return $this->loader; } /** * @param SchemaLoader $loader * @return Validator */ public function setLoader(SchemaLoader $loader): self { $this->loader = $loader; return $this; } /** * @return int */ public function getMaxErrors(): int { return $this->maxErrors; } /** * @param int $max_errors * @return Validator */ public function setMaxErrors(int $max_errors): self { $this->maxErrors = $max_errors; return $this; } /** * @param array $slots * @return array */ protected function parseSlots(array $slots): array { foreach ($slots as $name => &$value) { if (!is_string($name)) { unset($slots[$name]); continue; } if (is_string($value)) { $value = Uri::parse($value, true); } if ($value instanceof Uri) { $value = $this->loader->loadSchemaById($value); } elseif (is_bool($value)) { $value = $this->loader->loadBooleanSchema($value); } if (!is_object($value)) { unset($slots[$name]); } unset($value); } return $slots; } }