Passed
Pull Request — master (#30)
by Mathieu
02:14
created

DiffGenerator::__construct()   A

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
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Smart\EtlBundle\Generator;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Symfony\Component\PropertyAccess\PropertyAccess;
7
use Symfony\Component\PropertyAccess\PropertyAccessor;
8
9
/**
10
 * @author Mathieu Ducrot <[email protected]>
11
 *
12
 * The DiffGenerator class is responsible for comparing a raw data with data pulled from the manager on the entity and
13
 * generating a diff preview with the changes needed to migrate from one data to the other.
14
 */
15
class DiffGenerator
16
{
17
    protected EntityManagerInterface $entityManager;
18
19
    protected PropertyAccessor $accessor;
20
21
    public function __construct(EntityManagerInterface $entityManager)
22
    {
23
        $this->entityManager = $entityManager;
24
        $this->accessor = PropertyAccess::createPropertyAccessor();
25
    }
26
27
    /**
28
     * @param array $multiArrayData multidimensional array data containing one entity data per row
29
     */
30
    public function generateDiffs(string $entityClass, array $multiArrayData)
31
    {
32
        $toReturn = [];
33
        if ($multiArrayData === []) {
34
            return $toReturn;
35
        }
36
37
        // todo amélioration en récupérant uniquement ceux dont l'identifier match ceux présent dans $data
38
        $identifier = array_keys($multiArrayData[0])[0];
39
        $entitiesFromDb = $this->entityManager->getRepository($entityClass)
40
            ->createQueryBuilder('o', "o.$identifier")
41
            ->getQuery()
42
            ->getResult()
43
        ;
44
45
        foreach ($multiArrayData as $key => $row) {
46
            $toReturn[$key] = $this->generateDiff(
47
                $entitiesFromDb[reset($row)] ?? null,
48
                $row
49
            );
50
        }
51
52
        return $toReturn;
53
    }
54
55
    /**
56
     * @param mixed $entity
57
     */
58
    public function generateDiff($entity, array $data): array
59
    {
60
        $isNew = ($entity === null);
61
        $toReturn['diff_type'] = 'new';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$toReturn was never initialized. Although not strictly required by PHP, it is generally a good practice to add $toReturn = array(); before regardless.
Loading history...
62
63
        $hasDataChange = false;
64
        foreach ($data as $property => $value) {
65
            $toReturn['diff'][$property] = $value;
66
67
            if (!$isNew) {
68
                $toReturn['diff_type'] = 'change';
69
70
                $originValue = $this->accessor->getValue($entity, $property);
71
                $hasChange = ($originValue != $value);
72
                $toReturn['diff'][$property] = [
73
                    'value' => $value,
74
                    'origin_value' => $originValue,
75
                    'has_change' => $hasChange,
76
                ];
77
78
                if ($hasChange) {
79
                    $hasDataChange = true;
80
                }
81
            }
82
        }
83
84
        if (!$isNew && !$hasDataChange) {
85
            $toReturn['diff_type'] = 'unchanged';
86
        }
87
88
        return $toReturn;
89
    }
90
}
91