Completed
Pull Request — master (#4)
by Nicolas
04:12
created

YamlEntityExtractor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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