Completed
Push — master ( 99ca87...95904e )
by Andrey
23:44
created

onPreDeserialize()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
rs 8.5806
cc 4
eloc 17
nc 4
nop 1
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
            [
0 ignored issues
show
Unused Code introduced by
The call to ContainerInterface::get() has too many arguments starting with array('dataContainer' =>...r, 'entity' => $entity).

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.

Loading history...
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