Completed
Pull Request — master (#499)
by
unknown
02:14
created

CalMigrationUpdate::getExceptionConfigurationForExceptionGroup()   B

Complexity

Conditions 8
Paths 34

Size

Total Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 75
rs 7.301
c 0
b 0
f 0
cc 8
nc 34
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * CalMigrationUpdate.
5
 */
6
declare(strict_types=1);
7
8
namespace HDNET\Calendarize\Updates;
9
10
use HDNET\Autoloader\Annotation\SignalClass;
11
use HDNET\Autoloader\Annotation\SignalName;
12
use HDNET\Calendarize\Service\IndexerService;
13
use HDNET\Calendarize\Utility\HelperUtility;
14
use TYPO3\CMS\Core\Database\ConnectionPool;
15
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
18
19
/**
20
 * CalMigrationUpdate.
21
 *
22
 * If using the slots please use the m with func_get_args!
23
 * Example:
24
 * /**
25
 *  * @SignalClass("HDNET\Calendarize\Updates\CalMigrationUpdate")
26
 *  * @SignalName("getCalendarizeEventUid")
27
 *
28
 *  *@return array
29
 *  *
30
 * public function getCalendarizeEventUid()
31
 * {
32
 *    $args = func_get_args();
33
 *    list($table, $dbQueries, $call) = $args;
34
 *
35
 *    $variables = [
36
 *        'table'     => self::EVENT_TABLE,
37
 *        'dbQueries' => $dbQueries
38
 *    ];
39
 *
40
 *    return $variables;
41
 * }
42
 */
43
class CalMigrationUpdate extends AbstractUpdate
44
{
45
    /**
46
     * Import prefix.
47
     */
48
    const IMPORT_PREFIX = 'calMigration:';
49
50
    /**
51
     * Event table.
52
     */
53
    const EVENT_TABLE = 'tx_calendarize_domain_model_event';
54
55
    /**
56
     * Configuration table.
57
     */
58
    const CONFIGURATION_TABLE = 'tx_calendarize_domain_model_configuration';
59
60
    /**
61
     * ConfigurationGroup table.
62
     */
63
    const CONFIGURATION_GROUP_TABLE = 'tx_calendarize_domain_model_configurationgroup';
64
65
    /**
66
     * The human-readable title of the upgrade wizard.
67
     *
68
     * @var string
69
     */
70
    protected $title = 'Migrate cal event structures to the new calendarize event structures.
71
    Try to migrate all cal information and place the new calendarize event models in the same folder
72
    as the cal-records. Please note: the migration will be create calendarize default models.';
73
74
    /**
75
     * Checks whether updates are required.
76
     *
77
     * @param string &$description The description for the update
78
     *
79
     * @return bool Whether an update is required (TRUE) or not (FALSE)
80
     */
81
    public function checkForUpdate(&$description)
82
    {
83
        $nonMigratedCalIds = $this->getNonMigratedCalIds();
84
        $count = \count($nonMigratedCalIds);
85
        if (0 === $count) {
86
            return false;
87
        }
88
        $description = 'There ' . ($count > 1 ? 'are ' . $count : 'is ' . $count) . ' non migrated EXT:cal event
89
        ' . ($count > 1 ? 's' : '') . '. Run the update process to migrate the events to EXT:calendarize events.';
90
91
        return true;
92
    }
93
94
    /**
95
     * Performs the accordant updates.
96
     *
97
     * @param array &$dbQueries      Queries done in this update
98
     * @param mixed &$customMessages Custom messages
99
     *
100
     * @return bool Whether everything went smoothly or not
101
     */
102
    public function executeUpdate(): bool
103
    {
104
        $calIds = $this->getNonMigratedCalIds();
105
        if (empty($calIds)) {
106
            return true;
107
        }
108
        $dbQueries = [];
109
110
        /**
111
         * @var bool
112
         */
113
        $calUsesSysCategories = $this->isCalWithSysCategories();
114
115
        if (!$calUsesSysCategories) {
116
            $this->performSysCategoryUpdate($calIds, $dbQueries, $customMessages);
117
        }
118
        $this->performSysFileReferenceUpdate($calIds, $dbQueries, $customMessages);
119
        $this->performExceptionEventUpdate($calIds, $dbQueries, $customMessages);
120
        $this->performCalEventUpdate($calIds, $dbQueries, $customMessages);
121
        if ($calUsesSysCategories) {
122
            $this->performLinkEventToSysCategory($calIds, $dbQueries, $customMessages);
123
        } else {
124
            $this->performLinkEventToCategory($calIds, $dbQueries, $customMessages);
125
        }
126
        $this->performLinkEventToConfigurationGroup($calIds, $dbQueries, $customMessages);
127
128
        return true;
129
    }
130
131
    /**
132
     * Check if cal is already using sys_category instead
133
     * of tx_cal_category. This affects the conversion of
134
     * categories and category / event relations.
135
     *
136
     * @return bool
137
     */
138
    protected function isCalWithSysCategories(): bool
139
    {
140
        $table = 'sys_category_record_mm';
141
142
        $db = HelperUtility::getDatabaseConnection($table);
143
        $q = $db->createQueryBuilder();
144
        $count = (int)$q->count('*')
145
            ->from($table)
146
            ->where(
147
                $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_event')),
148
                $q->expr()->eq('fieldname', $q->createNamedParameter('category_id'))
149
            )
150
            ->execute();
151
        return $count > 0;
152
    }
153
154
    /**
155
     * Perform CAL event update.
156
     *
157
     * @param       $calIds
158
     * @param array $dbQueries
159
     * @param       $customMessages
160
     *
161
     * @return bool
162
     */
163
    public function performCalEventUpdate($calIds, array &$dbQueries, &$customMessages)
164
    {
165
        $table = 'tx_cal_event';
166
        $db = HelperUtility::getDatabaseConnection($table);
167
        $q = $db->createQueryBuilder();
168
        $q->getRestrictions()
169
            ->removeAll()
170
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
171
172
        $locationTable = 'tx_cal_location';
173
        $locations = HelperUtility::getDatabaseConnection($locationTable)
174
            ->createQueryBuilder()
175
            ->select('*')
176
            ->from($locationTable)
177
            ->execute()
178
            ->fetchAll();
179
        $locationByUid = [];
180
        foreach ($locations as $location) {
181
            $locationByUid[$location['uid']] = $location['name'];
182
        }
183
184
        $events = $q->select('*')->from($table)->where(
185
            $q->expr()->in('uid', $calIds)
186
        )->execute()->fetchAll();
187
188
        foreach ($events as $event) {
189
            $calendarizeEventRecord = [
190
                'pid' => $event['pid'],
191
                'import_id' => self::IMPORT_PREFIX . (int)$event['uid'],
192
                'tstamp' => $event['tstamp'],
193
                'crdate' => $event['crdate'],
194
                'hidden' => $event['hidden'],
195
                'starttime' => $event['starttime'],
196
                'endtime' => $event['endtime'],
197
                'title' => $event['title'],
198
                'organizer' => $event['organizer'],
199
                'location' => $event['location_id'] > 0 ? $locationByUid[$event['location_id']] : $event['location'],
200
                'abstract' => $event['teaser'],
201
                'description' => $event['description'],
202
                'images' => (int)$event['image'],
203
                'downloads' => (int)$event['attachment'],
204
                'calendarize' => $this->buildConfigurations($event, $dbQueries),
205
            ];
206
207
            $variables = [
208
                'calendarizeEventRecord' => $calendarizeEventRecord,
209
                'event' => $event,
210
                'table' => self::EVENT_TABLE,
211
                'dbQueries' => $dbQueries,
212
            ];
213
214
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
215
            $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
216
217
            $q->insert($variables['table'])->values($variables['calendarizeEventRecord']);
218
            $dbQueries[] = $q->getSQL();
219
220
            $q->execute();
221
222
            $variablesPostInsert = [
223
                'calendarizeEventRecord' => $calendarizeEventRecord,
224
                'event' => $event,
225
                'table' => $variables['table'],
226
                'recordId' => $db->lastInsertId($variables['table']),
227
                'dbQueries' => $dbQueries,
228
            ];
229
230
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
231
            $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variablesPostInsert);
232
        }
233
234
        $indexer = GeneralUtility::makeInstance(IndexerService::class);
235
        $indexer->reindexAll();
236
237
        return true;
238
    }
239
240
    /**
241
     * Perform exception event update.
242
     *
243
     * @param       $calIds
244
     * @param array $dbQueries
245
     * @param array $customMessages
246
     *
247
     * @return bool
248
     */
249
    public function performExceptionEventUpdate($calIds, &$dbQueries, &$customMessages)
250
    {
251
        $table = 'tx_cal_exception_event_group';
252
        // ConfigurationGroup für jede ExceptionGroup
253
        $db = HelperUtility::getDatabaseConnection($table);
254
        $q = $db->createQueryBuilder();
255
256
        $variables = [
257
            'table' => $table,
258
            'dbQueries' => $dbQueries,
259
            'calIds' => $calIds,
260
        ];
261
262
        $q->getRestrictions()
263
            ->removeAll()
264
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
265
266
        $q->select('*')->from($variables['table']);
267
268
        $selectResults = $q->execute()->fetchAll();
269
        $dbQueries[] = $q->getSQL();
270
271
        foreach ($selectResults as $selectResult) {
272
            $group = [
273
                'pid' => $selectResult['pid'],
274
                'tstamp' => $selectResult['tstamp'],
275
                'crdate' => $selectResult['crdate'],
276
                'cruser_id' => $selectResult['cruser_id'],
277
                'title' => $selectResult['title'],
278
                'configurations' => $this->getExceptionConfigurationForExceptionGroup($selectResult['uid'], $dbQueries),
279
                'hidden' => $selectResult['hidden'],
280
                'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
281
            ];
282
283
            $q->insert(self::CONFIGURATION_GROUP_TABLE)->values($group);
284
            $dbQueries[] = $q->getSQL();
285
286
            $q->execute();
287
        }
288
289
        return true;
290
    }
291
292
    /**
293
     * Perform link event to configuration group.
294
     *
295
     * @param $calIds
296
     * @param $dbQueries
297
     * @param $customMessages
298
     *
299
     * @return bool
300
     */
301
    public function performLinkEventToConfigurationGroup($calIds, &$dbQueries, &$customMessages)
302
    {
303
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_GROUP_TABLE);
304
        $q = $db->createQueryBuilder();
305
        $now = new \DateTime();
306
307
        $variables = [
308
            'table' => self::CONFIGURATION_GROUP_TABLE,
309
            'dbQueries' => $dbQueries,
310
            'calIds' => $calIds,
311
        ];
312
313
        $selectResults = $q->select('*')->from($variables['table'])->execute()->fetchAll();
314
        $dbQueries[] = $q->getSQL();
315
316
        foreach ($selectResults as $group) {
317
            $importId = explode(':', $group['import_id']);
318
            $groupId = (int)$importId[1];
319
320
            $variables = [
321
                'table' => 'tx_cal_exception_event_mm',
322
                'dbQueries' => $dbQueries,
323
                'calIds' => $calIds,
324
            ];
325
326
            $q->resetQueryParts()->resetRestrictions();
327
328
            $q->select('uid_local')
329
                ->from($variables['table'])
330
                ->where(
331
                    $q->expr()->andX(
332
                        $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_exception_event_group')),
333
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT))
334
                    )
335
                );
