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

DiffGenerator   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 36
c 1
b 0
f 0
dl 0
loc 76
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A generateDiffs() 0 23 3
A generateDiff() 0 31 6
A __construct() 0 4 1
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
    /** @var EntityManagerInterface */
18
    protected $entityManager;
19
20
    /** @var PropertyAccessor */
21
    protected $accessor;
22
23
    public function __construct(EntityManagerInterface $entityManager)
24
    {
25
        $this->entityManager = $entityManager;
26
        $this->accessor = PropertyAccess::createPropertyAccessor();
27
    }
28
29
    /**
30
     * @param array $multiArrayData multidimensional array data containing one entity data per row
31
     */
32
    public function generateDiffs(string $entityClass, array $multiArrayData)
33
    {
34
        $toReturn = [];
35
        if ($multiArrayData === []) {
36
            return $toReturn;
37
        }
38
39
        // todo amélioration en récupérant uniquement ceux dont l'identifier match ceux présent dans $data
40
        $identifier = array_keys($multiArrayData[0])[0];
41
        $entitiesFromDb = $this->entityManager->getRepository($entityClass)
42
            ->createQueryBuilder('o', "o.$identifier")
43
            ->getQuery()
44
            ->getResult()
45
        ;
46
47
        foreach ($multiArrayData as $key => $row) {
48
            $toReturn[$key] = $this->generateDiff(
49
                $entitiesFromDb[reset($row)] ?? null,
50
                $row
51
            );
52
        }
53
54
        return $toReturn;
55
    }
56
57
    /**
58
     * @param mixed $entity
59
     */
60
    public function generateDiff($entity, array $data): array
61
    {
62
        $isNew = ($entity === null);
63
        $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...
64
65
        $hasDataChange = false;
66
        foreach ($data as $property => $value) {
67
            $toReturn['diff'][$property] = $value;
68
69
            if (!$isNew) {
70
                $toReturn['diff_type'] = 'change';
71
72
                $originValue = $this->accessor->getValue($entity, $property);
73
                $hasChange = ($originValue != $value);
74
                $toReturn['diff'][$property] = [
75
                    'value' => $value,
76
                    'origin_value' => $originValue,
77
                    'has_change' => $hasChange,
78
                ];
79
80
                if ($hasChange) {
81
                    $hasDataChange = true;
82
                }
83
            }
84
        }
85
86
        if (!$isNew && !$hasDataChange) {
87
            $toReturn['diff_type'] = 'unchanged';
88
        }
89
90
        return $toReturn;
91
    }
92
}
93