Passed
Pull Request — master (#19)
by Nicolas
03:07
created

DoctrineEntityExtractor::setEntityToExtract()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
ccs 0
cts 5
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Smart\EtlBundle\Extractor;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\ORM\QueryBuilder;
8
use Smart\EtlBundle\Entity\ImportableInterface;
9
use Smart\EtlBundle\Exception\Extractor\EntityTypeNotHandledException;
10
use Symfony\Component\PropertyAccess\PropertyAccess;
11
use Symfony\Component\PropertyAccess\PropertyAccessor;
12
13
/**
14
 * Nicolas Bastien <[email protected]>
15
 */
16
class DoctrineEntityExtractor extends AbstractExtractor implements ExtractorInterface
17
{
18
    /**
19
     * @var EntityManager
20
     */
21
    protected $entityManager;
22
23
    /**
24
     * @var PropertyAccessor
25
     */
26
    protected $accessor;
27
28
    /**
29
     * @var string
30
     */
31
    protected $entityToExtract;
32
33
    /**
34
     * @var array
35
     */
36
    protected $propertiesToExtract;
37
38
    /**
39
     * @var QueryBuilder
40
     */
41
    protected $queryBuilder = null;
42
43
    public function __construct($entityManager)
44
    {
45
        $this->entityManager = $entityManager;
46
        $this->accessor = PropertyAccess::createPropertyAccessor();
47
    }
48
49
    /**
50
     * @param string $entityToExtract
51
     */
52
    public function setEntityToExtract($entityToExtract, array $propertiesToExtract)
53
    {
54
        $this->entityToExtract = $entityToExtract;
55
        $this->propertiesToExtract = $propertiesToExtract;
56
        $this->queryBuilder = null;
57
    }
58
59
    /**
60
     * @return QueryBuilder
61
     */
62
    public function getQueryBuilder()
63
    {
64
        if ($this->queryBuilder instanceof QueryBuilder) {
0 ignored issues
show
introduced by
$this->queryBuilder is always a sub-type of Doctrine\ORM\QueryBuilder.
Loading history...
65
            return $this->queryBuilder;
66
        }
67
        $repository = $this->entityManager->getRepository($this->entityToExtract);
68
        if (!$repository instanceof EntityRepository) {
69
            throw new \UnexpectedValueException("No repository found for class {$this->entityToExtract}");
70
        }
71
        $this->queryBuilder = $repository->createQueryBuilder('o');
72
73
        if ($this->queryBuilder === null) {
74
            throw new \BadMethodCallException('Invalid entityToExtract');
75
        }
76
77
        return $this->queryBuilder;
78
    }
79
80
    /**
81
     * @param QueryBuilder $queryBuilder
82
     */
83
    public function setQueryBuilder(QueryBuilder $queryBuilder)
84
    {
85
        $this->queryBuilder = $queryBuilder;
86
    }
87
88
    /**
89
     * @inheritdoc
90
     */
91
    public function extract()
92
    {
93
        $entities = $this->getQueryBuilder()->getQuery()->getResult();
94
95
        $toReturn = [];
96
        //Replace relation references
97
        foreach ($entities as $key => $entity) {
98
            if (!$entity instanceof ImportableInterface) {
99
                throw new EntityTypeNotHandledException(get_class($entity));
100
            }
101
            $entityData = [];
102
            foreach ($this->propertiesToExtract as $property) {
103
                $value = $this->accessor->getValue($entity, $property);
104
105
                if ($this->isEntityRelation($value)) {
106
                    if (!$value instanceof ImportableInterface) {
107
                        throw new EntityTypeNotHandledException(get_class($value));
108
                    }
109
                    $entityData[$property] = '@' . $value->getImportId();
110
                } else {
111
                    $entityData[$property] = $value;
112
                }
113
            }
114
            $toReturn[$entity->getImportId()] = $entityData;
115
        }
116
117
        return $toReturn;
118
    }
119
120
    /**
121
     * Check if $propertyValue is an entity relation to process
122
     *
123
     * @param  mixed $propertyValue
124
     * @return bool
125
     */
126
    protected function isEntityRelation($propertyValue)
127
    {
128
        return (is_object($propertyValue) && !($propertyValue instanceof \DateTime));
129
    }
130
}
131