336
337
            $dbQueries[] = $q->getSQL();
338
            $selectResults = $q->execute()->fetchAll();
339
340
            foreach ($selectResults as $eventUid) {
341
                $eventImportId = self::IMPORT_PREFIX . (int)$eventUid['uid_local'];
342
                $configurationRow = [
343
                    'pid' => (int)$group['pid'],
344
                    'tstamp' => $now->getTimestamp(),
345
                    'crdate' => $now->getTimestamp(),
346
                    'type' => 'group',
347
                    'handling' => 'exclude',
348
                    'groups' => $group['uid'],
349
                ];
350
351
                $this->updateEventWithConfiguration($eventImportId, $configurationRow, $dbQueries, $customMessages);
352
            }
353
        }
354
355
        return true;
356
    }
357
358
    /**
359
     * Migrate the 'sys_file_reference' entries from 'tx_cal_event' to 'tx_calendarize_domain_model_event'.
360
     * Mark the imported entries with the import-id.
361
     *
362
     * @param       $calIds
363
     * @param array $dbQueries
364
     * @param       $customMessages
365
     */
366
    public function performSysFileReferenceUpdate($calIds, array &$dbQueries, &$customMessages)
367
    {
368
        $db = HelperUtility::getDatabaseConnection('tx_cal_event');
369
        $q = $db->createQueryBuilder();
370
371
        $variables = [
372
            'table' => 'tx_cal_event',
373
            'fieldnames' => ['image', 'attachment'],
374
            'dbQueries' => $dbQueries,
375
            'calIds' => $calIds,
376
        ];
377
378
        // select all not migrated entries
379
        $fieldnames = 'fieldname = \'' . implode('\' OR fieldname = \'', $variables['fieldnames']) . '\'';
380
        $selectWhere = 'tablenames = \'' . $variables['table'] . '\' AND (' . $fieldnames . ')';
381
        $selectWhere .= ' AND NOT EXISTS (SELECT NULL FROM sys_file_reference sfr2 WHERE sfr2.import_id = CONCAT(\'' . self::IMPORT_PREFIX . '\', sfr1.uid))';
382
383
        $q->select('*')
384
            ->from('sys_file_reference', 'sfr1')
385
            ->where($selectWhere);
386
387
        $dbQueries[] = $q->getSQL();
388
        $selectResults = $q->execute()->fetchAll();
389
390
        $variables = [
391
            'table' => self::EVENT_TABLE,
392
            'fieldnames' => $variables['fieldnames'],
393
            'dbQueries' => $dbQueries,
394
            'calIds' => $calIds,
395
            'selectResults' => $selectResults,
396
        ];
397
398
        // create new entry with import_id
399
        foreach ($variables['selectResults'] as $selectResult) {
400
            $selectResult['tablenames'] = $variables['table'];
401
            $selectResult['import_id'] = self::IMPORT_PREFIX . $selectResult['uid'];
402
            $selectResult['fieldname'] = ('image' === $selectResult['fieldname']) ? 'images' : 'downloads';
403
            unset($selectResult['uid_foreign'], $selectResult['uid']);
404
405
            $q->resetQueryParts()->resetRestrictions();
406
            $q->insert('sys_file_reference')->values($selectResult);
407
408
            $dbQueries[] = $q->getSQL();
409
410
            $q->execute();
411
        }
412
    }
