Projekt

Obecné

Profil

Stáhnout (11.1 KB) Statistiky
| Větev: | Tag: | Revize:
1
<?php
2

    
3

    
4
namespace App\Model\Facade;
5

    
6

    
7
use App\AdminModule\Components\TransliterationNewForm;
8
use App\Enum\EFlashMessage;
9
use App\Model\Repository\BookRepository;
10
use App\Model\Repository\LineRepository;
11
use App\Model\Repository\LitReferenceRepository;
12
use App\Model\Repository\ObjectTypeRepository;
13
use App\Model\Repository\SurfaceRepository;
14
use App\Model\Repository\SurfaceTypeRepository;
15
use App\Model\Repository\TransliterationRepository;
16
use Nette\Application\UI\Form;
17
use Nette\Database\Context;
18
use Nette\Database\Table\ActiveRow;
19
use Nette\Utils\ArrayHash;
20
use Tracy\Debugger;
21

    
22
class TransliterationFacade
23
{
24
    /**
25
     * @var SurfaceRepository
26
     */
27
    private $surfaceRepository;
28
    /**
29
     * @var LineRepository
30
     */
31
    private $lineRepository;
32
    /**
33
     * @var ObjectTypeRepository
34
     */
35
    private $objectTypeRepository;
36
    /**
37
     * @var SurfaceTypeRepository
38
     */
39
    private $surfaceTypeRepository;
40
    /**
41
     * @var Context
42
     */
43
    private $context;
44
    /**
45
     * @var TransliterationRepository
46
     */
47
    private $transliterationRepository;
48
    /**
49
     * @var LitReferenceRepository
50
     */
51
    private $litReferenceRepository;
52
    /**
53
     * @var BookFacade
54
     */
55
    private $bookFacade;
56

    
57
    public function __construct(SurfaceRepository $surfaceRepository,
58
                                LineRepository $lineRepository,
59
                                ObjectTypeRepository $objectTypeRepository,
60
                                SurfaceTypeRepository $surfaceTypeRepository,
61
                                TransliterationRepository $transliterationRepository,
62
                                LitReferenceRepository $litReferenceRepository,
63
                                Context $context,
64
                                BookFacade $bookFacade
65
    )
66
    {
67
        $this->surfaceRepository = $surfaceRepository;
68
        $this->lineRepository = $lineRepository;
69
        $this->objectTypeRepository = $objectTypeRepository;
70
        $this->surfaceTypeRepository = $surfaceTypeRepository;
71
        $this->context = $context;
72
        $this->transliterationRepository = $transliterationRepository;
73
        $this->litReferenceRepository = $litReferenceRepository;
74
        $this->bookFacade = $bookFacade;
75
    }
76

    
77
    /**
78
     * Vložení nové transliterace do databáze
79
     *
80
     * @param \App\Utils\Form $form
81
     * @return bool|void
82
     */
83
    public function saveNewTransliteration(\App\Utils\Form $form)
84
    {
85
        $data = $form->getValues();
86
        $transliteration = $this->saveTransliterationInfo($form);
87

    
88
        if ($data['bookContainer']['book'] == TransliterationNewForm::BOOK_EXISTING)
89
        {
90
            $bookId = $data['bookContainer'][BookRepository::COLUMN_ID];
91
        } else
92
        {
93
            $book = $this->bookFacade->saveBook($form);
94
            $bookId = $book[BookRepository::COLUMN_ID];
95
        }
96

    
97
        $transliteration->update([TransliterationRepository::COLUMN_BOOK_ID => $bookId]);
98

    
99
        if ($transliteration == null)
100
        {
101
            return FALSE;
102
        }
103

    
104
        $result = $this->saveTransliterationData($transliteration[TransliterationRepository::COLUMN_ID], $form);
105
        return $result;
106
    }
107

    
108
    /**
109
     * Uložení informací o transliteraci do databáze
110
     *
111
     * @param Form $form
112
     * @param int|null $id
113
     * @return ActiveRow|null
114
     */
115
    public function saveTransliterationInfo(Form $form, int $id = null)
116
    {
117
        $formValues = $form->getValues();
118
        $formValues = isset($formValues['infoContainer']) ? $formValues['infoContainer'] : $formValues;
119

    
120
        $references = $formValues['references'];
121
        unset($formValues['references']);
122

    
123
        $newTransliteration = $this->transliterationRepository->save($formValues, $id);
124

    
125
        if ($id != null)
126
        {
127
            $this->deleteRemovedReferences($references, $id);
128
        } else
129
        {
130
            $id = $newTransliteration[TransliterationRepository::COLUMN_ID];
131
        }
132

    
133
        foreach ($references as $item)
134
        {
135
            $item[LitReferenceRepository::COLUMN_TRANSLITERATION_ID] = $id;
136
            $this->litReferenceRepository->save($item, (int)$item[LitReferenceRepository::COLUMN_ID]);
137
        }
138

    
139
        return $newTransliteration;
140
    }
141

    
142
    /**
143
     * Zkontroluje jestli není nějaká refence prázdná
144
     *
145
     * @param $references array referencí
146
     * @return bool
147
     */
148
    public function isAnyReferenceEmpty($references)
149
    {
150
        foreach ($references as $r)
151
        {
152
            if (empty($r[LitReferenceRepository::COLUMN_SERIES]) && empty($r[LitReferenceRepository::COLUMN_NUMBER])
153
                && empty($r[LitReferenceRepository::COLUMN_PLATE]))
154
            {
155
                return true;
156
            }
157
        }
158
        return false;
159
    }
160

    
161
    /**
162
     * Odstraní odebrané reference transliterace
163
     *
164
     * @param $newReferences array nových transliterací
165
     */
166
    public function deleteRemovedReferences($newReferences, $id)
167
    {
168
        $references = $this->litReferenceRepository->findByTransliterationId($id);
169

    
170
        foreach ($references as $ref)
171
        {
172
            if ($this->isRemovedReference($ref, $newReferences))
173
            {
174
                $this->litReferenceRepository->delete($ref[LitReferenceRepository::COLUMN_ID]);
175
            }
176
        }
177

    
178
    }
179

    
180
    /**
181
     * Zkontroluje jestli je refence v poli referencí
182
     *
183
     * @param $reference ActiveRow reference ke kontrole
184
     * @param $newReferences array pole referencí
185
     * @return bool
186
     */
187
    public function isRemovedReference($reference, $newReferences)
188
    {
189
        foreach ($newReferences as $ref)
190
        {
191
            if ($ref[LitReferenceRepository::COLUMN_ID] == $reference[LitReferenceRepository::COLUMN_ID])
192
            {
193
                return false;
194
            }
195
        }
196
        return true;
197
    }
198

    
199
    /**
200
     * Uloží data transliterace
201
     *
202
     * @param int|null $id : ID transliterace
203
     * @param Form $form
204
     * @return int $id : Vrací ID transliterace
205
     */
206
    public function saveTransliterationData(int $id, Form $form): int
207
    {
208
        $formValues = $form->getValues();
209
        $formValues = isset($formValues['dataContainer']) ? $formValues['dataContainer'] : $formValues;
210

    
211
        $this->removeDeletedLines($id, $formValues);
212

    
213
        // Škaredý zanoření hodnot z formuláře v kontainerech :(
214
        foreach ($formValues as $objectTypeId => $surfaceContainers)
215
        {
216
            foreach ($surfaceContainers as $surfaceTypeId => $inputs)
217
            {
218
                foreach ($inputs as $key => $values)
219
                {
220
                    try
221
                    {
222
                        $lineId = (int)$values->{LineRepository::COLUMN_ID};
223

    
224
                        // Editace již existující řádky
225
                        if (!empty($lineId))
226
                        {
227
                            $this->lineRepository->fetchById($lineId)->update($values);
228

    
229
                        } else
230
                        {
231
                            unset($values->{LineRepository::COLUMN_ID});
232

    
233
                            $surface = $this->surfaceRepository->fetchSurface($id, $objectTypeId, $surfaceTypeId);
234

    
235
                            if ($surface === FALSE)
236
                            {
237
                                $surface = $this->surfaceRepository->insert(
238
                                    [
239
                                        SurfaceRepository::COLUMN_SURFACE_TYPE_ID => $surfaceTypeId,
240
                                        SurfaceRepository::COLUMN_OBJECT_TYPE_ID => $objectTypeId,
241
                                        SurfaceRepository::COLUMN_TRANSLITERATION_ID => $id
242
                                    ]
243
                                );
244
                            }
245

    
246
                            $surfaceId = $this->context->getInsertId(SurfaceRepository::TABLE_NAME);
247

    
248
                            $values->{LineRepository::COLUMN_SURFACE_ID} = !empty($surfaceId) ? $surfaceId : $surface->{SurfaceRepository::COLUMN_ID};
249

    
250
                            $this->lineRepository->insert($values);
251
                        }
252
                    } catch (\Exception $exception)
253
                    {
254
                        \Tracy\Debugger::log('Nepodařilo se uložit data transliterace. Chyba: ' . $exception->getMessage(), 'transliteration-facade');
255
                        return 0;
256
                    }
257
                }
258
            }
259
        }
260

    
261
        return $id;
262
    }
263

    
264
    /**
265
     * Vrací data transliterace pro formulář
266
     *
267
     * @param int $id : ID transliterace
268
     * @return array : pole výchozích hodnot pro formulář
269
     */
270
    public function getTransliterationData(int $id): array
271
    {
272
        $surfaces = $this->surfaceRepository->findByTransliterationId($id)->fetchAll();
273

    
274
        $defaults = array();
275

    
276
        /** @var ActiveRow $surface */
277
        foreach ($surfaces as $surface)
278
        {
279
            // Načtení všech řádek
280
            $lineRows = $surface->related(LineRepository::TABLE_NAME, SurfaceRepository::COLUMN_ID)->fetchAll();
281
            if ($lineRows === FALSE || empty($lineRows))
282
            {
283
                continue;
284
            }
285

    
286
            $objectId = $surface->{SurfaceRepository::COLUMN_OBJECT_TYPE_ID};
287
            $surfaceId = $surface->{SurfaceRepository::COLUMN_SURFACE_TYPE_ID};
288

    
289
            $defaults[$objectId][$surfaceId] = $lineRows;
290
        }
291

    
292
        return $defaults;
293
    }
294

    
295
    /**
296
     * Odstraní smazané řádky z DB
297
     *
298
     * @param int $id : ID transliterace
299
     * @param ArrayHash $formValues : hodnoty z formuláře
300
     * @return int : počet smazaných řádek
301
     */
302
    public function removeDeletedLines(int $id, ArrayHash $formValues)
303
    {
304
        $deletedIds = $this->getDeletedLineIds($id, $formValues);
305

    
306
        return $this->lineRepository->deleteLines($deletedIds);
307
    }
308

    
309
    /**
310
     * Vrací ID smazaných řádek transliterace
311
     *
312
     * @param int $id : ID transliterace
313
     * @param ArrayHash $formValues : hodnoty z formuláře
314
     * @return array
315
     */
316
    private function getDeletedLineIds(int $id, ArrayHash $formValues)
317
    {
318
        $deletedIds = [];
319
        $oldLines = $this->getTransliterationData($id);
320

    
321
        // Tohle je fakt nádhera :(
322
        foreach ($oldLines as $objectTypeId => $surfaceContainers)
323
        {
324
            foreach ($surfaceContainers as $surfaceTypeId => $activeRows)
325
            {
326
                foreach ($activeRows as $activeRow)
327
                {
328
                    if (isset($formValues[$objectTypeId][$surfaceTypeId]))
329
                    {
330
                        $oldLineFound = FALSE;
331
                        foreach ($formValues[$objectTypeId][$surfaceTypeId] as $array)
332
                        {
333
                            if ($array[LineRepository::COLUMN_ID] == $activeRow->{LineRepository::COLUMN_ID})
334
                            {
335
                                $oldLineFound = TRUE;
336
                                break;
337
                            }
338
                        }
339

    
340
                        if (!$oldLineFound)
341
                        {
342
                            $deletedIds[] = $activeRow->{LineRepository::COLUMN_ID};
343
                        }
344
                    }
345
                }
346
            }
347
        }
348

    
349
        return $deletedIds;
350
    }
351
}
(2-2/4)