1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace GoetasWebservices\SoapServices\Metadata\Arguments; |
||
6 | |||
7 | use Doctrine\Instantiator\Instantiator; |
||
8 | use GoetasWebservices\SoapServices\Metadata\SerializerUtils; |
||
9 | use JMS\Serializer\Accessor\DefaultAccessorStrategy; |
||
10 | use JMS\Serializer\DeserializationContext; |
||
11 | use JMS\Serializer\Metadata\PropertyMetadata; |
||
12 | use JMS\Serializer\Serializer; |
||
13 | |||
14 | class ArgumentsReader implements ArgumentsReaderInterface |
||
15 | { |
||
16 | /** |
||
17 | * @var Serializer |
||
18 | */ |
||
19 | private $serializer; |
||
20 | |||
21 | public function __construct(Serializer $serializer) |
||
22 | { |
||
23 | $this->serializer = $serializer; |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * @param array $args |
||
28 | * @param array $message |
||
29 | */ |
||
30 | public function readArguments(array $args, array $message): object |
||
31 | { |
||
32 | $envelopes = array_filter($args, static function ($item) use ($message) { |
||
33 | return $item instanceof $message['message_fqcn']; |
||
34 | }); |
||
35 | if ($envelopes) { |
||
0 ignored issues
–
show
|
|||
36 | $envelope = reset($envelopes); |
||
37 | $this->handleHeaders($args, $message, $envelope); |
||
38 | |||
39 | return $envelope; |
||
40 | } |
||
41 | |||
42 | $instantiator = new Instantiator(); |
||
43 | $envelope = $instantiator->instantiate($message['message_fqcn']); |
||
44 | $this->handleHeaders($args, $message, $envelope); |
||
45 | |||
46 | if (!count($message['parts'])) { |
||
47 | return $envelope; |
||
48 | } |
||
49 | |||
50 | if ($args[0] instanceof $message['part_fqcn']) { |
||
51 | $envelope->setBody($args[0]); |
||
52 | |||
53 | return $envelope; |
||
54 | } |
||
55 | |||
56 | $body = $instantiator->instantiate($message['part_fqcn']); |
||
57 | $envelope->setBody($body); |
||
58 | |||
59 | $factory = SerializerUtils::getMetadataFactory($this->serializer); |
||
60 | |||
61 | $classMetadata = $factory->getMetadataForClass($message['part_fqcn']); |
||
62 | |||
63 | if (count($message['parts']) > 1) { |
||
64 | if (count($message['parts']) !== count($args)) { |
||
65 | throw new \Exception('Expected to have exactly ' . count($message['parts']) . ' arguments, supplied ' . count($args)); |
||
66 | } |
||
67 | |||
68 | foreach ($message['parts'] as $paramName => $elementName) { |
||
69 | $propertyMetadata = $classMetadata->propertyMetadata[$paramName]; |
||
0 ignored issues
–
show
|
|||
70 | $this->setValue($body, array_shift($args), $propertyMetadata); |
||
71 | } |
||
72 | |||
73 | return $envelope; |
||
74 | } |
||
75 | |||
76 | $propertyName = key($message['parts']); |
||
77 | $propertyMetadata = $classMetadata->propertyMetadata[$propertyName]; |
||
78 | |||
79 | if ($args[0] instanceof $propertyMetadata->type['name']) { |
||
80 | $this->setValue($body, reset($args), $propertyMetadata); |
||
81 | |||
82 | return $envelope; |
||
83 | } |
||
84 | |||
85 | $instance2 = $instantiator->instantiate($propertyMetadata->type['name']); |
||
86 | $classMetadata2 = $factory->getMetadataForClass($propertyMetadata->type['name']); |
||
87 | $this->setValue($body, $instance2, $propertyMetadata); |
||
88 | |||
89 | foreach ($classMetadata2->propertyMetadata as $propertyMetadata2) { |
||
90 | if (!count($args)) { |
||
91 | throw new \Exception("Not enough arguments provided. Can't find a parameter to set " . $propertyMetadata2->name); |
||
92 | } |
||
93 | |||
94 | $value = array_shift($args); |
||
95 | $this->setValue($instance2, $value, $propertyMetadata2); |
||
96 | } |
||
97 | |||
98 | return $envelope; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * @param array $args |
||
103 | * @param array $message |
||
104 | */ |
||
105 | private function handleHeaders(array $args, array $message, object $envelope): void |
||
106 | { |
||
107 | $headers = array_filter($args, static function ($item) use ($message) { |
||
108 | return $item instanceof $message['headers_fqcn']; |
||
109 | }); |
||
110 | if (count($headers)) { |
||
111 | $envelope->setHeader(reset($headers)); |
||
112 | } |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * @param mixed $value |
||
117 | */ |
||
118 | private function setValue(object $target, $value, PropertyMetadata $propertyMetadata): void |
||
119 | { |
||
120 | $context = DeserializationContext::create(); |
||
121 | $accessor = new DefaultAccessorStrategy(); |
||
122 | |||
123 | $accessor->setValue($target, $value, $propertyMetadata, $context); |
||
124 | } |
||
125 | } |
||
126 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.