413
414
    /**
415
     * Link the Events to the migrated Categories.
416
     * This build up the 'sys_category_record_mm' table on base of the 'tx_cal_event_category_mm' table.
417
     *
418
     * @param       $calIds
419
     * @param array $dbQueries
420
     * @param array $customMessages
421
     */
422
    public function performLinkEventToCategory($calIds, &$dbQueries, &$customMessages)
423
    {
424
        $table = 'tx_cal_event_category_mm';
425
426
        $db = HelperUtility::getDatabaseConnection($table);
427
        $q = $db->createQueryBuilder();
428
429
        $q->select('*')->from($table);
430
        $dbQueries[] = $q->getSQL();
431
432
        $selectResults = $q->execute()->fetchAll();
433
434
        $variables = [
435
            'tablenames' => self::EVENT_TABLE,
436
            'fieldname' => 'categories',
437
            'dbQueries' => $dbQueries,
438
        ];
439
440
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
441
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
442
443
        foreach ($selectResults as $mm) {
444
            $eventUid = (int)$this->getCalendarizeEventUid(self::IMPORT_PREFIX . $mm['uid_local'], $dbQueries, $customMessages);
445
            $categoryUid = (int)$this->getCalendarizeCategoryUid(
446
                self::IMPORT_PREFIX . $mm['uid_foreign'],
447
                $dbQueries,
448
                $customMessages
449
            );
450
451
            if (0 !== $eventUid && 0 !== $categoryUid) {
452
                $insertValues = [
453
                    'uid_local' => $categoryUid,
454
                    'uid_foreign' => $eventUid,
455
                    'tablenames' => $variables['tablenames'],
456
                    'fieldname' => $variables['fieldname'],
457
                ];
458
459
                $q->insert('sys_category_record_mm')->values($insertValues);
460
                $dbQueries[] = $q->getSQL();
461
462
                $q->execute();
463
            }
464
        }
465
    }
