1<?php
2
3/*
4 * This file is part of the JsonSchema package.
5 *
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
8 */
9
10namespace JsonSchema\Constraints;
11
12use JsonSchema\Entity\JsonPointer;
13
14/**
15 * The Base Constraints, all Validators should extend this class
16 *
17 * @author Robert Schönthal <seroscho@googlemail.com>
18 * @author Bruno Prieto Reis <bruno.p.reis@gmail.com>
19 */
20abstract class Constraint extends BaseConstraint implements ConstraintInterface
21{
22    protected $inlineSchemaProperty = '$schema';
23
24    const CHECK_MODE_NONE =             0x00000000;
25    const CHECK_MODE_NORMAL =           0x00000001;
26    const CHECK_MODE_TYPE_CAST =        0x00000002;
27    const CHECK_MODE_COERCE_TYPES =     0x00000004;
28    const CHECK_MODE_APPLY_DEFAULTS =   0x00000008;
29    const CHECK_MODE_EXCEPTIONS =       0x00000010;
30    const CHECK_MODE_DISABLE_FORMAT =   0x00000020;
31    const CHECK_MODE_ONLY_REQUIRED_DEFAULTS   = 0x00000080;
32    const CHECK_MODE_VALIDATE_SCHEMA =  0x00000100;
33
34    /**
35     * Bubble down the path
36     *
37     * @param JsonPointer|null $path Current path
38     * @param mixed            $i    What to append to the path
39     *
40     * @return JsonPointer;
41     */
42    protected function incrementPath(JsonPointer $path = null, $i)
43    {
44        $path = $path ?: new JsonPointer('');
45        $path = $path->withPropertyPaths(
46            array_merge(
47                $path->getPropertyPaths(),
48                array_filter(array($i), 'strlen')
49            )
50        );
51
52        return $path;
53    }
54
55    /**
56     * Validates an array
57     *
58     * @param mixed            $value
59     * @param mixed            $schema
60     * @param JsonPointer|null $path
61     * @param mixed            $i
62     */
63    protected function checkArray(&$value, $schema = null, JsonPointer $path = null, $i = null)
64    {
65        $validator = $this->factory->createInstanceFor('collection');
66        $validator->check($value, $schema, $path, $i);
67
68        $this->addErrors($validator->getErrors());
69    }
70
71    /**
72     * Validates an object
73     *
74     * @param mixed            $value
75     * @param mixed            $schema
76     * @param JsonPointer|null $path
77     * @param mixed            $properties
78     * @param mixed            $additionalProperties
79     * @param mixed            $patternProperties
80     */
81    protected function checkObject(&$value, $schema = null, JsonPointer $path = null, $properties = null,
82        $additionalProperties = null, $patternProperties = null, $appliedDefaults = array())
83    {
84        $validator = $this->factory->createInstanceFor('object');
85        $validator->check($value, $schema, $path, $properties, $additionalProperties, $patternProperties, $appliedDefaults);
86
87        $this->addErrors($validator->getErrors());
88    }
89
90    /**
91     * Validates the type of a property
92     *
93     * @param mixed            $value
94     * @param mixed            $schema
95     * @param JsonPointer|null $path
96     * @param mixed            $i
97     */
98    protected function checkType(&$value, $schema = null, JsonPointer $path = null, $i = null)
99    {
100        $validator = $this->factory->createInstanceFor('type');
101        $validator->check($value, $schema, $path, $i);
102
103        $this->addErrors($validator->getErrors());
104    }
105
106    /**
107     * Checks a undefined element
108     *
109     * @param mixed            $value
110     * @param mixed            $schema
111     * @param JsonPointer|null $path
112     * @param mixed            $i
113     */
114    protected function checkUndefined(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false)
115    {
116        $validator = $this->factory->createInstanceFor('undefined');
117
118        $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i, $fromDefault);
119
120        $this->addErrors($validator->getErrors());
121    }
122
123    /**
124     * Checks a string element
125     *
126     * @param mixed            $value
127     * @param mixed            $schema
128     * @param JsonPointer|null $path
129     * @param mixed            $i
130     */
131    protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null)
132    {
133        $validator = $this->factory->createInstanceFor('string');
134        $validator->check($value, $schema, $path, $i);
135
136        $this->addErrors($validator->getErrors());
137    }
138
139    /**
140     * Checks a number element
141     *
142     * @param mixed       $value
143     * @param mixed       $schema
144     * @param JsonPointer $path
145     * @param mixed       $i
146     */
147    protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null)
148    {
149        $validator = $this->factory->createInstanceFor('number');
150        $validator->check($value, $schema, $path, $i);
151
152        $this->addErrors($validator->getErrors());
153    }
154
155    /**
156     * Checks a enum element
157     *
158     * @param mixed            $value
159     * @param mixed            $schema
160     * @param JsonPointer|null $path
161     * @param mixed            $i
162     */
163    protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null)
164    {
165        $validator = $this->factory->createInstanceFor('enum');
166        $validator->check($value, $schema, $path, $i);
167
168        $this->addErrors($validator->getErrors());
169    }
170
171    /**
172     * Checks format of an element
173     *
174     * @param mixed            $value
175     * @param mixed            $schema
176     * @param JsonPointer|null $path
177     * @param mixed            $i
178     */
179    protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null)
180    {
181        $validator = $this->factory->createInstanceFor('format');
182        $validator->check($value, $schema, $path, $i);
183
184        $this->addErrors($validator->getErrors());
185    }
186
187    /**
188     * Get the type check based on the set check mode.
189     *
190     * @return TypeCheck\TypeCheckInterface
191     */
192    protected function getTypeCheck()
193    {
194        return $this->factory->getTypeCheck();
195    }
196
197    /**
198     * @param JsonPointer $pointer
199     *
200     * @return string property path
201     */
202    protected function convertJsonPointerIntoPropertyPath(JsonPointer $pointer)
203    {
204        $result = array_map(
205            function ($path) {
206                return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path);
207            },
208            $pointer->getPropertyPaths()
209        );
210
211        return trim(implode('', $result), '.');
212    }
213}
214