Completed
Push — master ( 99d468...d88042 )
by Nicolas
15s queued 11s
created

DoctrineInsertUpdateLoader::addEntityToProcess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 8
cts 9
cp 0.8889
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 4
crap 2.0054
1
<?php
2
3
namespace Smart\EtlBundle\Loader;
4
5
use Doctrine\ORM\EntityManager;
6
use Smart\EtlBundle\Exception\Loader\EntityTypeNotHandledException;
7
use Smart\EtlBundle\Exception\Loader\EntityAlreadyRegisteredException;
8
use Symfony\Component\PropertyAccess\PropertyAccess;
9
use Symfony\Component\PropertyAccess\PropertyAccessor;
10
11
/**
12
 * Nicolas Bastien <[email protected]>
13
 */
14
class DoctrineInsertUpdateLoader implements LoaderInterface
15
{
16
    /**
17
     * @var EntityManager
18
     */
19
    protected $entityManager;
20
21
    /**
22
     * @var array
23
     */
24
    protected $references;
25
26
    /**
27
     * @var PropertyAccessor
28
     */
29
    protected $accessor;
30
31
    /**
32
     * List of entities to extract
33
     * [
34
     *      'class' => []
35
     * ]
36
     * @var array
37
     */
38
    protected $entitiesToProcess = [];
39
    
40 1
    public function __construct($entityManager)
41
    {
42 1
        $this->entityManager = $entityManager;
43 1
        $this->accessor = PropertyAccess::createPropertyAccessor();
44 1
    }
45
46
    /**
47
     * @param string $entityClass
48
     * @param function $identifierCallback
49
     * @param string $identifierProperty
50
     * @param array $entityProperties properties to synchronize
51
     * @return $this
52
     */
53 1
    public function addEntityToProcess($entityClass, $identifierCallback, $identifierProperty, array $entityProperties)
54
    {
55 1
        if (isset($this->entitiesToProcess[$entityClass])) {
56
            throw new EntityAlreadyRegisteredException($entityClass);
57
        }
58
59 1
        $this->entitiesToProcess[$entityClass] = [
60 1
            'class' => $entityClass,
61 1
            'callback' => $identifierCallback,
62 1
            'identifier' => $identifierProperty,
63 1
            'properties' => $entityProperties
64
        ];
65
66 1
        return $this;
67
    }
68
69 1
    public function load(array $data)
70
    {
71 1
        $this->entityManager->beginTransaction();
72
        try {
73 1
            foreach ($data as $object) {
74 1
                $this->processObject($object);
75
            }
76 1
            $this->entityManager->flush();
77 1
            $this->entityManager->commit();
78
        } catch (\Exception $e) {
79
            var_dump($e->getMessage());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($e->getMessage()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
80
            $this->entityManager->rollback();
81
        }
82 1
    }
83
84
    /**
85
     * @param  mixed $object
86
     * @return mixed
87
     * @throws \Exception
88
     * @throws \TypeError
89
     */
90 1
    protected function processObject($object)
91
    {
92 1
        if (!isset($this->entitiesToProcess[get_class($object)])) {
93
            throw new EntityTypeNotHandledException(get_class($object));
94
        }
95 1
        $identifier = $this->entitiesToProcess[get_class($object)]['callback']($object);
96
        
97
        //Replace relations by their reference
98 1
        foreach ($this->entitiesToProcess[get_class($object)]['properties'] as $property) {
99 1
            if (is_object($this->accessor->getValue($object, $property))) {
100 1
                $relation = $this->accessor->getValue($object, $property);
101
102 1
                if (!isset($this->entitiesToProcess[get_class($relation)])) {
103
                    throw new EntityTypeNotHandledException(get_class($relation));
104
                }
105 1
                $relationIdentifier = $this->entitiesToProcess[get_class($relation)]['callback']($relation);
106 1
                $this->accessor->setValue(
107 1
                    $object,
108 1
                    $property,
109 1
                    $this->references[$relationIdentifier]
110
                );
111
            }
112
        }
113
114 1
        $dbObject = $this->entityManager->getRepository(get_class($object))->findOneBy([
115 1
            $this->entitiesToProcess[get_class($object)]['identifier'] => $identifier
116
        ]);
117 1
        if ($dbObject === null) {
118 1
            $this->entityManager->persist($object);
119 1
            $this->references[$identifier] = $object;
120
        } else {
121 1
            foreach ($this->entitiesToProcess[get_class($object)]['properties'] as $property) {
122 1
                $this->accessor->setValue($dbObject, $property, $this->accessor->getValue($object, $property));
123
            }
124 1
            $this->references[$identifier] = $dbObject;
125
        }
126
127 1
        return $object;
128
    }
129
}
130