466
467
    /**
468
     * Link the Events to the migrated categories.
469
     *
470
     * This uses the existing 'sys_category_record_mm' table which links tx_cal_event to sys_category.
471
     * The fields must be updated to use tx_calendarize_domain_model_event instead.
472
     * Additionally, the uid_foreign must be updated to point to the new event uid.
473
     *
474
     * Before: tablenames='tx_cal_event', fieldname='category_id'
475
     * After: tablenames='tx_calendarize_domain_model_event', fieldname='categories'
476
     *
477
     * @param       $calIds
478
     * @param array $dbQueries
479
     * @param array $customMessages
480
     */
481
    public function performLinkEventToSysCategory($calIds, &$dbQueries, &$customMessages)
482
    {
483
        $table = 'sys_category_record_mm';
484
485
        $db = HelperUtility::getDatabaseConnection($table);
486
        $q = $db->createQueryBuilder();
487
488
        $q->select('uid_foreign')->from($table)
489
            ->where(
490
                $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_event')),
491
                $q->expr()->eq('fieldname', $q->createNamedParameter('category_id')),
492
                $q->expr()->neq('uid_local', $q->createNamedParameter(0, \PDO::PARAM_INT)),
493
                $q->expr()->neq('uid_foreign', $q->createNamedParameter(0, \PDO::PARAM_INT))
494
            )->groupBy('uid_foreign');
495
496
        $selectResults = $q->execute()->fetchAll();
497
498
        $variables = [
499
            'tablenames' => self::EVENT_TABLE,
500
            'fieldname' => 'categories'
501
        ];
502
503
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
504
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
505
506
        foreach ($selectResults as $mm) {
507
            $eventUidOld = (int) $mm['uid_foreign'];
508
            // event id is in uid_foreign
509
            $eventUid = (int)$this->getCalendarizeEventUid(self::IMPORT_PREFIX . $eventUidOld, $dbQueries, $customMessages);
510
511
            if ($eventUid !== 0) {
512
                $q->update('sys_category_record_mm')
513
                    ->set('tablenames', $variables['tablenames'])
514
                    ->set('fieldname', $variables['fieldname'])
515
                    ->set('uid_foreign', $eventUid)
516
                    ->where(
517
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter($eventUidOld, \PDO::PARAM_INT)),
518
                        $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_event')),
519
                        $q->expr()->eq('fieldname', $q->createNamedParameter('category_id')),
520
                    )->execute();
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected ')'
Loading history...
521
            } else {
522
                $q->delete($table)
523
                    ->where(
524
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter($eventUid, \PDO::PARAM_INT)),
525
                        $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_event')),
526
                        $q->expr()->eq('fieldname', $q->createNamedParameter('category_id')),
527
                    )
528
                    ->execute();
529
            }
530
        }
531
532
        // delete remaining entries with insufficient values (e.g. uid_foreign=0)
533
        $q->delete($table)
534
            ->where(
535
                $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_event')),
536
                $q->expr()->orX(
537
                    $q->expr()->eq('fieldname', $q->createNamedParameter('')),
538
                    $q->expr()->eq('uid_local', $q->createNamedParameter(0, \PDO::PARAM_INT)),
539
                    $q->expr()->eq('uid_foreign', $q->createNamedParameter(0, \PDO::PARAM_INT))
540
                )
541
            )->execute();
542
    }
543
544
    /**
545
     * Update event with configuration.
546
     *
547
     * @param $eventImportId
548
     * @param $configuration
549
     * @param $dbQueries
550
     * @param $customMessages
551
     *
552
     * @return array
553
     */
