1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the API Platform project. |
||
5 | * |
||
6 | * (c) Kévin Dunglas <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | declare(strict_types=1); |
||
13 | |||
14 | namespace ApiPlatform\Core\Serializer; |
||
15 | |||
16 | use Symfony\Component\Serializer\NameConverter\NameConverterInterface; |
||
17 | use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; |
||
18 | use Symfony\Component\Serializer\Normalizer\NormalizerInterface; |
||
19 | use Symfony\Component\Validator\ConstraintViolationListInterface; |
||
20 | |||
21 | /** |
||
22 | * Common features regarding Constraint Violation normalization. |
||
23 | * |
||
24 | * @author Kévin Dunglas <[email protected]> |
||
25 | * |
||
26 | * @internal |
||
27 | */ |
||
28 | abstract class AbstractConstraintViolationListNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface |
||
29 | { |
||
30 | public const FORMAT = null; // Must be overrode |
||
31 | |||
32 | private $serializePayloadFields; |
||
33 | private $nameConverter; |
||
34 | |||
35 | public function __construct(array $serializePayloadFields = null, NameConverterInterface $nameConverter = null) |
||
36 | { |
||
37 | $this->nameConverter = $nameConverter; |
||
38 | $this->serializePayloadFields = $serializePayloadFields; |
||
39 | } |
||
40 | |||
41 | /** |
||
42 | * {@inheritdoc} |
||
43 | */ |
||
44 | public function supportsNormalization($data, $format = null): bool |
||
45 | { |
||
46 | return static::FORMAT === $format && $data instanceof ConstraintViolationListInterface; |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * {@inheritdoc} |
||
51 | */ |
||
52 | public function hasCacheableSupportsMethod(): bool |
||
53 | { |
||
54 | return true; |
||
55 | } |
||
56 | |||
57 | protected function getMessagesAndViolations(ConstraintViolationListInterface $constraintViolationList): array |
||
58 | { |
||
59 | $violations = $messages = []; |
||
60 | |||
61 | foreach ($constraintViolationList as $violation) { |
||
62 | $class = \is_object($root = $violation->getRoot()) ? \get_class($root) : null; |
||
63 | $violationData = [ |
||
64 | 'propertyPath' => $this->nameConverter ? $this->nameConverter->normalize($violation->getPropertyPath(), $class, static::FORMAT) : $violation->getPropertyPath(), |
||
0 ignored issues
–
show
|
|||
65 | 'message' => $violation->getMessage(), |
||
66 | ]; |
||
67 | |||
68 | $constraint = $violation->getConstraint(); |
||
69 | if ($this->serializePayloadFields && $constraint && $constraint->payload) { |
||
70 | // If some fields are whitelisted, only them are added |
||
71 | $payloadFields = null === $this->serializePayloadFields ? $constraint->payload : array_intersect_key($constraint->payload, array_flip($this->serializePayloadFields)); |
||
72 | $payloadFields && $violationData['payload'] = $payloadFields; |
||
73 | } |
||
74 | |||
75 | $violations[] = $violationData; |
||
76 | $messages[] = ($violationData['propertyPath'] ? "{$violationData['propertyPath']}: " : '').$violationData['message']; |
||
77 | } |
||
78 | |||
79 | return [$messages, $violations]; |
||
80 | } |
||
81 | } |
||
82 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.