1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @link https://github.com/nnx-framework/jms-serializer-module |
4
|
|
|
* @author Malofeykin Andrey <[email protected]> |
5
|
|
|
*/ |
6
|
|
|
namespace Nnx\JmsSerializerModule\EventDispatcher; |
7
|
|
|
|
8
|
|
|
use Doctrine\Common\Persistence\ManagerRegistry; |
9
|
|
|
use Doctrine\Common\Persistence\ObjectManager; |
10
|
|
|
use Interop\Container\ContainerInterface; |
11
|
|
|
use JMS\Serializer\EventDispatcher\PreDeserializeEvent; |
12
|
|
|
use JMS\Serializer\EventDispatcher\EventSubscriberInterface; |
13
|
|
|
use JMS\Serializer\EventDispatcher\Events; |
14
|
|
|
use JMS\Serializer\XmlDeserializationVisitor; |
15
|
|
|
use SimpleXMLElement; |
16
|
|
|
use Nnx\JmsSerializerModule\DataContainerBuilder\XmlBuilderInterface; |
17
|
|
|
use Nnx\JmsSerializerModule\ObjectConstructor\DoctrineObjectConstructor\DataInterface; |
18
|
|
|
use Zend\ServiceManager\AbstractPluginManager; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Class XmlDoctrineObjectConstructorSubscriber |
22
|
|
|
* |
23
|
|
|
* @package Nnx\JmsSerializerModule\EventDispatcher |
24
|
|
|
*/ |
25
|
|
|
class XmlDoctrineObjectConstructorSubscriber implements EventSubscriberInterface |
26
|
|
|
{ |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Хранилище ObjectManager'ов Doctrine 2 |
30
|
|
|
* |
31
|
|
|
* @var ManagerRegistry |
32
|
|
|
*/ |
33
|
|
|
protected $managerRegistry; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Сервис для подготовки данных из SimpleXMLElement |
37
|
|
|
* |
38
|
|
|
* @var XmlBuilderInterface |
39
|
|
|
*/ |
40
|
|
|
protected $dataContainerFromXmlBuilder; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Менеджер для получения контейнера с данными для DoctrineObjectConstructor |
44
|
|
|
* |
45
|
|
|
* @var ContainerInterface |
46
|
|
|
*/ |
47
|
|
|
protected $doctrineObjectConstructorDataManager; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* XmlDoctrineObjectConstructorSubscriber constructor. |
51
|
|
|
* |
52
|
|
|
* @param ManagerRegistry $managerRegistry |
53
|
|
|
* @param XmlBuilderInterface $dataContainerFromXmlBuilder |
54
|
|
|
* @param ContainerInterface $doctrineObjectConstructorDataManager |
55
|
|
|
*/ |
56
|
|
|
public function __construct( |
57
|
|
|
ManagerRegistry $managerRegistry, |
58
|
|
|
XmlBuilderInterface $dataContainerFromXmlBuilder, |
59
|
|
|
ContainerInterface $doctrineObjectConstructorDataManager |
60
|
|
|
) { |
61
|
|
|
$this->setDoctrineObjectConstructorDataManager($doctrineObjectConstructorDataManager); |
62
|
|
|
$this->setManagerRegistry($managerRegistry); |
63
|
|
|
$this->setDataContainerFromXmlBuilder($dataContainerFromXmlBuilder); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Обработка события бросаемого перед десериализацией данных |
69
|
|
|
* |
70
|
|
|
* @param PreDeserializeEvent $event |
71
|
|
|
* |
72
|
|
|
* @return void |
73
|
|
|
* @throws \Zend\ServiceManager\Exception\ServiceNotFoundException |
74
|
|
|
* @throws \Zend\ServiceManager\Exception\ServiceNotCreatedException |
75
|
|
|
* @throws \Zend\ServiceManager\Exception\RuntimeException |
76
|
|
|
* @throws \Interop\Container\Exception\NotFoundException |
77
|
|
|
* @throws \Interop\Container\Exception\ContainerException |
78
|
|
|
*/ |
79
|
|
|
public function onPreDeserialize(PreDeserializeEvent $event) |
80
|
|
|
{ |
81
|
|
|
if (!$this->isToHandleEvent($event)) { |
82
|
|
|
return; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$visitor = $event->getVisitor(); |
86
|
|
|
if (!$visitor instanceof XmlDeserializationVisitor) { |
87
|
|
|
return; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
|
91
|
|
|
/** @var SimpleXMLElement $data */ |
92
|
|
|
$data = $event->getData(); |
93
|
|
|
|
94
|
|
|
$dataContainerFromXmlBuilder = $this->getDataContainerFromXmlBuilder(); |
95
|
|
|
|
96
|
|
|
if (!$dataContainerFromXmlBuilder->hasDataInCache($data)) { |
97
|
|
|
$this->getDataContainerFromXmlBuilder()->loadDataFromResource($data); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$dataContainer = $dataContainerFromXmlBuilder->getDataContainerFromCache($data); |
101
|
|
|
$entity = $dataContainerFromXmlBuilder->getEntityFromCache($data); |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
$dataForDoctrineObjectConstructor = $this->getDoctrineObjectConstructorDataManager()->get( |
105
|
|
|
DataInterface::class, |
106
|
|
|
[ |
|
|
|
|
107
|
|
|
'dataContainer' => $dataContainer, |
108
|
|
|
'entity' => $entity |
109
|
|
|
] |
110
|
|
|
); |
111
|
|
|
|
112
|
|
|
$event->setData($dataForDoctrineObjectConstructor); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Проверяет, нужно ли обрабатывать данное событие |
118
|
|
|
* |
119
|
|
|
* @param PreDeserializeEvent $event |
120
|
|
|
* |
121
|
|
|
* @return false |
122
|
|
|
*/ |
123
|
|
|
public function isToHandleEvent(PreDeserializeEvent $event) |
124
|
|
|
{ |
125
|
|
|
$type = $event->getType(); |
126
|
|
|
if (!array_key_exists('name', $type)) { |
127
|
|
|
return false; |
128
|
|
|
} |
129
|
|
|
$class = $type['name']; |
130
|
|
|
if (!class_exists($class)) { |
131
|
|
|
return false; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
$managerRegistry = $this->getManagerRegistry(); |
135
|
|
|
$objectManager = $managerRegistry->getManagerForClass($class); |
136
|
|
|
if (!$objectManager instanceof ObjectManager) { |
137
|
|
|
return false; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$data = $event->getData(); |
141
|
|
|
|
142
|
|
|
return $data instanceof SimpleXMLElement; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @inheritdoc |
148
|
|
|
* |
149
|
|
|
* @return array |
150
|
|
|
*/ |
151
|
|
|
public static function getSubscribedEvents() |
152
|
|
|
{ |
153
|
|
|
return [ |
154
|
|
|
[ |
155
|
|
|
'event' => Events::PRE_DESERIALIZE, |
156
|
|
|
'format' => 'xml', |
157
|
|
|
'method' => 'onPreDeserialize' |
158
|
|
|
], |
159
|
|
|
]; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Возвращает хранилище ObjectManager'ов Doctrine 2 |
164
|
|
|
* |
165
|
|
|
* @return ManagerRegistry |
166
|
|
|
*/ |
167
|
|
|
public function getManagerRegistry() |
168
|
|
|
{ |
169
|
|
|
return $this->managerRegistry; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Устанавливает хранилище ObjectManager'ов Doctrine 2 |
174
|
|
|
* |
175
|
|
|
* @param ManagerRegistry $managerRegistry |
176
|
|
|
* |
177
|
|
|
* @return $this |
178
|
|
|
*/ |
179
|
|
|
public function setManagerRegistry(ManagerRegistry $managerRegistry) |
180
|
|
|
{ |
181
|
|
|
$this->managerRegistry = $managerRegistry; |
182
|
|
|
|
183
|
|
|
return $this; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Возвращает сервис для подготовки данных из SimpleXMLElement |
188
|
|
|
* |
189
|
|
|
* @return XmlBuilderInterface |
190
|
|
|
*/ |
191
|
|
|
public function getDataContainerFromXmlBuilder() |
192
|
|
|
{ |
193
|
|
|
return $this->dataContainerFromXmlBuilder; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Устанавливает сервис для подготовки данных из SimpleXMLElement |
198
|
|
|
* |
199
|
|
|
* @param XmlBuilderInterface $dataContainerFromXmlBuilder |
200
|
|
|
* |
201
|
|
|
* @return $this |
202
|
|
|
*/ |
203
|
|
|
public function setDataContainerFromXmlBuilder(XmlBuilderInterface $dataContainerFromXmlBuilder) |
204
|
|
|
{ |
205
|
|
|
$this->dataContainerFromXmlBuilder = $dataContainerFromXmlBuilder; |
206
|
|
|
|
207
|
|
|
return $this; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Возвращает менеджер для получения контейнера с данными для DoctrineObjectConstructor |
212
|
|
|
* |
213
|
|
|
* @return AbstractPluginManager |
214
|
|
|
*/ |
215
|
|
|
public function getDoctrineObjectConstructorDataManager() |
216
|
|
|
{ |
217
|
|
|
return $this->doctrineObjectConstructorDataManager; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Устанавливает менеджер для получения контейнера с данными для DoctrineObjectConstructor |
222
|
|
|
* |
223
|
|
|
* @param ContainerInterface $doctrineObjectConstructorDataManager |
224
|
|
|
* |
225
|
|
|
* @return $this |
226
|
|
|
*/ |
227
|
|
|
public function setDoctrineObjectConstructorDataManager(ContainerInterface $doctrineObjectConstructorDataManager) |
228
|
|
|
{ |
229
|
|
|
$this->doctrineObjectConstructorDataManager = $doctrineObjectConstructorDataManager; |
230
|
|
|
|
231
|
|
|
return $this; |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
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.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.