PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.2
WooCommerce v10.9.2
11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / vendor / opis / json-schema / src / JsonPointer.php
woocommerce / vendor / opis / json-schema / src Last commit date
Errors 1 year ago Exceptions 1 year ago Filters 1 year ago Formats 1 year ago Info 1 year ago KeywordValidators 1 year ago Keywords 1 year ago Parsers 1 year ago Pragmas 1 year ago Resolvers 1 year ago Schemas 1 year ago Variables 1 year ago CompliantValidator.php 1 year ago ContentEncoding.php 1 year ago ContentMediaType.php 1 year ago Filter.php 1 year ago Format.php 1 year ago Helper.php 1 year ago JsonPointer.php 1 year ago Keyword.php 1 year ago KeywordValidator.php 1 year ago Pragma.php 1 year ago Schema.php 1 year ago SchemaLoader.php 7 months ago SchemaValidator.php 1 year ago Uri.php 1 year ago ValidationContext.php 7 months ago ValidationResult.php 1 year ago Validator.php 1 year ago Variables.php 1 year ago
JsonPointer.php
411 lines
1 <?php
2 /* ============================================================================
3 * Copyright 2020 Zindex Software
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ============================================================================ */
17
18 namespace Opis\JsonSchema;
19
20 final class JsonPointer
21 {
22 /** @var string */
23 protected const PATTERN = '~^(?:(?<level>0|[1-9][0-9]*)(?<shift>(?:\+|-)(?:0|[1-9][0-9]*))?)?(?<pointer>(?:/[^/#]*)*)(?<fragment>#)?$~';
24
25 /** @var string */
26 protected const UNESCAPED = '/~([^01]|$)/';
27
28 protected int $level = -1;
29
30 protected int $shift = 0;
31
32 protected bool $fragment = false;
33
34 /** @var string[]|int[] */
35 protected array $path;
36
37 protected ?string $str = null;
38
39 final protected function __construct(array $path, int $level = -1, int $shift = 0, bool $fragment = false)
40 {
41 $this->path = $path;
42 $this->level = $level < 0 ? -1 : $level;
43 $this->shift = $shift;
44 $this->fragment = $level >= 0 && $fragment;
45 }
46
47 public function isRelative(): bool
48 {
49 return $this->level >= 0;
50 }
51
52 public function isAbsolute(): bool
53 {
54 return $this->level < 0;
55 }
56
57 public function level(): int
58 {
59 return $this->level;
60 }
61
62 public function shift(): int
63 {
64 return $this->shift;
65 }
66
67 /**
68 * @return string[]
69 */
70 public function path(): array
71 {
72 return $this->path;
73 }
74
75 /**
76 * @return bool
77 */
78 public function hasFragment(): bool
79 {
80 return $this->fragment;
81 }
82
83 /**
84 * @return string
85 */
86 public function __toString(): string
87 {
88 if ($this->str === null) {
89 if ($this->level >= 0) {
90 $this->str = (string)$this->level;
91
92 if ($this->shift !== 0) {
93 if ($this->shift > 0) {
94 $this->str .= '+';
95 }
96 $this->str .= $this->shift;
97 }
98
99 if ($this->path) {
100 $this->str .= '/';
101 $this->str .= implode('/', self::encodePath($this->path));
102 }
103
104 if ($this->fragment) {
105 $this->str .= '#';
106 }
107 } else {
108 $this->str = '/';
109 $this->str .= implode('/', self::encodePath($this->path));
110 }
111 }
112
113 return $this->str;
114 }
115
116 /**
117 * @param $data
118 * @param array|null $path
119 * @param mixed $default
120 * @return mixed
121 */
122 public function data($data, ?array $path = null, $default = null)
123 {
124 if ($this->level < 0) {
125 return self::getData($data, $this->path, false, $default);
126 }
127
128 if ($path !== null) {
129 $path = $this->absolutePath($path);
130 }
131
132 if ($path === null) {
133 return $default;
134 }
135
136 return self::getData($data, $path, $this->fragment, $default);
137 }
138
139 /**
140 * @param array $path
141 * @return array|null
142 */
143 public function absolutePath(array $path = []): ?array
144 {
145 if ($this->level < 0) {
146 // Absolute pointer
147 return $this->path;
148 }
149
150 if ($this->level === 0) {
151 if ($this->shift && !$this->handleShift($path)) {
152 return null;
153 }
154 return $this->path ? array_merge($path, $this->path) : $path;
155 }
156
157 $count = count($path);
158 if ($count === $this->level) {
159 if ($this->shift) {
160 return null;
161 }
162 return $this->path;
163 }
164
165 if ($count > $this->level) {
166 $count -= $this->level;
167
168 /** @var array $path */
169 $path = array_slice($path, 0, $count);
170
171 if ($this->shift && !$this->handleShift($path, $count)) {
172 return null;
173 }
174
175 return $this->path ? array_merge($path, $this->path) : $path;
176 }
177
178 return null;
179 }
180
181 protected function handleShift(array &$path, ?int $count = null): bool
182 {
183 if (!$path) {
184 return false;
185 }
186
187 $count ??= count($path);
188
189 $last = $path[$count - 1];
190
191 if (is_string($last) && preg_match('/^[1-9]\d*$/', $last)) {
192 $last = (int) $last;
193 }
194
195 if (!is_int($last)) {
196 return false;
197 }
198
199 $path[$count - 1] = $last + $this->shift;
200
201 return true;
202 }
203
204 public static function parse(string $pointer, bool $decode = true): ?self
205 {
206 if ($pointer === '' || !preg_match(self::PATTERN, $pointer, $m)) {
207 // Not a pointer
208 return null;
209 }
210
211 $pointer = $m['pointer'] ?? null;
212
213 // Check if the pointer is escaped
214 if ($decode && $pointer && preg_match(self::UNESCAPED, $pointer)) {
215 // Invalid pointer
216 return null;
217 }
218
219 $level = isset($m['level']) && $m['level'] !== ''
220 ? (int)$m['level']
221 : -1;
222
223 $shift = 0;
224 if ($level >= 0 && isset($m['shift']) && $m['shift'] !== '') {
225 $shift = (int) $m['shift'];
226 }
227
228 $fragment = isset($m['fragment']) && $m['fragment'] === '#';
229 unset($m);
230
231 if ($fragment && $level < 0) {
232 return null;
233 }
234
235 if ($pointer === '') {
236 $pointer = null;
237 } elseif ($pointer !== null) {
238 // Remove leading slash
239 $pointer = substr($pointer, 1);
240
241 if ($pointer !== '') {
242 $pointer = self::decodePath(explode('/', $pointer));
243 } else {
244 $pointer = null;
245 }
246 }
247
248 return new self($pointer ?? [], $level, $shift, $fragment);
249 }
250
251 /**
252 * @param $data
253 * @param array|null $path
254 * @param bool $fragment
255 * @param mixed $default
256 * @return mixed
257 */
258 public static function getData($data, ?array $path = null, bool $fragment = false, $default = null)
259 {
260 if ($path === null) {
261 return $default;
262 }
263
264 if (!$path) {
265 return $fragment ? $default : $data;
266 }
267
268 if ($fragment) {
269 return end($path);
270 }
271
272 foreach ($path as $key) {
273 if (is_array($data)) {
274 if (!array_key_exists($key, $data)) {
275 return $default;
276 }
277 $data = $data[$key];
278 } elseif (is_object($data)) {
279 if (!property_exists($data, $key)) {
280 return $default;
281 }
282 $data = $data->{$key};
283 } else {
284 return $default;
285 }
286 }
287
288 return $data;
289 }
290
291 /**
292 * @param string|string[] $path
293 * @return string|string[]
294 */
295 public static function encodePath($path)
296 {
297 $path = str_replace('~', '~0', $path);
298 $path = str_replace('/', '~1', $path);
299
300 if (is_array($path)) {
301 return array_map('rawurlencode', $path);
302 }
303
304 return rawurlencode($path);
305 }
306
307 /**
308 * @param string|string[] $path
309 * @return string|string[]
310 */
311 public static function decodePath($path)
312 {
313 if (is_array($path)) {
314 $path = array_map('rawurldecode', $path);
315 } else {
316 $path = rawurldecode($path);
317 }
318
319 $path = str_replace('~1', '/', $path);
320 $path = str_replace('~0', '~', $path);
321
322 return $path;
323 }
324
325 /**
326 * @param array $path
327 * @return string
328 */
329 public static function pathToString(array $path): string
330 {
331 if (!$path) {
332 return '/';
333 }
334
335 return '/' . implode('/', self::encodePath($path));
336 }
337
338 /**
339 * @param array $path
340 * @return string
341 */
342 public static function pathToFragment(array $path): string
343 {
344 if (!$path) {
345 return '#';
346 }
347
348 return '#/' . implode('/', self::encodePath($path));
349 }
350
351 /**
352 * @param string $pointer
353 * @return bool
354 */
355 public static function isAbsolutePointer(string $pointer): bool
356 {
357 if ($pointer === '/') {
358 return true;
359 }
360
361 if (!preg_match(self::PATTERN, $pointer, $m)) {
362 return false;
363 }
364
365 if (isset($m['fragment']) || isset($m['level']) && $m['level'] !== '') {
366 return false;
367 }
368
369 if (!isset($m['pointer']) || $m['pointer'] === '') {
370 return true;
371 }
372
373 return !preg_match(self::UNESCAPED, $m['pointer']);
374 }
375
376 /**
377 * @param string $pointer
378 * @return bool
379 */
380 public static function isRelativePointer(string $pointer): bool
381 {
382 if ($pointer === '') {
383 return false;
384 }
385
386 if (!preg_match(self::PATTERN, $pointer, $m)) {
387 return false;
388 }
389
390 if (!isset($m['level']) || $m['level'] === '' || (int)$m['level'] < 0) {
391 return false;
392 }
393
394 if (!isset($m['pointer']) || $m['pointer'] === '') {
395 return true;
396 }
397
398 return !preg_match(self::UNESCAPED, $m['pointer']);
399 }
400
401 public static function createAbsolute(array $path): self
402 {
403 return new self($path, -1, 0, false);
404 }
405
406 public static function createRelative(int $level, array $path = [], int $shift = 0, bool $fragment = false): self
407 {
408 return new self($path, $level, $shift, $fragment);
409 }
410 }
411