554
    protected function updateEventWithConfiguration($eventImportId, $configuration, &$dbQueries, &$customMessages)
555
    {
556
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_TABLE);
557
        $q = $db->createQueryBuilder();
558
559
        $configurationRow = $this->findEventExcludeConfiguration($eventImportId, $dbQueries, $customMessages);
560
        if ($configurationRow) {
561
            $configurationRow['groups'] = $this->addValueToCsv($configurationRow['groups'], $configuration['groups']);
562
563
            unset($configurationRow['uid']);
564
565
            $q->update(self::CONFIGURATION_GROUP_TABLE)
566
                ->where('uid', $q->createNamedParameter((int)$configuration['uid'], \PDO::PARAM_INT));
567
            foreach ($configurationRow as $key => $value) {
568
                $q->set($key, $value);
569
            }
570
571
            $dbQueries[] = $q->getSQL();
572
            $results = $q->execute();
573
        } else {
574
            $q->insert(self::CONFIGURATION_TABLE)->values($configuration);
575
            $dbQueries[] = $q->getSQL();
576
577
            $configurationId = $db->lastInsertId(self::CONFIGURATION_TABLE);
578
579
            $results = $this->addConfigurationIdToEvent($eventImportId, $configurationId, $dbQueries, $customMessages);
580
        }
581
582
        return $results;
583
    }
584
585
    /**
586
     * Add Value to CSV.
587
     *
588
     * @param string $csv
589
     * @param string $value
590
     *
591
     * @return string
592
     */
593
    protected function addValueToCsv($csv, $value)
594
    {
595
        $csvArray = GeneralUtility::trimExplode(',', $csv);
596
597
        // check for doubles
598
        $values = array_flip($csvArray);
599
        if (isset($values[$value])) {
600
            return $csv;
601
        }
602
        $csvArray[] = $value;
603
        $csv = implode(',', $csvArray);
604
605
        return $csv;
606
    }
607
608
    /**
609
     * Add configuration ID to event.
610
     *
611
     * @param string $eventImportId
612
     * @param int    $configurationId
613
     * @param array  $dbQueries
614
     * @param array  $customMessages
615
     *
616
     * @return array|bool
617
     */
618
    protected function addConfigurationIdToEvent($eventImportId, $configurationId, &$dbQueries, &$customMessages)
619
    {
620
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
621
        if (!$event) {
622
            return false;
623
        }
624
625
        $event['calendarize'] = $this->addValueToCsv($event['calendarize'], $configurationId);
626
627
        return $this->updateEvent($event['uid'], $event, $dbQueries, $customMessages);
628
    }
629
630
    /**
631
     * Update event.
632
     *
633
     * @param int   $eventId
634
     * @param array $values
635
     * @param array $dbQueries
636
     * @param array $customMessages
637
     *
638
     * @return array
639
     */
640
    protected function updateEvent($eventId, $values, &$dbQueries, &$customMessages)
641
    {
642
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
643
        $q = $db->createQueryBuilder();
644
645
        $variables = [
646
            'table' => self::EVENT_TABLE,
647
            'eventId' => (int)$eventId,
648
            'values' => $values,
649
            'dbQueries' => $dbQueries,
650
        ];
651
652
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
653
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
654
655
        $q->update($variables['table'])
656
            ->where(
657
                $q->expr()->eq('uid', $q->createNamedParameter((int)$eventId, \PDO::PARAM_INT))
658
            );
659
        foreach ($variables['values'] as $key => $value) {
660
            $q->set($key, $value);
661
        }
662
663
        unset($values['uid']);
664
665
        $dbQueries[] = $q->getSQL();
666
667
        return $q->execute()->fetchAll();
668
    }
669
670
    /**
671
     * Find event by import ID.
672
     *
673
     * @param $eventImportId
674
     * @param $dbQueries
675
     * @param $customMessages
676
     *
677
     * @return array|bool
678
     */
679
    protected function findEventByImportId($eventImportId, &$dbQueries, &$customMessages)
680
    {
681
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
682
        $q = $db->createQueryBuilder();
683
684
        $variables = [
685
            'table' => self::EVENT_TABLE,
686
            'dbQueries' => $dbQueries,
687
            'eventImportId' => $eventImportId,
688
        ];
689
690
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
691
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
692
693
        $q->select('*')->from($variables['table'])
694
            ->where(
695
                $q->expr()->eq('import_id', $q->createNamedParameter($eventImportId))
696
            );
697
698
        $dbQueries[] = $q->getSQL();
699
700
        return $q->execute()->fetchAll();
701
    }
702
703
    /**
704
     * Find event exclude configuration.
705
     *
706
     * @param string $eventImportId
707
     * @param array  $dbQueries
708
     * @param array  $customMessages
709
     *
710
     * @return array|bool
711
     */
712
    protected function findEventExcludeConfiguration($eventImportId, &$dbQueries, &$customMessages)
