Completed
Push — master ( 306c06...2f0398 )
by
unknown
11s
created

DoctrineInsertUpdateLoader::processObject()   C

Complexity

Conditions 12
Paths 50

Size

Total Lines 52
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 12.0351

Importance

Changes 0
Metric Value
cc 12
eloc 32
nc 50
nop 1
dl 0
loc 52
ccs 30
cts 32
cp 0.9375
crap 12.0351
rs 6.9666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Smart\EtlBundle\Loader;
4
5
use Doctrine\ORM\EntityManager;
6
use Smart\EtlBundle\Entity\ImportableInterface;
7
use Smart\EtlBundle\Exception\Loader\EntityTypeNotHandledException;
8
use Smart\EtlBundle\Exception\Loader\EntityAlreadyRegisteredException;
9
use Symfony\Component\PropertyAccess\PropertyAccess;
10
use Symfony\Component\PropertyAccess\PropertyAccessor;
11
12
/**
13
 * Nicolas Bastien <[email protected]>
14
 */
15
class DoctrineInsertUpdateLoader implements LoaderInterface
16
{
17
    /**
18
     * @var EntityManager
19
     */
20
    protected $entityManager;
21
22
    /**
23
     * @var array
24
     */
25
    protected $references;
26
27
    /**
28
     * @var PropertyAccessor
29
     */
30
    protected $accessor;
31
32
    /**
33
     * List of entities to extract
34
     * [
35
     *      'class' => []
36
     * ]
37
     * @var array
38
     */
39
    protected $entitiesToProcess = [];
40
41 1
    public function __construct($entityManager)
42
    {
43 1
        $this->entityManager = $entityManager;
44 1
        $this->accessor = PropertyAccess::createPropertyAccessor();
45 1
    }
46
47
    /**
48
     * @param string $entityClass
49
     * @param function $identifierCallback
0 ignored issues
show
Bug introduced by
The type Smart\EtlBundle\Loader\function was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
50
     * @param string $identifierProperty : if null this entity will be always insert
51
     * @param array $entityProperties properties to synchronize
52
     * @return $this
53
     */
54 1
    public function addEntityToProcess($entityClass, $identifierCallback, $identifierProperty, array $entityProperties = [])
55
    {
56 1
        if (isset($this->entitiesToProcess[$entityClass])) {
57
            throw new EntityAlreadyRegisteredException($entityClass);
58
        }
59
60 1
        $this->entitiesToProcess[$entityClass] = [
61 1
            'class' => $entityClass,
62 1
            'callback' => $identifierCallback,
63 1
            'identifier' => $identifierProperty,
64 1
            'properties' => $entityProperties
65
        ];
66
67 1
        return $this;
68
    }
69
70
    /**
71
     * @inheritDoc
72
     */
73 1
    public function load(array $data)
74
    {
75 1
        $this->entityManager->beginTransaction();
76
        try {
77 1
            foreach ($data as $object) {
78 1
                $this->processObject($object);
79
            }
80 1
            $this->entityManager->flush();
81 1
            $this->entityManager->commit();
82
        } catch (\Exception $e) {
83
            var_dump('EXCEPTION LOADER : ' . $e->getMessage());
0 ignored issues
show
Security Debugging Code introduced by
var_dump('EXCEPTION LOAD...: ' . $e->getMessage()) looks like debug code. Are you sure you do not want to remove it?
Loading history...
84
            $this->entityManager->rollback();
85
        }
86 1
    }
87
88
    /**
89
     * @param  ImportableInterface $object
90
     * @return ImportableInterface
91
     * @throws \Exception
92
     * @throws \TypeError
93
     */
94 1
    protected function processObject($object)
95
    {
96 1
        if (!isset($this->entitiesToProcess[get_class($object)])) {
97
            throw new EntityTypeNotHandledException(get_class($object));
98
        }
99 1
        $identifier = $this->entitiesToProcess[get_class($object)]['callback']($object);
100
101
        //Replace relations by their reference
102 1
        foreach ($this->entitiesToProcess[get_class($object)]['properties'] as $property) {
103 1
            $propertyValue = $this->accessor->getValue($object, $property);
104 1
            if ($this->isEntityRelation($propertyValue)) {
105 1
                $relation = $propertyValue; //better understanding
106
107 1
                if (!isset($this->entitiesToProcess[get_class($relation)])) {
108
                    throw new EntityTypeNotHandledException(get_class($relation));
109
                }
110 1
                $relationIdentifier = $this->entitiesToProcess[get_class($relation)]['callback']($relation);
111 1
                if (!isset($this->references[$relationIdentifier])) {
112
                    //new relation should be processed before
113 1
                    $this->processObject($relation);
114
                }
115 1
                $this->accessor->setValue(
116 1
                    $object,
117 1
                    $property,
118 1
                    $this->references[$relationIdentifier]
119
                );
120
            }
121
        }
122
123 1
        $dbObject = null;
124 1
        if (!is_null($this->entitiesToProcess[get_class($object)]['identifier'])) {
125 1
            $dbObject = $this->entityManager->getRepository(get_class($object))->findOneBy([$this->entitiesToProcess[get_class($object)]['identifier'] => $identifier]);
126
        }
127 1
        if ($dbObject === null) {
128 1
            if (!$object->isImported()) {
129 1
                $object->setImportedAt(new \DateTime());
130
            }
131 1
            $this->entityManager->persist($object);
132 1
            if (!is_null($identifier)) {
133 1
                $this->references[$identifier] = $object;
134
            }
135
        } else {
136 1
            foreach ($this->entitiesToProcess[get_class($object)]['properties'] as $property) {
137 1
                $this->accessor->setValue($dbObject, $property, $this->accessor->getValue($object, $property));
138
            }
139 1
            if (!$dbObject->isImported()) {
140 1
                $dbObject->setImportedAt(new \DateTime());
141
            }
142 1
            $this->references[$identifier] = $dbObject;
143
        }
144
145 1
        return $object;
146
    }
147
148
    /**
149
     * Check if $propertyValue is an entity relation to process
150
     *
151
     * @param  mixed $propertyValue
152
     * @return bool
153
     */
154 1
    protected function isEntityRelation($propertyValue)
155
    {
156 1
        return (is_object($propertyValue) && !($propertyValue instanceof \DateTime));
157
    }
158
}
159