|
4 | 4 | * SPDX-License-Identifier: MIT |
5 | 5 | * SPDX-FileCopyrightText: (c) Respect Project Contributors |
6 | 6 | * SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com> |
| 7 | + * SPDX-FileContributor: Alexandre Gomes Gaigalas <alganet@gmail.com> |
7 | 8 | */ |
8 | 9 |
|
9 | 10 | declare(strict_types=1); |
10 | 11 |
|
11 | 12 | namespace Respect\Validation\Transformers; |
12 | 13 |
|
13 | | -use function array_shift; |
14 | | -use function in_array; |
15 | | -use function str_starts_with; |
16 | | -use function strlen; |
17 | | -use function substr; |
| 14 | +use function array_keys; |
| 15 | +use function array_slice; |
| 16 | +use function implode; |
| 17 | +use function preg_match; |
| 18 | +use function sprintf; |
18 | 19 |
|
19 | 20 | final class Prefix implements Transformer |
20 | 21 | { |
21 | | - private const array RULES_TO_SKIP = [ |
22 | | - 'all', |
23 | | - 'allOf', |
24 | | - 'key', |
25 | | - 'keyExists', |
26 | | - 'keyOptional', |
27 | | - 'keySet', |
28 | | - 'length', |
29 | | - 'max', |
30 | | - 'maxAge', |
31 | | - 'min', |
32 | | - 'minAge', |
33 | | - 'not', |
34 | | - 'emoji', |
35 | | - 'nullOr', |
36 | | - 'property', |
37 | | - 'propertyExists', |
38 | | - 'propertyOptional', |
39 | | - 'undefOr', |
| 22 | + private const array RULES_THAT_PREFIX_OR_STAND_ALONE = [ |
| 23 | + 'all' => true, |
| 24 | + 'allOf' => true, |
| 25 | + 'emoji' => true, |
| 26 | + 'key' => true, |
| 27 | + 'keyExists' => true, |
| 28 | + 'keyOptional' => true, |
| 29 | + 'keySet' => true, |
| 30 | + 'length' => true, |
| 31 | + 'max' => true, |
| 32 | + 'maxAge' => true, |
| 33 | + 'min' => true, |
| 34 | + 'minAge' => true, |
| 35 | + 'not' => true, |
| 36 | + 'nullOr' => true, |
| 37 | + 'property' => true, |
| 38 | + 'propertyExists' => true, |
| 39 | + 'propertyOptional' => true, |
| 40 | + 'undefOr' => true, |
40 | 41 | ]; |
| 42 | + private const array RULES_THAT_USE_SUFFIX_AS_ARGUMENT = [ |
| 43 | + 'key' => true, |
| 44 | + 'property' => true, |
| 45 | + ]; |
| 46 | + |
| 47 | + private static string|null $regex = null; |
41 | 48 |
|
42 | 49 | public function transform(ValidatorSpec $validatorSpec): ValidatorSpec |
43 | 50 | { |
44 | | - if ($validatorSpec->wrapper !== null || in_array($validatorSpec->name, self::RULES_TO_SKIP, true)) { |
| 51 | + $matches = $this->match($validatorSpec); |
| 52 | + if ($matches === []) { |
45 | 53 | return $validatorSpec; |
46 | 54 | } |
47 | 55 |
|
48 | | - foreach (['all', 'length', 'max', 'min', 'not', 'nullOr', 'undefOr'] as $prefix) { |
49 | | - if (!str_starts_with($validatorSpec->name, $prefix)) { |
50 | | - continue; |
51 | | - } |
52 | | - |
| 56 | + if (!isset(self::RULES_THAT_USE_SUFFIX_AS_ARGUMENT[$matches['name']])) { |
53 | 57 | return new ValidatorSpec( |
54 | | - substr($validatorSpec->name, strlen($prefix)), |
| 58 | + $matches['rest'], |
55 | 59 | $validatorSpec->arguments, |
56 | | - new ValidatorSpec($prefix), |
| 60 | + new ValidatorSpec($matches['name']), |
57 | 61 | ); |
58 | 62 | } |
59 | 63 |
|
60 | | - foreach (['key', 'property'] as $prefix) { |
61 | | - if (!str_starts_with($validatorSpec->name, $prefix)) { |
62 | | - continue; |
63 | | - } |
64 | | - |
65 | | - $arguments = $validatorSpec->arguments; |
66 | | - array_shift($arguments); |
67 | | - $wrapperArguments = [$validatorSpec->arguments[0]]; |
| 64 | + return new ValidatorSpec( |
| 65 | + $matches['rest'], |
| 66 | + array_slice($validatorSpec->arguments, 1), |
| 67 | + new ValidatorSpec($matches['name'], [$validatorSpec->arguments[0]]), |
| 68 | + ); |
| 69 | + } |
68 | 70 |
|
69 | | - return new ValidatorSpec( |
70 | | - substr($validatorSpec->name, strlen($prefix)), |
71 | | - $arguments, |
72 | | - new ValidatorSpec($prefix, $wrapperArguments), |
73 | | - ); |
| 71 | + /** @return array{}|array{name: string, rest: string} */ |
| 72 | + private function match(ValidatorSpec $validatorSpec): array |
| 73 | + { |
| 74 | + if ($validatorSpec->wrapper !== null || isset(self::RULES_THAT_PREFIX_OR_STAND_ALONE[$validatorSpec->name])) { |
| 75 | + return []; |
74 | 76 | } |
75 | 77 |
|
76 | | - return $validatorSpec; |
| 78 | + preg_match(self::getRegex(), $validatorSpec->name, $matches); |
| 79 | + |
| 80 | + return $matches; |
| 81 | + } |
| 82 | + |
| 83 | + private static function getRegex(): string |
| 84 | + { |
| 85 | + return self::$regex ?? self::$regex = sprintf( |
| 86 | + '/^(?<name>%s)(?<rest>.+)$/', |
| 87 | + implode('|', array_keys(self::RULES_THAT_PREFIX_OR_STAND_ALONE)), |
| 88 | + ); |
77 | 89 | } |
78 | 90 | } |
0 commit comments