Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 21
CRAP
0.00% covered (danger)
0.00%
0 / 1
Base
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 21
1560
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 getPDOAccess
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCurrentEntitys
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIterator
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 removeEntityFromCurrentList
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCurrentEntitys
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
30
 createMetaObject
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 getMetaObject
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 saveMetaObject
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 needsUpdate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 setImportData
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setLocale
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getLocale
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setImportHash
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getImportHash
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEntityClass
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 createEntity
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 clearEntity
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
42
 preImport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 postImport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 runImport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
1<?php
2
3namespace BO\Zmsdldb\Importer\MySQL;
4
5use BO\Zmsdldb\PDOAccess;
6use BO\Zmsdldb\Importer\OptionsTrait;
7use BO\Zmsdldb\Importer\PDOTrait;
8use BO\Zmsdldb\Importer\Options;
9use BO\Zmsdldb\Importer\MySQL\Entity\Meta as MetaEntity;
10use BO\Zmsdldb\Importer\MySQL\Entity\Base as EntityBase;
11
12abstract class Base implements Options
13{
14    use PDOTrait;
15    use OptionsTrait;
16
17    /** @var class-string<EntityBase>|null */
18    protected ?string $entityClass = null;
19    protected array $importData = [];
20    protected string $hash = '';
21    protected string $locale = 'de';
22    protected ?MetaEntity $metaObject = null;
23    /** @var array<int, EntityBase> */
24    protected array $entitysToDelete = [];
25    protected bool $getCurrentEntitys = true;
26
27    public function __construct(PDOAccess $mySqlAccess, array $importData = [], string $locale = 'de', int $options = 0)
28    {
29        try {
30            $this->setPDOAccess($mySqlAccess);
31            $data = $importData['data'] ?? [];
32            $hash = $importData['hash'] ?? '';
33            if (!is_array($data)) {
34                throw new \InvalidArgumentException('Import data must be an array');
35            }
36            if (!is_string($hash)) {
37                throw new \InvalidArgumentException('Import hash must be a string');
38            }
39            $this->setImportData($data);
40            $this->setImportHash($hash);
41            $this->setLocale($locale);
42
43            $this->setOptions($options);
44            $this->clearEntity();
45        } catch (\Exception $e) {
46            throw $e;
47        }
48    }
49
50    public function getPDOAccess(): PDOAccess
51    {
52        return $this->pdoAccess;
53    }
54
55    /**
56     * @return array<int, EntityBase>
57     */
58    public function getCurrentEntitys(): array
59    {
60        return $this->entitysToDelete;
61    }
62
63    public function getIterator(): iterable
64    {
65        foreach ($this->importData as $item) {
66            yield $item;
67        }
68    }
69
70    public function removeEntityFromCurrentList(int $entityId): void
71    {
72        unset($this->entitysToDelete[$entityId]);
73    }
74
75    public function setCurrentEntitys(): void
76    {
77        try {
78            if (false === $this->getCurrentEntitys) {
79                return;
80            }
81            $this->entitysToDelete = [];
82            $entityClass = $this->getEntityClass();
83            $sql = "SELECT 
84            m.object_id AS id, 
85            e.data_json AS data_json 
86            FROM meta AS m
87            JOIN " . $entityClass::getTableName() . " AS e ON e.id = m.object_id AND e.locale = ?
88            WHERE m.locale = ?";
89
90
91            $stm = $this->getPDOAccess()->prepare($sql);
92            $stm->setFetchMode(\PDO::FETCH_OBJ);
93            $stm->execute([$this->getLocale(),$this->getLocale()]);
94            $entitys = $stm->fetchAll();
95            foreach ($entitys as $entity) {
96                $decoded = json_decode($entity->data_json, true);
97                if (!is_array($decoded)) {
98                    continue;
99                }
100                $entityObject = $this->createEntity($decoded);
101                $this->entitysToDelete[(int) $entity->id] = $entityObject;
102            }
103        } catch (\Exception $e) {
104            throw $e;
105        }
106    }
107
108    public function createMetaObject(): void
109    {
110        try {
111            if (empty($this->metaObject)) {
112                $entityClass = $this->getEntityClass();
113                $metaObject = new MetaEntity(
114                    $this->getPDOAccess(),
115                    [
116                        'object_id' => 0,
117                        'locale' => $this->getLocale(),
118                        'hash' => $this->getImportHash(),
119                        'type' => $entityClass::getTableName()
120                    ]
121                );
122                $this->metaObject = $metaObject;
123            }
124        } catch (\Exception $e) {
125            throw $e;
126        }
127    }
128
129    public function getMetaObject(): MetaEntity
130    {
131        $this->createMetaObject();
132        if (null === $this->metaObject) {
133            throw new \RuntimeException('Failed to create meta object');
134        }
135        return $this->metaObject;
136    }
137
138    public function saveMetaObject(): self
139    {
140        $this->getMetaObject()->save();
141        return $this;
142    }
143
144    public function needsUpdate(): bool
145    {
146        $metaObject = $this->getMetaObject();
147        $needsUpdate = $metaObject->itemNeedsUpdateAlt();
148        if ($needsUpdate) {
149            $this->setCurrentEntitys();
150        }
151        return $needsUpdate;
152    }
153
154    public function setImportData(array $importData = []): self
155    {
156        $this->importData = $importData;
157        return $this;
158    }
159
160    public function setLocale(string $locale): self
161    {
162        $this->locale = $locale;
163        return $this;
164    }
165
166    public function getLocale(): string
167    {
168        return $this->locale;
169    }
170
171    public function setImportHash(string $hash): self
172    {
173        $this->hash = $hash;
174        return $this;
175    }
176
177    public function getImportHash(): string
178    {
179        return $this->hash;
180    }
181
182    /**
183     * @return class-string<EntityBase>
184     */
185    protected function getEntityClass(): string
186    {
187        if (null === $this->entityClass) {
188            throw new \InvalidArgumentException(__METHOD__ . " invalid entity class");
189        }
190        return $this->entityClass;
191    }
192
193    public function createEntity(array $data = array(), bool $setup = true): EntityBase
194    {
195        $entityClass = $this->getEntityClass();
196        /** @psalm-suppress UnsafeInstantiation */
197        $entity = new $entityClass($this->getPDOAccess(), $data, $setup);
198        if (!$entity instanceof EntityBase) {
199            throw new \InvalidArgumentException($entityClass . ' must extend ' . EntityBase::class);
200        }
201        return $entity;
202    }
203
204    final public function clearEntity(): void
205    {
206        try {
207            if (
208                !$this->checkOptionFlag(static::OPTION_CLEAR_ENTITIY_TABLE) &&
209                !$this->checkOptionFlag(static::OPTION_CLEAR_ENTITIY_REFERENCES_TABLES)
210            ) {
211                return;
212            }
213            $entity = $this->createEntity(['meta' => ['locale' => $this->getLocale()]], false);
214            if ($this->checkOptionFlag(static::OPTION_CLEAR_ENTITIY_TABLE)) {
215                $entity->clearEntity();
216            }
217            if ($this->checkOptionFlag(static::OPTION_CLEAR_ENTITIY_REFERENCES_TABLES)) {
218                $entity->clearEntityReferences();
219            }
220        } catch (\Exception $e) {
221            throw $e;
222        }
223    }
224
225    /** @psalm-api */
226    public function preImport(): void
227    {
228    }
229
230    /** @psalm-api */
231    public function postImport(): void
232    {
233    }
234
235    /** @psalm-api */
236    abstract public function runImport(): bool;
237}