Completed
Push — master ( 57351d...99d468 )
by Nicolas
15s queued 10s
created

YamlEntityExtractor::processFile()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 11
cts 11
cp 1
rs 9.7333
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4
1
<?php
2
3
namespace Smart\EtlBundle\Extractor;
4
5
use Smart\EtlBundle\Exception\Extractor\EntityAlreadyRegisteredException;
6
use Smart\EtlBundle\Exception\Extractor\EntityIdentifiedNotFoundException;
7
use Smart\EtlBundle\Exception\Extractor\EntityIdentifierAlreadyProcessedException;
8
use Symfony\Component\PropertyAccess\PropertyAccess;
9
use Symfony\Component\PropertyAccess\PropertyAccessor;
10
use Symfony\Component\Yaml\Yaml;
11
12
/**
13
 * Nicolas Bastien <[email protected]>
14
 */
15
class YamlEntityExtractor extends AbstractFolderExtrator implements ExtractorInterface
16
{
17
    /**
18
     * List of entities to extract
19
     * [
20
     *      'entity_code' => 'Model Classname'
21
     * ]
22
     * @var array
23
     */
24
    protected $entitiesToProcess = [];
25
26
    /**
27
     * @var array
28
     */
29
    protected $entities = [];
30
31
    /**
32
     * @var PropertyAccessor
33
     */
34
    protected $accessor;
35
36 4
    public function __construct()
37
    {
38 4
        $this->accessor = PropertyAccess::createPropertyAccessor();
39 4
    }
40
41
    /**
42
     * @param string $entityType
43
     * @param string$entityClass
44
     * @param function $identifierCallback
45
     * @return $this
46
     * @throws \Exception
47
     */
48 4
    public function addEntityToProcess($entityType, $entityClass, $identifierCallback)
49
    {
50 4
        if (isset($this->entitiesToProcess[$entityType])) {
51 1
            throw new EntityAlreadyRegisteredException($entityType);
52
        }
53
54 4
        $this->entitiesToProcess[$entityType] = [
55 4
            'type' => $entityType,
56 4
            'class' => $entityClass,
57 4
            'callback' => $identifierCallback
58
        ];
59
        
60 4
        return $this;
61
    }
62
63
    /**
64
     * @inheritDoc
65
     */
66 3
    public function extract()
67
    {
68
        try {
69 3
            $this->check();
70
            
71 3
            $files = $this->getFiles('yml');
72 3
            foreach ($this->entitiesToProcess as $entityType => $data) {
73 3
                if (!isset($files[$entityType])) {
74
                    continue;
75
                }
76 3
                $this->processFile($entityType);
77
            }
78
79 1
            return $this->entities;
80 2
        } catch (\Exception $e) {
81 2
            throw $e;
82
        }
83
    }
84
    
85 3
    protected function check()
86
    {
87 3
        parent::check();
88
        
89 3
        if (count($this->entitiesToProcess) === 0) {
90
            throw new \BadMethodCallException('Nothing to process');
91
        }
92 3
    }
93
94
    /**
95
     * @param $filename
96
     * @throws \Exception
97
     */
98 3
    protected function processFile($filename)
99
    {
100 3
        $filepath = sprintf('%s/%s.yml', $this->folderToExtract, $filename);
101
102 3
        $data = Yaml::parse(file_get_contents($filepath));
103 3
        foreach ($data as $values) {
104 3
            $object = $this->processObject($filename, $values);
105 2
            if ($object !== null) {
106 2
                $entityIdentifier = $this->entitiesToProcess[$filename]['callback']($object);
107 2
                if (isset($this->entities[$entityIdentifier])) {
108 1
                    throw new EntityIdentifierAlreadyProcessedException($entityIdentifier);
109
                }
110 2
                $this->entities[$entityIdentifier] = $object;
111
            }
112
        }
113 1
    }
114
115
    /**
116
     * @param string $entityType
117
     * @param array $data
118
     * @return mixed
119
     * @throws \Exception
120
     */
121 3
    protected function processObject($entityType, array $data)
122
    {
123 3
        if (!isset($this->entitiesToProcess[$entityType])) {
124
            throw new \Exception('Entity type ' . $entityType . ' is not handled');
125
        }
126
127 3
        $objectClass = $this->entitiesToProcess[$entityType]['class'];
128 3
        $object = new $objectClass();
129
130 3
        foreach ($data as $key => $value) {
131 3
            $valueToSet = $value;
132 3
            if (strpos($value, '@') === 0) {
133
                //handle relations
134 2
                $valueToSet = $this->getEntity($value);
135
            }
136
137 3
            $this->accessor->setValue($object, $key, $valueToSet);
138
        }
139
140 2
        return $object;
141
    }
142
143
    /**
144
     * @param string $identifier
145
     * @return mixed
146
     * @throws \Exception
147
     */
148 2
    protected function getEntity($identifier)
149
    {
150 2
        if (strpos($identifier, '@') === 0) {
151 2
            $identifier = substr($identifier, 1);
152
        }
153 2
        if (!isset($this->entities[$identifier])) {
154 1
            throw new EntityIdentifiedNotFoundException($identifier);
155
        }
156
157 1
        return $this->entities[$identifier];
158
    }
159
}
160