713
    {
714
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
715
716
        if (!$event) {
717
            return false;
718
        }
719
720
        $variables = [
721
            'table' => self::CONFIGURATION_TABLE,
722
            'dbQueries' => $dbQueries,
723
            'event' => $event,
724
        ];
725
726
        $db = HelperUtility::getDatabaseConnection($variables['table']);
727
        $q = $db->createQueryBuilder();
728
729
        $q->select('*')
730
            ->from($variables['table'])
731
            ->where(
732
                $q->expr()->andX(
733
                    $q->expr()->eq('type', 'group'),
734
                    $q->expr()->eq('handling', 'exclude'),
735
                    $q->expr()->in('uid', $variables['event']['calendarize'])
736
                )
737
            );
738
739
        $dbQueries[] = $q->getSQL();
740
741
        return $q->execute()->fetchAll();
742
    }
743
744
    /**
745
     * Get exception configuration for exception group.
746
     *
747
     * @param       $groupId
748
     * @param array $dbQueries
749
     *
750
     * @return string
751
     */
752
    protected function getExceptionConfigurationForExceptionGroup($groupId, &$dbQueries)
753
    {
754
        $recordIds = [];
755
        $variables = [
756
            'table' => 'tx_cal_exception_event_group_mm',
757
            'dbQueries' => $dbQueries,
758
        ];
759
760
        $db = HelperUtility::getDatabaseConnection($variables['table']);
761
        $q = $db->createQueryBuilder();
762
763
        $q->select('*')
764
            ->from($variables['table'])
765
            ->where('uid_local', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT));
766
767
        $dbQueries[] = $q->getSQL();
768
769
        $mmResults = $q->execute()->fetchAll();
770
        foreach ($mmResults as $mmResult) {
771
            $variables = [
772
                'table' => 'tx_cal_exception_event',
773
                'dbQueries' => $dbQueries,
774
            ];
775
776
            $q->resetQueryParts()->resetRestrictions();
777
            $q->select('*')
778
                ->from($variables['table'])
779
                ->where(
780
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$mmResult['uid_foreign'], \PDO::PARAM_INT))
781
                );
782
783
            $dbQueries[] = $q->getSQL();
784
785
            $selectResults = $q->execute()->fetchAll();
786
787
            foreach ($selectResults as $selectResult) {
788
                $configurationRow = [
789
                    'pid' => $selectResult['pid'],
790
                    'tstamp' => $selectResult['tstamp'],
791
                    'crdate' => $selectResult['crdate'],
792
                    'type' => 'time',
793
                    'handling' => 'include',
794
                    'start_date' => (string)$selectResult['start_date'] ?: null,
795
                    'end_date' => (string)$selectResult['end_date'] ?: null,
796
                    'start_time' => (int)$selectResult['start_time'],
797
                    'end_time' => (int)$selectResult['end_time'],
798
                    'all_day' => (null === $selectResult['start_time'] && null === $selectResult['end_time']) ? 1 : 0,
799
                    'frequency' => $this->mapFrequency($selectResult['freq']),
800
                    'till_date' => (string)$selectResult['until'] ?: null,
801
                    'counter_amount' => (int)$selectResult['cnt'],
802
                    'counter_interval' => (int)$selectResult['interval'],
803
                    'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
804
                ];
805
806
                $variables = [
807
                    'table' => self::CONFIGURATION_TABLE,
808
                    'configurationRow' => $configurationRow,
809
                ];
810
811
                $dispatcher = HelperUtility::getSignalSlotDispatcher();
812
                $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
813
814
                $q->resetQueryParts()->resetRestrictions();
815
                $q->insert($variables['table'])->values($variables['configurationRow']);
816
817
                $dbQueries[] = $q->getSQL();
818
819
                $q->execute();
820
821
                $recordIds[] = $db->lastInsertId($variables['table']);
822
            }
823
        }
824
825
        return implode(',', $recordIds);
826
    }
827
828
    /**
829
     * Map frequency.
830
     *
831
     * @param string $calFrequency
832
     *
833
     * @return string
834
     */
835
    protected function mapFrequency($calFrequency)
836
    {
837
        $freq = [
838
            'none' => null,
839
            'day' => 'daily',
840
            'week' => 'weekly',
841
            'month' => 'monthly',
842
            'year' => 'yearly',
843
        ];
844
845
        if (!isset($freq[$calFrequency])) {
846
            return '';
847
        }
848
849
        return $freq[$calFrequency];
850
    }
851
852
    /**
853
     * Migrate the 'tx_cal_category' table to the 'sys_category' table.
854
     *
855
     * @param       $calIds
856
     * @param array $dbQueries
857
     * @param       $customMessages
858
     */
859
    protected function performSysCategoryUpdate($calIds, array &$dbQueries, &$customMessages)
