Completed
Push — master ( 2f0398...5c44ed )
by
unknown
13s
created

DoctrineEntityExtractor::getQueryBuilder()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.128

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 0
dl 0
loc 16
ccs 8
cts 10
cp 0.8
crap 4.128
rs 9.9666
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 1
    public function __construct($entityManager)
44
    {
45 1
        $this->entityManager = $entityManager;
46 1
        $this->accessor = PropertyAccess::createPropertyAccessor();
47 1
    }
48
49
    /**
50
     * @param string $entityToExtract
51
     */
52 1
    public function setEntityToExtract($entityToExtract, array $propertiesToExtract)
53
    {
54 1
        $this->entityToExtract = $entityToExtract;
55 1
        $this->propertiesToExtract = $propertiesToExtract;
56 1
        $this->queryBuilder = null;
57 1
    }
58
59
    /**
60
     * @return QueryBuilder
61
     */
62 1
    public function getQueryBuilder()
63
    {
64 1
        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 1
            return $this->queryBuilder;
66
        }
67 1
        $repository = $this->entityManager->getRepository($this->entityToExtract);
68 1
        if (!$repository instanceof EntityRepository) {
69
            throw new \UnexpectedValueException("No repository found for class {$this->entityToExtract}");
70
        }
71 1
        $this->queryBuilder = $repository->createQueryBuilder('o');
72
73 1
        if ($this->queryBuilder === null) {
74
            throw new \BadMethodCallException('Invalid entityToExtract');
75
        }
76
77 1
        return $this->queryBuilder;
78
    }
79
80
    /**
81
     * @param QueryBuilder $queryBuilder
82
     */
83 1
    public function setQueryBuilder(QueryBuilder $queryBuilder)
84
    {
85 1
        $this->queryBuilder = $queryBuilder;
86 1
    }
87
88
    /**
89
     * @inheritdoc
90
     */
91 1
    public function extract()
92
    {
93 1
        $entities = $this->getQueryBuilder()->getQuery()->getResult();
94
95 1
        $toReturn = [];
96
        //Replace relation references
97 1
        foreach ($entities as $key => $entity) {
98 1
            if (!$entity instanceof ImportableInterface) {
99
                throw new EntityTypeNotHandledException(get_class($entity));
100
            }
101 1
            $entityData = [];
102 1
            foreach ($this->propertiesToExtract as $property) {
103 1
                $value = $this->accessor->getValue($entity, $property);
104
105 1
                if ($this->isEntityRelation($value)) {
106 1
                    if (!$value instanceof ImportableInterface) {
107
                        throw new EntityTypeNotHandledException(get_class($value));
108
                    }
109 1
                    $entityData[$property] = '@' . $value->getImportId();
110 1
                } elseif ($value instanceof \Traversable) {
111 1
                    $entityData[$property] = [];
112 1
                    foreach ($value as $k => $v) {
113 1
                        if ($this->isEntityRelation($v)) {
114 1
                            if (!$v instanceof ImportableInterface) {
115
                                throw new EntityTypeNotHandledException(get_class($v));
116
                            }
117 1
                            $entityData[$property][$k] = '@' . $v->getImportId();
118
                        }
119
                    }
120
                } else {
121 1
                    $entityData[$property] = $value;
122
                }
123
            }
124 1
            $toReturn[$entity->getImportId()] = $entityData;
125
        }
126
127 1
        return $toReturn;
128
    }
129
130
    /**
131
     * Check if $propertyValue is an entity relation to process
132
     *
133
     * @param  mixed $propertyValue
134
     * @return bool
135
     */
136 1
    protected function isEntityRelation($propertyValue)
137
    {
138 1
        return (is_object($propertyValue) && !($propertyValue instanceof \DateTime) && !($propertyValue instanceof \Traversable));
139
    }
140
}
141