getFallbackConstructor()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * @link    https://github.com/nnx-framework/jms-serializer-module
4
 * @author  Malofeykin Andrey  <[email protected]>
5
 */
6
namespace Nnx\JmsSerializerModule\ObjectConstructor;
7
8
use Doctrine\Common\Persistence\ManagerRegistry;
9
use JMS\Serializer\Construction\ObjectConstructorInterface;
10
use JMS\Serializer\VisitorInterface;
11
use JMS\Serializer\Metadata\ClassMetadata;
12
use JMS\Serializer\DeserializationContext;
13
use Nnx\JmsSerializerModule\DoctrineObjectEngine\DoctrineObjectEngineInterface;
14
15
/**
16
 * Class DoctrineObjectConstructor
17
 *
18
 * @package Nnx\JmsSerializerModule\ObjectConstructor
19
 */
20
class DoctrineObjectConstructor implements ObjectConstructorInterface
21
{
22
    /**
23
     * Хранилище ObjectManager'ов Doctrine
24
     *
25
     * @var ManagerRegistry
26
     */
27
    protected $managerRegistry;
28
29
    /**
30
     * Конструктор объектов которому делегируется создание объекта из данных, в случае если данные не подходят для данного
31
     * конструктора
32
     *
33
     * @var ObjectConstructorInterface
34
     */
35
    protected $fallbackConstructor;
36
37
    /**
38
     * Движок для создания объектов доктрины
39
     *
40
     * @var DoctrineObjectEngineInterface
41
     */
42
    protected $doctrineObjectEngine;
43
44
    /**
45
     * Информация о уже обработанных конейнерах данных
46
     *
47
     * @var array
48
     */
49
    protected $finishedDataContainerId = [];
50
51
    /**
52
     * Constructor.
53
     *
54
     * @param ManagerRegistry               $managerRegistry     Manager registry
55
     * @param ObjectConstructorInterface    $fallbackConstructor Fallback object constructor
56
     * @param DoctrineObjectEngineInterface $doctrineObjectEngine
57
     */
58
    public function __construct(
59
        ManagerRegistry $managerRegistry,
60
        ObjectConstructorInterface $fallbackConstructor,
61
        DoctrineObjectEngineInterface $doctrineObjectEngine
62
    ) {
63
        $this->setManagerRegistry($managerRegistry);
64
        $this->setFallbackConstructor($fallbackConstructor);
65
        $this->setDoctrineObjectEngine($doctrineObjectEngine);
66
    }
67
68
    /**
69
     * @inheritdoc
70
     *
71
     * @param VisitorInterface       $visitor
72
     * @param ClassMetadata          $metadata
73
     * @param mixed                  $data
74
     * @param array                  $type
75
     * @param DeserializationContext $context
76
     *
77
     * @return mixed
78
     */
79
    public function construct(VisitorInterface $visitor, ClassMetadata $metadata, $data, array $type, DeserializationContext $context)
80
    {
81
        $fallbackConstructor = $this->getFallbackConstructor();
82
        if (!$data instanceof DoctrineObjectConstructor\DataInterface) {
83
            return $fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
84
        }
85
86
        // Locate possible ObjectManager
87
        $objectManager = $this->getManagerRegistry()->getManagerForClass($metadata->name);
88
89
        if (!$objectManager) {
90
            // No ObjectManager found, proceed with normal deserialization
91
            return $fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
92
        }
93
94
        // Locate possible ClassMetadata
95
        $classMetadataFactory = $objectManager->getMetadataFactory();
96
97
        if ($classMetadataFactory->isTransient($metadata->name)) {
98
            // No ClassMetadata found, proceed with normal deserialization
99
            return $fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
100
        }
101
102
        $dataContainer = $data->getDataContainer();
103
104
        $doctrineObjectEngine = $this->getDoctrineObjectEngine();
105
        $dataContainerId = $dataContainer->getId();
106
        if (!array_key_exists($dataContainerId, $this->finishedDataContainerId)) {
107
            $doctrineObjectEngine->import($dataContainer, $metadata->name, $objectManager);
108
            $objectManager->flush();
109
            $this->finishedDataContainerId[$dataContainerId] = $dataContainerId;
110
        }
111
112
        $entity = $data->getEntity();
113
114
        return $doctrineObjectEngine->getDoctrineEntityByDataContainer($entity);
115
    }
116
117
    /**
118
     * Возвращает хранилище ObjectManager'ов Doctrine
119
     *
120
     * @return ManagerRegistry
121
     */
122
    public function getManagerRegistry()
123
    {
124
        return $this->managerRegistry;
125
    }
126
127
    /**
128
     * Устанавливает хранилище ObjectManager'ов Doctrine
129
     *
130
     * @param ManagerRegistry $managerRegistry
131
     *
132
     * @return $this
133
     */
134
    public function setManagerRegistry(ManagerRegistry $managerRegistry)
135
    {
136
        $this->managerRegistry = $managerRegistry;
137
138
        return $this;
139
    }
140
141
    /**
142
     * Возвращает конструктор объектов которому делегируется создание объекта из данных, в случае если данные не
143
     * подходят для данного конструктора
144
     *
145
     * @return ObjectConstructorInterface
146
     */
147
    public function getFallbackConstructor()
148
    {
149
        return $this->fallbackConstructor;
150
    }
151
152
    /**
153
     * Устанавливает конструктор объектов которому делегируется создание объекта из данных, в случае если данные не
154
     * подходят для данного конструктора
155
     *
156
     * @param ObjectConstructorInterface $fallbackConstructor
157
     *
158
     * @return $this
159
     */
160
    public function setFallbackConstructor($fallbackConstructor)
161
    {
162
        $this->fallbackConstructor = $fallbackConstructor;
163
164
        return $this;
165
    }
166
167
    /**
168
     * Возвращает движок для создания объектов доктрины
169
     *
170
     * @return DoctrineObjectEngineInterface
171
     */
172
    public function getDoctrineObjectEngine()
173
    {
174
        return $this->doctrineObjectEngine;
175
    }
176
177
    /**
178
     * Устанавливает движок для создания объектов доктрины
179
     *
180
     * @param DoctrineObjectEngineInterface $doctrineObjectEngine
181
     *
182
     * @return $this
183
     */
184
    public function setDoctrineObjectEngine(DoctrineObjectEngineInterface $doctrineObjectEngine)
185
    {
186
        $this->doctrineObjectEngine = $doctrineObjectEngine;
187
188
        return $this;
189
    }
190
}
191