1 | <?php |
||
2 | /** |
||
3 | * BEdita, API-first content management framework |
||
4 | * Copyright 2017 ChannelWeb Srl, Chialab Srl |
||
5 | * |
||
6 | * This file is part of BEdita: you can redistribute it and/or modify |
||
7 | * it under the terms of the GNU Lesser General Public License as published |
||
8 | * by the Free Software Foundation, either version 3 of the License, or |
||
9 | * (at your option) any later version. |
||
10 | * |
||
11 | * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details. |
||
12 | */ |
||
13 | |||
14 | namespace BEdita\Core\Model\Validation; |
||
15 | |||
16 | use Cake\Core\Configure; |
||
17 | use Cake\Core\Configure\Engine\PhpConfig; |
||
18 | use Cake\Utility\Hash; |
||
19 | use Cake\Validation\Validation as CakeValidation; |
||
20 | use DateTimeInterface; |
||
21 | use League\JsonGuard\Validator as JsonSchemaValidator; |
||
0 ignored issues
–
show
|
|||
22 | use League\JsonReference\Dereferencer as JsonSchemaDereferencer; |
||
0 ignored issues
–
show
The type
League\JsonReference\Dereferencer was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths
Loading history...
|
|||
23 | use League\JsonReference\Loader\ArrayLoader; |
||
0 ignored issues
–
show
The type
League\JsonReference\Loader\ArrayLoader was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths
Loading history...
|
|||
24 | use League\JsonReference\Loader\ChainedLoader; |
||
0 ignored issues
–
show
The type
League\JsonReference\Loader\ChainedLoader was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths
Loading history...
|
|||
25 | |||
26 | /** |
||
27 | * Class to provide reusable validation rules. |
||
28 | * Used for object types and properties. |
||
29 | * |
||
30 | * @since 4.0.0 |
||
31 | */ |
||
32 | class Validation |
||
33 | { |
||
34 | /** |
||
35 | * The list of reserved names |
||
36 | * |
||
37 | * @var string[]|null |
||
38 | */ |
||
39 | protected static $reserved = null; |
||
40 | |||
41 | /** |
||
42 | * Clear reserved names list |
||
43 | * |
||
44 | * @return void |
||
45 | */ |
||
46 | public static function clear() |
||
47 | { |
||
48 | static::$reserved = null; |
||
49 | } |
||
50 | |||
51 | /** |
||
52 | * Load list of reserved names in `$reserved` |
||
53 | * |
||
54 | * @return string[] |
||
55 | */ |
||
56 | protected static function reservedWords() |
||
57 | { |
||
58 | if (static::$reserved === null) { |
||
59 | static::$reserved = (new PhpConfig())->read('BEdita/Core.reserved'); |
||
60 | } |
||
61 | |||
62 | return static::$reserved; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Check if a value is not reserved |
||
67 | * |
||
68 | * @param mixed $value Value to check |
||
69 | * @return bool |
||
70 | */ |
||
71 | public static function notReserved($value) |
||
72 | { |
||
73 | if ($value && in_array($value, static::reservedWords())) { |
||
74 | return false; |
||
75 | } |
||
76 | |||
77 | return true; |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * Checks that a value is a valid URL or custom url as myapp:// |
||
82 | * |
||
83 | * @param string $value The url to check |
||
84 | * @return bool |
||
85 | */ |
||
86 | public static function url($value) |
||
87 | { |
||
88 | // check for a valid scheme (https://, myapp://,...) |
||
89 | $regex = '/(?<scheme>^[a-z][a-z0-9+\-.]*:\/\/).*/'; |
||
90 | if (!preg_match($regex, $value, $matches)) { |
||
91 | return false; |
||
92 | } |
||
93 | |||
94 | // if scheme is not an URL protocol then it's a custom url (myapp://) => ok |
||
95 | if (!preg_match('/^(https?|ftps?|sftp|file|news|gopher:\/\/)/', $matches['scheme'])) { |
||
96 | return true; |
||
97 | } |
||
98 | |||
99 | return CakeValidation::url($value, true); |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Validate using JSON Schema. |
||
104 | * |
||
105 | * @param mixed $value Value being validated. |
||
106 | * @param mixed $schema Schema to validate against. |
||
107 | * @return true|string |
||
108 | */ |
||
109 | public static function jsonSchema($value, $schema) |
||
110 | { |
||
111 | if (is_string($schema)) { |
||
112 | $cacheLoader = new ArrayLoader([ |
||
113 | 'json-schema.org/draft-06/schema' => json_decode(file_get_contents(__DIR__ . DS . 'schemas' . DS . 'draft-06.json')), |
||
114 | ]); |
||
115 | |||
116 | $dereferencer = JsonSchemaDereferencer::draft6(); |
||
117 | $loaderManager = $dereferencer->getLoaderManager(); |
||
118 | $loaderManager->registerLoader('http', new ChainedLoader( |
||
119 | $cacheLoader, |
||
120 | $loaderManager->getLoader('http') |
||
121 | )); |
||
122 | $loaderManager->registerLoader('https', new ChainedLoader( |
||
123 | $cacheLoader, |
||
124 | $loaderManager->getLoader('https') |
||
125 | )); |
||
126 | |||
127 | $schema = $dereferencer->dereference($schema); |
||
128 | } |
||
129 | if (empty($schema)) { |
||
130 | return true; |
||
131 | } |
||
132 | |||
133 | $value = json_decode(json_encode($value)); |
||
134 | $schema = json_decode(json_encode($schema)); |
||
135 | $validator = new JsonSchemaValidator($value, $schema); |
||
136 | |||
137 | if ($validator->fails()) { |
||
138 | $errors = $validator->errors(); |
||
139 | $error = reset($errors); |
||
140 | |||
141 | return sprintf('%s (in: %s)', $error->getMessage(), $error->getDataPath()); |
||
142 | } |
||
143 | |||
144 | return true; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Validate language tag using `I18n` configuration. |
||
149 | * |
||
150 | * @param string $tag Language tag |
||
151 | * @return true|string |
||
152 | */ |
||
153 | public static function languageTag($tag) |
||
154 | { |
||
155 | $languages = Hash::normalize((array)Configure::read('I18n.languages')); |
||
156 | if (!empty($languages)) { |
||
157 | if (!array_key_exists($tag, $languages)) { |
||
158 | return __d('bedita', 'Invalid language tag "{0}"', $tag); |
||
159 | } |
||
160 | } |
||
161 | |||
162 | return true; |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * Validate input date and datetime. |
||
167 | * Accepetd input formats: |
||
168 | * - string date format |
||
169 | * - integer timestamps |
||
170 | * - DateTime objects |
||
171 | * |
||
172 | * Accepted date time string formats are |
||
173 | * - 2017-01-01 YYYY-MM-DD |
||
174 | * - 2017-01-01 11:22 YYYY-MM-DD hh:mm |
||
175 | * - 2017-01-01T11:22:33 YYYY-MM-DDThh:mm:ss |
||
176 | * - 2017-01-01T11:22:33Z YYYY-MM-DDThh:mm:ssZ |
||
177 | * - 2017-01-01T19:20+01:00 YYYY-MM-DDThh:mmTZD |
||
178 | * - 2017-01-01T11:22:33+01:00 YYYY-MM-DDThh:mm:ssTZD |
||
179 | * - 2017-01-01T19:20:30.45+01:00 YYYY-MM-DDThh:mm:ss.sTZD |
||
180 | * |
||
181 | * See ISO 8601 subset as defined here https://www.w3.org/TR/NOTE-datetime: |
||
182 | * |
||
183 | * Also timestamp as integer are accepted. |
||
184 | * |
||
185 | * @param mixed $value Date or datetime value |
||
186 | * @return true|string |
||
187 | */ |
||
188 | public static function dateTime($value) |
||
189 | { |
||
190 | if ($value instanceof DateTimeInterface) { |
||
191 | return true; |
||
192 | } |
||
193 | |||
194 | if (is_string($value) && preg_match('/^\d{4}(-\d\d(-\d\d([T ]\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/i', $value)) { |
||
195 | return true; |
||
196 | } |
||
197 | |||
198 | if (filter_var($value, FILTER_VALIDATE_INT)) { |
||
199 | return true; |
||
200 | } |
||
201 | |||
202 | return __d('bedita', 'Invalid date or datetime "{0}"', print_r($value, true)); |
||
203 | } |
||
204 | } |
||
205 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths