Overview

Namespaces

  • Webmozart
    • Json

Classes

  • Webmozart\Json\JsonDecoder
  • Webmozart\Json\JsonEncoder
  • Webmozart\Json\JsonError
  • Webmozart\Json\JsonValidator

Exceptions

  • Webmozart\Json\DecodingFailedException
  • Webmozart\Json\EncodingFailedException
  • Webmozart\Json\FileNotFoundException
  • Webmozart\Json\InvalidSchemaException
  • Webmozart\Json\ValidationFailedException
  • Overview
  • Namespace
  • Class
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 
<?php

/*
 * This file is part of the Webmozart JSON package.
 *
 * (c) Bernhard Schussek <bschussek@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Webmozart\Json;

use JsonSchema\Exception\InvalidArgumentException;
use JsonSchema\Validator;

/**
 * Validates decoded JSON values against a JSON schema.
 *
 * This class is a wrapper for {@link Validator} that adds exceptions and
 * validation of schema files. A few edge cases that are not handled by
 * {@link Validator} are handled by this class.
 *
 * @since  1.0
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class JsonValidator
{
    /**
     * The schema used for validating schemas.
     *
     * @var object|null
     */
    private $metaSchema;

    /**
     * Validates JSON data against a schema.
     *
     * The schema may be passed as file path or as object returned from
     * `json_decode($schemaFile)`.
     *
     * @param mixed         $data   The decoded JSON data.
     * @param string|object $schema The schema file or object.
     *
     * @return string[] The errors found during validation. Returns an empty
     *                  array if no errors were found.
     *
     * @throws InvalidSchemaException If the schema is invalid.
     */
    public function validate($data, $schema)
    {
        if (is_string($schema)) {
            $schema = $this->loadSchema($schema);
        } else {
            $this->assertSchemaValid($schema);
        }

        $validator = new Validator();

        try {
            $validator->check($data, $schema);
        } catch (InvalidArgumentException $e) {
            throw new InvalidSchemaException(sprintf(
                'The schema is invalid: %s',
                $e->getMessage()
            ), 0, $e);
        }

        $errors = array();

        if (!$validator->isValid()) {
            $errors = (array) $validator->getErrors();

            foreach ($errors as $key => $error) {
                $prefix = $error['property'] ? $error['property'].': ' : '';
                $errors[$key] = $prefix.$error['message'];
            }
        }

        return $errors;
    }

    private function assertSchemaValid($schema)
    {
        if (null === $this->metaSchema) {
            // The meta schema is obviously not validated. If we
            // validate it against itself, we have an endless recursion
            $this->metaSchema = json_decode(file_get_contents(__DIR__.'/../res/meta-schema.json'));
        }

        if ($schema === $this->metaSchema) {
            return;
        }

        $errors = $this->validate($schema, $this->metaSchema);

        if (count($errors) > 0) {
            throw new InvalidSchemaException(sprintf(
                "The schema is invalid:\n%s",
                implode("\n", $errors)
            ));
        }

        // not caught by justinrainbow/json-schema
        if (!is_object($schema)) {
            throw new InvalidSchemaException(sprintf(
                'The schema must be an object. Got: %s',
                $schema,
                gettype($schema)
            ));
        }
    }

    private function loadSchema($file)
    {
        if (!file_exists($file)) {
            throw new InvalidSchemaException(sprintf(
                'The schema file %s does not exist.',
                $file
            ));
        }

        $schema = json_decode(file_get_contents($file));

        try {
            $this->assertSchemaValid($schema);
        } catch (InvalidSchemaException $e) {
            throw new InvalidSchemaException(sprintf(
                'An error occurred while loading the schema %s: %s',
                $file,
                $e->getMessage()
            ), 0, $e);
        }

        return $schema;
    }
}
Webmozart JSON API API documentation generated by ApiGen