860
    {
861
        // first migrate from tx_cal_category to sys_category
862
        $variables = [
863
            'table' => 'tx_cal_category',
864
            'dbQueries' => $dbQueries,
865
            'calIds' => $calIds,
866
        ];
867
868
        $db = HelperUtility::getDatabaseConnection($variables['table']);
869
        $q = $db->createQueryBuilder();
870
        $q->getRestrictions()
871
            ->removeAll()
872
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
873
874
        $q->select('*')
875
            ->from($variables['table']);
876
877
        $dbQueries[] = $q->getSQL();
878
879
        $selectResults = $q->execute()->fetchAll();
880
881
        foreach ($selectResults as $category) {
882
            $sysCategoryRecord = [
883
                'pid' => $category['pid'],
884
                'tstamp' => $category['tstamp'],
885
                'crdate' => $category['crdate'],
886
                'cruser_id' => $category['cruser_id'],
887
                'deleted' => $category['deleted'],
888
                'hidden' => $category['hidden'],
889
                'starttime' => $category['starttime'],
890
                'endtime' => $category['endtime'],
891
                'sys_language_uid' => $category['sys_language_uid'],
892
                'l10n_parent' => $category['l18n_parent'],
893
                'l10n_diffsource' => $category['l18n_diffsource'],
894
                'title' => $category['title'],
895
                'parent' => (int)$category['parent_category'],
896
                'import_id' => self::IMPORT_PREFIX . (int)$category['uid'],
897
                'sorting' => $category['sorting'],
898
            ];
899
900
            $q->resetQueryParts()->resetRestrictions();
901
902
            $q->insert('sys_category')->values($sysCategoryRecord);
903
            $dbQueries[] = $q->getSQL();
904
905
            $q->execute();
906
        }
907
908
        // second rewrite the tree
909
        $variables = [
910
            'table' => 'sys_category',
911
            'dbQueries' => $dbQueries,
912
            'calIds' => $calIds,
913
        ];
914
915
        $q->resetQueryParts()->resetRestrictions();
916
917
        $q->select('*')
918
            ->from($variables['table'])
919
            ->where(
920
                $q->expr()->neq('import_id', $q->createNamedParameter(''))
921
            );
922
923
        $dbQueries[] = $q->getSQL();
924
        $selectResults = $q->execute()->fetchAll();
925
926
        foreach ($selectResults as $sysCategory) {
927
            // update parent, because there are just the old uids
928
            $q->resetQueryParts()->resetRestrictions();
929
            $q->update('sys_category')
930
                ->where(
931
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$sysCategory['uid'], \PDO::PARAM_INT))
932
                )->set(
933
                    'parent',
934
                    $this->getSysCategoryParentUid(self::IMPORT_PREFIX . (int)$sysCategory['parent'])
935
                );
936
937
            $dbQueries[] = $q->getSQL();
938
939
            $q->execute();
940
        }
941
    }
942
943
    /**
944
     * Return the parentUid for the 'sys_category' entry on base of the import_id.
945
     *
946
     * @param string $importId
947
     *
948
     * @return int
949
     */
950
    protected function getSysCategoryParentUid($importId)
951
    {
952
        $table = 'sys_category';
953
        $db = HelperUtility::getDatabaseConnection($table);
954
        $q = $db->createQueryBuilder();
955
956
        $q->select('uid')
957
            ->from($table)
958
            ->where(
959
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
960
            );
961
962
        $dbQueries[] = $q->getSQL();
963
964
        $result = $q->execute()->fetchAll();
965
966
        return (int)$result[0]['uid'];
967
    }
968
969
    /**
970
     * Get the event uid on base of the given import_id.
971
     * The import_id is the original tx_cal_event id prefixed with the IMPORT_PREFIX.
972
     *
973
     * @param string $importId
974
     * @param array  $dbQueries
975
     * @param array  $customMessages
976
     *
977
     * @return int
978
     */
979
    protected function getCalendarizeEventUid($importId, &$dbQueries, &$customMessages)
980
    {
981
        $variables = [
982
            'table' => self::EVENT_TABLE,
983
            'dbQueries' => $dbQueries,
984
        ];
985
986
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
987
988
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
989
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
990
991
        // also get restricted (e.g. hidden) records, otherwise retrieving event uid for
992
        // restricted records will always return 0
993
        $q->getRestrictions()
994
            ->removeAll()
995
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
996
        $q->select('uid')
997
            ->from($variables['table'])
998
            ->where(
999
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
1000
            );
1001
1002
        $dbQueries[] = $q->getSQL();
1003
1004
        $result = $q->execute()->fetchAll();
1005
1006
        return (int)$result[0]['uid'];
1007
    }
1008
1009
    /**
1010
     * Get the sys_category uid on base of the given import_id.
1011
     * The import_id is the original tx_cal_category id prefixed with the IMPORT_PREFIX.
1012
     *
1013
     * @see CalMigrationUpdate::IMPORT_PREFIX
1014
     *
1015
     * @param string $importId
1016
     * @param array  $dbQueries
1017
     * @param array  $customMessages
1018
     *
1019
     * @return int
1020
     */
1021
    protected function getCalendarizeCategoryUid($importId, &$dbQueries, &$customMessages)
1022
    {
1023
        $variables = [
1024
            'table' => 'sys_category',
1025
            'dbQueries' => $dbQueries,
1026
        ];
1027
1028
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
1029
1030
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1031
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
1032
1033
        $q->select('uid')
1034
            ->from($variables['table'])
1035
            ->where(
1036
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
1037
            );
1038
1039
        $dbQueries[] = $q->getSQL();
1040
1041
        $result = $q->execute()->fetchAll();
1042
1043
        return (int)$result[0]['uid'];
1044
    }
1045
1046
    /**
1047
     * Build configurations.
1048
     *
1049
     * @param $calEventRow
1050
     * @param $dbQueries
1051
     *
1052
     * @return int
1053
     */
1054
    protected function buildConfigurations($calEventRow, &$dbQueries)
1055
    {
1056
        $configurationRow = [
1057
            'pid' => $calEventRow['pid'],
1058
            'tstamp' => $calEventRow['tstamp'],
1059
            'crdate' => $calEventRow['crdate'],
1060
            'type' => 'time',
1061
            'handling' => 'include',
1062
            'start_date' => (string)$calEventRow['start_date'] ?: null,
1063
            'end_date' => (string)$calEventRow['end_date'] ?: null,
1064
            'start_time' => (int)$calEventRow['start_time'],
1065
            'end_time' => (int)$calEventRow['end_time'],
1066
            'all_day' => $calEventRow['allday'],
1067
            'frequency' => $this->mapFrequency($calEventRow['freq']),
1068
            'till_date' => (string)$calEventRow['until'] ?: null,
1069
            'counter_amount' => (int)$calEventRow['cnt'],
1070
            'counter_interval' => (int)$calEventRow['interval'],
1071
        ];
1072
1073
        $variables = [
1074
            'table' => self::CONFIGURATION_TABLE,
1075
            'configurationRow' => $configurationRow,
1076
            'calEventRow' => $calEventRow,
1077
            'dbQueries' => $dbQueries,
1078
        ];
1079
1080
        $db = HelperUtility::getDatabaseConnection($variables['table']);
1081
        $q = $db->createQueryBuilder();
1082
1083
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1084
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
1085
1086
        $q->insert($variables['table'])
1087
            ->values($variables['configurationRow']);
1088
1089
        $dbQueries[] = $q->getSQL();
1090
        $q->execute();
1091
        $recordId = $db->lastInsertId($variables['table']);
1092
1093
        $variables = [
1094
            'table' => $variables['table'],
1095
            'configurationRow' => $configurationRow,
1096
            'calEventRow' => $calEventRow,
1097
            'recordId' => $recordId,
1098
            'dbQueries' => $dbQueries,
1099
        ];
1100
1101
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1102
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variables);
1103
1104
        return $variables['recordId'];
1105
    }
1106
1107
    /**
1108
     * Get the non migrated cal IDs.
1109
     *
1110
     * @return array
1111
     */
1112
    protected function getNonMigratedCalIds()
1113
    {
1114
        $checkImportIds = [];
1115
        $nonMigrated = [];
1116
1117
        $table = 'tx_cal_event';
1118
        $q = HelperUtility::getDatabaseConnection($table)->createQueryBuilder();
1119
        $q->getRestrictions()
1120
            ->removeAll()
1121
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1122
1123
        $events = $q->select('uid')
1124
            ->from($table)
1125
            ->execute()
1126
            ->fetchAll();
1127
1128
        foreach ($events as $event) {
1129
            $checkImportIds[] = '"' . self::IMPORT_PREFIX . $event['uid'] . '"';
1130
            $nonMigrated[(int)$event['uid']] = (int)$event['uid'];
1131
        }
1132
1133
        $countOriginal = \count($checkImportIds);
1134
        if (0 === $countOriginal) {
1135
            return [];
1136
        }
1137
1138
        $variables = [
1139
            'table' => self::EVENT_TABLE,
1140
        ];
1141
1142
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1143
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreSelect', $variables);
1144
1145
        $q->resetQueryParts();
1146
1147
        $migratedRows = $q->select('uid', 'import_id')
1148
            ->from($variables['table'])
1149
            ->where(
1150
                $q->expr()->in('import_id', $checkImportIds)
1151
            )
1152
            ->execute()
1153
            ->fetchAll();
1154
1155
        foreach ($migratedRows as $migratedRow) {
1156
            $importId = (int)str_replace(self::IMPORT_PREFIX, '', $migratedRow['import_id']);
1157
            if (isset($nonMigrated[$importId])) {
1158
                unset($nonMigrated[$importId]);
1159
            }
1160
        }
1161
1162
        $variables = [
1163
            'table' => $variables['table'],
1164
            'migratedRows' => $migratedRows,
1165
            'nonMigrated' => $nonMigrated,
1166
        ];
1167
1168
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1169
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'ReadyParsed', $variables);
1170
1171
        return $variables['nonMigrated'];
1172
    }
1173
1174
    public function updateNecessary(): bool
1175
    {
1176
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
1177
        $connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
1178
        $dbSchema = $connection->getSchemaManager()->createSchema();
1179
1180
        $tableNames = array_map(function ($table) {
1181
            return $table->getName();
1182
        }, $dbSchema->getTables());
1183
1184
        return \in_array('tx_cal_event', $tableNames);
1185
    }
1186
1187
    public function getPrerequisites(): array
1188
    {
1189
        return [
1190
            DatabaseUpdatedPrerequisite::class,
1191
        ];
1192
    }
1193
}
1194