Completed
Push — master ( c38f18...f68a32 )
by Tim
27s queued 11s
created

CalMigrationUpdate   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 1040
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 6
dl 0
loc 1040
rs 5.92
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A checkForUpdate() 0 12 4
A executeUpdate() 0 12 1
B performCalEventUpdate() 0 61 2
A performExceptionEventUpdate() 0 41 2
B performLinkEventToConfigurationGroup() 0 56 3
A performSysFileReferenceUpdate() 0 47 3
A performLinkEventToCategory() 0 42 2
A updateEventWithConfiguration() 0 28 2
A addValueToCsv() 0 14 2
A addConfigurationIdToEvent() 0 11 2
A updateEvent() 0 27 1
A findEventByImportId() 0 23 1
A findEventExcludeConfiguration() 0 31 2
B getExceptionConfigurationForExceptionGroup() 0 75 5
A mapFrequency() 0 16 2
B performSysCategoryUpdate() 0 85 3
A getSysCategoryParentUid() 0 18 1
A getCalendarizeEventUid() 0 25 1
A getCalendarizeCategoryUid() 0 25 1
A buildConfigurations() 0 52 1
A migrateDate() 0 11 2
B getNonMigratedCalIds() 0 63 6
A getIdentifier() 0 4 1
A getTitle() 0 4 1
A getDescription() 0 4 1
A updateNecessary() 0 4 1
A getPrerequisites() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like CalMigrationUpdate often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CalMigrationUpdate, and based on these observations, apply Extract Interface, too.

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\Query\Restriction\DeletedRestriction;
15
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
18
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
19
20
/**
21
 * CalMigrationUpdate.
22
 *
23
 * If using the slots please use the m with func_get_args!
24
 * Example:
25
 * /**
26
 *  * @SignalClass \HDNET\Calendarize\Updates\CalMigrationUpdate
27
 *  * @SignalName getCalendarizeEventUid
28
 *  *
29
 *
30
 *  *@return array
31
 *  *
32
 * public function getCalendarizeEventUid()
33
 * {
34
 *    $args = func_get_args();
35
 *    list($table, $dbQueries, $call) = $args;
36
 *
37
 *    $variables = [
38
 *        'table'     => self::EVENT_TABLE,
39
 *        'dbQueries' => $dbQueries
40
 *    ];
41
 *
42
 *    return $variables;
43
 * }
44
 */
45
class CalMigrationUpdate implements UpgradeWizardInterface
46
{
47
    /**
48
     * Import prefix.
49
     */
50
    const IMPORT_PREFIX = 'calMigration:';
51
52
    /**
53
     * Event table.
54
     */
55
    const EVENT_TABLE = 'tx_calendarize_domain_model_event';
56
57
    /**
58
     * Configuration table.
59
     */
60
    const CONFIGURATION_TABLE = 'tx_calendarize_domain_model_configuration';
61
62
    /**
63
     * ConfigurationGroup table.
64
     */
65
    const CONFIGURATION_GROUP_TABLE = 'tx_calendarize_domain_model_configurationgroup';
66
67
    /**
68
     * The human-readable title of the upgrade wizard.
69
     *
70
     * @var string
71
     */
72
    protected $title = 'Migrate cal event structures to the new calendarize event structures.
73
    Try to migrate all cal information and place the new calendarize event models in the same folder
74
    as the cal-records. Please note: the migration will be create calendarize default models.';
75
76
    /**
77
     * Checks whether updates are required.
78
     *
79
     * @param string &$description The description for the update
80
     *
81
     * @return bool Whether an update is required (TRUE) or not (FALSE)
82
     */
83
    public function checkForUpdate(&$description)
84
    {
85
        $nonMigratedCalIds = $this->getNonMigratedCalIds();
86
        $count = \count($nonMigratedCalIds);
87
        if (0 === $count) {
88
            return false;
89
        }
90
        $description = 'There ' . ($count > 1 ? 'are ' . $count : 'is ' . $count) . ' non migrated EXT:cal event
91
        ' . ($count > 1 ? 's' : '') . '. Run the update process to migrate the events to EXT:calendarize events.';
92
93
        return true;
94
    }
95
96
    /**
97
     * Performs the accordant updates.
98
     *
99
     * @param array &$dbQueries      Queries done in this update
100
     * @param mixed &$customMessages Custom messages
101
     *
102
     * @return bool Whether everything went smoothly or not
103
     */
104
    public function executeUpdate() : bool
105
    {
106
        $calIds = $this->getNonMigratedCalIds();
107
        $this->performSysCategoryUpdate($calIds, $dbQueries, $customMessages);
108
        $this->performSysFileReferenceUpdate($calIds, $dbQueries, $customMessages);
109
        $this->performExceptionEventUpdate($calIds, $dbQueries, $customMessages);
110
        $this->performCalEventUpdate($calIds, $dbQueries, $customMessages);
111
        $this->performLinkEventToCategory($calIds, $dbQueries, $customMessages);
112
        $this->performLinkEventToConfigurationGroup($calIds, $dbQueries, $customMessages);
113
114
        return true;
115
    }
116
117
    /**
118
     * Perform CAL event update.
119
     *
120
     * @param       $calIds
121
     * @param array $dbQueries
122
     * @param       $customMessages
123
     *
124
     * @return bool
125
     */
126
    public function performCalEventUpdate($calIds, array &$dbQueries, &$customMessages)
127
    {
128
        $table = 'tx_cal_event';
129
        $db = HelperUtility::getDatabaseConnection($table);
130
        $q = $db->createQueryBuilder();
131
132
        $events = $q->select('*')->from($table)->where(
133
            $q->expr()->in('uid', $calIds)
134
        )->execute()->fetchAll();
135
136
        foreach ($events as $event) {
137
            $calendarizeEventRecord = [
138
                'pid' => $event['pid'],
139
                'import_id' => self::IMPORT_PREFIX . (int)$event['uid'],
140
                'tstamp' => $event['tstamp'],
141
                'crdate' => $event['crdate'],
142
                'hidden' => $event['hidden'],
143
                'starttime' => $event['starttime'],
144
                'endtime' => $event['endtime'],
145
                'title' => $event['title'],
146
                'organizer' => $event['organizer'],
147
                'location' => $event['location'],
148
                'abstract' => $event['teaser'],
149
                'description' => $event['description'],
150
                'images' => $event['image'],
151
                'downloads' => $event['attachment'],
152
                'calendarize' => $this->buildConfigurations($event, $dbQueries),
153
            ];
154
155
            $variables = [
156
                'calendarizeEventRecord' => $calendarizeEventRecord,
157
                'event' => $event,
158
                'table' => self::EVENT_TABLE,
159
                'dbQueries' => $dbQueries,
160
            ];
161
162
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
163
            $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
164
165
            $q->insert($variables['table'])->values($variables['calendarizeEventRecord']);
166
            $dbQueries[] = $q->getSQL();
167
168
            $q->execute();
169
170
            $variablesPostInsert = [
171
                'calendarizeEventRecord' => $calendarizeEventRecord,
172
                'event' => $event,
173
                'table' => $variables['table'],
174
                'recordId' => $db->lastInsertId($variables['table']),
175
                'dbQueries' => $dbQueries,
176
            ];
177
178
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
179
            $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variablesPostInsert);
180
        }
181
182
        $indexer = GeneralUtility::makeInstance(IndexerService::class);
183
        $indexer->reindexAll();
184
185
        return true;
186
    }
187
188
    /**
189
     * Perform exception event update.
190
     *
191
     * @param       $calIds
192
     * @param array $dbQueries
193
     * @param array $customMessages
194
     *
195
     * @return bool
196
     */
197
    public function performExceptionEventUpdate($calIds, &$dbQueries, &$customMessages)
198
    {
199
        $table = 'tx_cal_exception_event_group';
200
        // ConfigurationGroup für jede ExceptionGroup
201
        $db = HelperUtility::getDatabaseConnection($table);
202
        $q = $db->createQueryBuilder();
203
        $variables = [
204
            'table' => $table,
205
            'dbQueries' => $dbQueries,
206
            'calIds' => $calIds,
207
        ];
208
209
        $q->getRestrictions()
210
            ->removeAll()
211
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
212
213
        $q->select('*')->from($variables['table']);
214
215
        $selectResults = $q->execute()->fetchAll();
216
        $dbQueries[] = $q->getSQL();
217
218
        foreach ($selectResults as $selectResult) {
219
            $group = [
220
                'pid' => $selectResult['pid'],
221
                'tstamp' => $selectResult['tstamp'],
222
                'crdate' => $selectResult['crdate'],
223
                'cruser_id' => $selectResult['cruser_id'],
224
                'title' => $selectResult['title'],
225
                'configurations' => $this->getExceptionConfigurationForExceptionGroup($selectResult['uid'], $dbQueries),
226
                'hidden' => $selectResult['hidden'],
227
                'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
228
            ];
229
230
            $q->insert(self::CONFIGURATION_GROUP_TABLE)->values($group);
231
            $dbQueries[] = $q->getSQL();
232
233
            $q->execute();
234
        }
235
236
        return true;
237
    }
238
239
    /**
240
     * Perform link event to configuration group.
241
     *
242
     * @param $calIds
243
     * @param $dbQueries
244
     * @param $customMessages
245
     *
246
     * @return bool
247
     */
248
    public function performLinkEventToConfigurationGroup($calIds, &$dbQueries, &$customMessages)
249
    {
250
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_GROUP_TABLE);
251
        $q = $db->createQueryBuilder();
252
        $now = new \DateTime();
253
254
        $variables = [
255
            'table' => self::CONFIGURATION_GROUP_TABLE,
256
            'dbQueries' => $dbQueries,
257
            'calIds' => $calIds,
258
        ];
259
260
        $selectResults = $q->select('*')->from($variables['table'])->execute()->fetchAll();
261
        $dbQueries[] = $q->getSQL();
262
263
        foreach ($selectResults as $group) {
264
            $importId = \explode(':', $group['import_id']);
265
            $groupId = (int)$importId[1];
266
267
            $variables = [
268
                'table' => 'tx_cal_exception_event_mm',
269
                'dbQueries' => $dbQueries,
270
                'calIds' => $calIds,
271
            ];
272
273
            $q->resetQueryParts()->resetRestrictions();
274
275
            $q->select('uid_local')
276
                ->from($variables['table'])
277
                ->where(
278
                    $q->expr()->andX(
279
                        $q->expr()->eq('tablenames', 'tx_cal_exception_event_group'),
280
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT))
281
                    )
282
                );
283
284
            $dbQueries[] = $q->getSQL();
285
            $selectResults = $q->execute()->fetchAll();
286
287
            foreach ($selectResults as $eventUid) {
288
                $eventImportId = self::IMPORT_PREFIX . (int)$eventUid['uid_local'];
289
                $configurationRow = [
290
                    'pid' => (int)$group['pid'],
291
                    'tstamp' => $now->getTimestamp(),
292
                    'crdate' => $now->getTimestamp(),
293
                    'type' => 'group',
294
                    'handling' => 'exclude',
295
                    'groups' => $group['uid'],
296
                ];
297
298
                $this->updateEventWithConfiguration($eventImportId, $configurationRow, $dbQueries, $customMessages);
299
            }
300
        }
301
302
        return true;
303
    }
304
305
    /**
306
     * Migrate the 'sys_file_reference' entries from 'tx_cal_event' to 'tx_calendarize_domain_model_event'.
307
     * Mark the imported entries with the import-id.
308
     *
309
     * @param       $calIds
310
     * @param array $dbQueries
311
     * @param       $customMessages
312
     */
313
    public function performSysFileReferenceUpdate($calIds, array &$dbQueries, &$customMessages)
314
    {
315
        $db = HelperUtility::getDatabaseConnection('tx_cal_event');
316
        $q = $db->createQueryBuilder();
317
318
        $variables = [
319
            'table' => 'tx_cal_event',
320
            'fieldnames' => ['image', 'attachment'],
321
            'dbQueries' => $dbQueries,
322
            'calIds' => $calIds,
323
        ];
324
325
        // select all not migrated entries
326
        $fieldnames = 'fieldname = \'' . \implode('\' OR fieldname = \'', $variables['fieldnames']) . '\'';
327
        $selectWhere = 'tablenames = \'' . $variables['table'] . '\' AND (' . $fieldnames . ')';
328
        $selectWhere .= ' AND NOT EXISTS (SELECT NULL FROM sys_file_reference sfr2 WHERE sfr2.import_id = CONCAT(\'' . self::IMPORT_PREFIX . '\', sfr1.uid))';
329
330
        $q->select('*')
331
            ->from('sys_file_reference', 'sfr1')
332
            ->where($selectWhere);
333
334
        $dbQueries[] = $q->getSQL();
335
        $selectResults = $q->execute()->fetchAll();
336
337
        $variables = [
338
            'table' => self::EVENT_TABLE,
339
            'fieldnames' => $variables['fieldnames'],
340
            'dbQueries' => $dbQueries,
341
            'calIds' => $calIds,
342
            'selectResults' => $selectResults,
343
        ];
344
345
        // create new entry with import_id
346
        foreach ($variables['selectResults'] as $selectResult) {
347
            $selectResult['tablenames'] = $variables['table'];
348
            $selectResult['import_id'] = self::IMPORT_PREFIX . $selectResult['uid'];
349
            $selectResult['fieldname'] = ('image' === $selectResult['fieldname']) ? 'images' : 'downloads';
350
            unset($selectResult['uid_foreign'], $selectResult['uid']);
351
352
            $q->resetQueryParts()->resetRestrictions();
353
            $q->insert('sys_file_reference')->values($selectResult);
354
355
            $dbQueries[] = $q->getSQL();
356
357
            $q->execute();
358
        }
359
    }
360
361
    /**
362
     * Link the Events to the migrated Categories.
363
     * This build up the 'sys_category_record_mm' table on base of the 'tx_cal_event_category_mm' table.
364
     *
365
     * @param       $calIds
366
     * @param array $dbQueries
367
     * @param array $customMessages
368
     */
369
    public function performLinkEventToCategory($calIds, &$dbQueries, &$customMessages)
370
    {
371
        $table = 'tx_cal_event_category_mm';
372
373
        $db = HelperUtility::getDatabaseConnection($table);
374
        $q = $db->createQueryBuilder();
375
376
        $q->select('*')->from($table);
377
        $dbQueries[] = $q->getSQL();
378
379
        $selectResults = $q->execute()->fetchAll();
380
381
        $variables = [
382
            'tablenames' => self::EVENT_TABLE,
383
            'fieldname' => 'categories',
384
            'dbQueries' => $dbQueries,
385
        ];
386
387
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
388
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
389
390
        foreach ($selectResults as $mm) {
391
            $eventUid = $this->getCalendarizeEventUid(self::IMPORT_PREFIX . $mm['uid_local'], $dbQueries, $customMessages);
392
            $categoryUid = $this->getCalendarizeCategoryUid(
393
                self::IMPORT_PREFIX . $mm['uid_foreign'],
394
                $dbQueries,
395
                $customMessages
396
            );
397
398
            $insertValues = [
399
                'uid_local' => $categoryUid,
400
                'uid_foreign' => $eventUid,
401
                'tablenames' => $variables['tablenames'],
402
                'fieldname' => $variables['fieldname'],
403
            ];
404
405
            $q->insert('sys_category_record_mm')->values($insertValues);
406
            $dbQueries[] = $q->getSQL();
407
408
            $q->execute();
409
        }
410
    }
411
412
    /**
413
     * Update event with configuration.
414
     *
415
     * @param $eventImportId
416
     * @param $configuration
417
     * @param $dbQueries
418
     * @param $customMessages
419
     *
420
     * @return array
421
     */
422
    protected function updateEventWithConfiguration($eventImportId, $configuration, &$dbQueries, &$customMessages)
423
    {
424
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_TABLE);
425
        $q = $db->createQueryBuilder();
426
427
        $configurationRow = $this->findEventExcludeConfiguration($eventImportId, $dbQueries, $customMessages);
428
        if ($configurationRow) {
429
            $configurationRow['groups'] = $this->addValueToCsv($configurationRow['groups'], $configuration['groups']);
430
431
            unset($configurationRow['uid']);
432
433
            $q->update(self::CONFIGURATION_GROUP_TABLE)
434
                ->where('uid', $q->createNamedParameter((int)$configuration['uid'], \PDO::PARAM_INT))
435
                ->values($configurationRow);
436
437
            $dbQueries[] = $q->getSQL();
438
            $results = $q->execute();
439
        } else {
440
            $q->insert(self::CONFIGURATION_TABLE)->values($configuration);
441
            $dbQueries[] = $q->getSQL();
442
443
            $configurationId = $db->lastInsertId(self::CONFIGURATION_TABLE);
444
445
            $results = $this->addConfigurationIdToEvent($eventImportId, $configurationId, $dbQueries, $customMessages);
446
        }
447
448
        return $results;
449
    }
450
451
    /**
452
     * Add Value to CSV.
453
     *
454
     * @param string $csv
455
     * @param string $value
456
     *
457
     * @return string
458
     */
459
    protected function addValueToCsv($csv, $value)
460
    {
461
        $csvArray = GeneralUtility::trimExplode(',', $csv);
462
463
        // check for doubles
464
        $values = \array_flip($csvArray);
465
        if (isset($values[$value])) {
466
            return $csv;
467
        }
468
        $csvArray[] = $value;
469
        $csv = \implode(',', $csvArray);
470
471
        return $csv;
472
    }
473
474
    /**
475
     * Add configuration ID to event.
476
     *
477
     * @param string $eventImportId
478
     * @param int    $configurationId
479
     * @param array  $dbQueries
480
     * @param array  $customMessages
481
     *
482
     * @return array|bool
483
     */
484
    protected function addConfigurationIdToEvent($eventImportId, $configurationId, &$dbQueries, &$customMessages)
485
    {
486
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
487
        if (!$event) {
488
            return false;
489
        }
490
491
        $event['calendarize'] = $this->addValueToCsv($event['calendarize'], $configurationId);
492
493
        return $this->updateEvent($event['uid'], $event, $dbQueries, $customMessages);
494
    }
495
496
    /**
497
     * Update event.
498
     *
499
     * @param int   $eventId
500
     * @param array $values
501
     * @param array $dbQueries
502
     * @param array $customMessages
503
     *
504
     * @return array
505
     */
506
    protected function updateEvent($eventId, $values, &$dbQueries, &$customMessages)
507
    {
508
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
509
        $q = $db->createQueryBuilder();
510
511
        $variables = [
512
            'table' => self::EVENT_TABLE,
513
            'eventId' => (int)$eventId,
514
            'values' => $values,
515
            'dbQueries' => $dbQueries,
516
        ];
517
518
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
519
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
520
521
        $q->update($variables['table'])
522
            ->where(
523
                $q->expr()->eq('uid', $q->createNamedParameter((int)$eventId, \PDO::PARAM_INT))
524
            )
525
            ->values($variables['values']);
526
527
        unset($values['uid']);
528
529
        $dbQueries[] = $q->getSQL();
530
531
        return $q->execute()->fetchAll();
532
    }
533
534
    /**
535
     * Find event by import ID.
536
     *
537
     * @param $eventImportId
538
     * @param $dbQueries
539
     * @param $customMessages
540
     *
541
     * @return array|bool
542
     */
543
    protected function findEventByImportId($eventImportId, &$dbQueries, &$customMessages)
544
    {
545
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
546
        $q = $db->createQueryBuilder();
547
548
        $variables = [
549
            'table' => self::EVENT_TABLE,
550
            'dbQueries' => $dbQueries,
551
            'eventImportId' => $eventImportId,
552
        ];
553
554
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
555
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
556
557
        $q->select('*')->from($variables['table'])
558
            ->where(
559
                $q->expr()->eq('import_id', $q->createNamedParameter($eventImportId))
560
            );
561
562
        $dbQueries[] = $q->getSQL();
563
564
        return $q->execute()->fetchAll();
565
    }
566
567
    /**
568
     * Find event exclude configuration.
569
     *
570
     * @param string $eventImportId
571
     * @param array  $dbQueries
572
     * @param array  $customMessages
573
     *
574
     * @return array|bool
575
     */
576
    protected function findEventExcludeConfiguration($eventImportId, &$dbQueries, &$customMessages)
577
    {
578
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
579
580
        if (!$event) {
581
            return false;
582
        }
583
584
        $variables = [
585
            'table' => self::CONFIGURATION_TABLE,
586
            'dbQueries' => $dbQueries,
587
            'event' => $event,
588
        ];
589
590
        $db = HelperUtility::getDatabaseConnection($variables['table']);
591
        $q = $db->createQueryBuilder();
592
593
        $q->select('*')
594
            ->from($variables['table'])
595
            ->where(
596
                $q->expr()->andX(
597
                    $q->expr()->eq('type', 'group'),
598
                    $q->expr()->eq('handling', 'exclude'),
599
                    $q->expr()->in('uid', $variables['event']['calendarize'])
600
                )
601
            );
602
603
        $dbQueries[] = $q->getSQL();
604
605
        return $q->execute()->fetchAll();
606
    }
607
608
    /**
609
     * Get exception configuration for exception group.
610
     *
611
     * @param       $groupId
612
     * @param array $dbQueries
613
     *
614
     * @return string
615
     */
616
    protected function getExceptionConfigurationForExceptionGroup($groupId, &$dbQueries)
617
    {
618
        $recordIds = [];
619
        $variables = [
620
            'table' => 'tx_cal_exception_event_group_mm',
621
            'dbQueries' => $dbQueries,
622
        ];
623
624
        $db = HelperUtility::getDatabaseConnection($variables['table']);
625
        $q = $db->createQueryBuilder();
626
627
        $q->select('*')
628
            ->from($variables['table'])
629
            ->where('uid_local', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT));
630
631
        $dbQueries[] = $q->getSQL();
632
633
        $mmResults = $q->execute()->fetchAll();
634
        foreach ($mmResults as $mmResult) {
635
            $variables = [
636
                'table' => 'tx_cal_exception_event',
637
                'dbQueries' => $dbQueries,
638
            ];
639
640
            $q->resetQueryParts()->resetRestrictions();
641
            $q->select('*')
642
                ->from($variables['table'])
643
                ->where(
644
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$mmResult['uid_foreign'], \PDO::PARAM_INT))
645
                );
646
647
            $dbQueries[] = $q->getSQL();
648
649
            $selectResults = $q->execute()->fetchAll();
650
651
            foreach ($selectResults as $selectResult) {
652
                $configurationRow = [
653
                    'pid' => $selectResult['pid'],
654
                    'tstamp' => $selectResult['tstamp'],
655
                    'crdate' => $selectResult['crdate'],
656
                    'type' => 'time',
657
                    'handling' => 'include',
658
                    'start_date' => $this->migrateDate($selectResult['start_date']),
659
                    'end_date' => $this->migrateDate($selectResult['end_date']),
660
                    'start_time' => (int)$selectResult['start_time'],
661
                    'end_time' => (int)$selectResult['end_time'],
662
                    'all_day' => (null === $selectResult['start_time'] && null === $selectResult['end_time']) ? 1 : 0,
663
                    'frequency' => $this->mapFrequency($selectResult['freq']),
664
                    'till_date' => $this->migrateDate($selectResult['until']),
665
                    'counter_amount' => (int)$selectResult['cnt'],
666
                    'counter_interval' => (int)$selectResult['interval'],
667
                    'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
668
                ];
669
670
                $variables = [
671
                    'table' => self::CONFIGURATION_TABLE,
672
                    'configurationRow' => $configurationRow,
673
                ];
674
675
                $dispatcher = HelperUtility::getSignalSlotDispatcher();
676
                $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
677
678
                $q->resetQueryParts()->resetRestrictions();
679
                $q->insert($variables['table'])->values($variables['configurationRow']);
680
681
                $dbQueries[] = $q->getSQL();
682
683
                $q->execute();
684
685
                $recordIds[] = $db->lastInsertId($variables['table']);
686
            }
687
        }
688
689
        return \implode(',', $recordIds);
690
    }
691
692
    /**
693
     * Map frequency.
694
     *
695
     * @param string $calFrequency
696
     *
697
     * @return string
698
     */
699
    protected function mapFrequency($calFrequency)
700
    {
701
        $freq = [
702
            'none' => null,
703
            'day' => 'daily',
704
            'week' => 'weekly',
705
            'month' => 'monthly',
706
            'year' => 'yearly',
707
        ];
708
709
        if (!isset($freq[$calFrequency])) {
710
            return '';
711
        }
712
713
        return $freq[$calFrequency];
714
    }
715
716
    /**
717
     * Migrate the 'tx_cal_category' table to the 'sys_category' table.
718
     *
719
     * @param       $calIds
720
     * @param array $dbQueries
721
     * @param       $customMessages
722
     */
723
    protected function performSysCategoryUpdate($calIds, array &$dbQueries, &$customMessages)
724
    {
725
        // first migrate from tx_cal_category to sys_category
726
        $variables = [
727
            'table' => 'tx_cal_category',
728
            'dbQueries' => $dbQueries,
729
            'calIds' => $calIds,
730
        ];
731
732
        $db = HelperUtility::getDatabaseConnection($variables['table']);
733
        $q = $db->createQueryBuilder();
734
        $q->getRestrictions()
735
            ->removeAll()
736
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
737
738
        $q->select('*')
739
            ->from($variables['table']);
740
741
        $dbQueries[] = $q->getSQL();
742
743
        $selectResults = $q->execute()->fetchAll();
744
745
        foreach ($selectResults as $category) {
746
            $sysCategoryRecord = [
747
                'pid' => $category['pid'],
748
                'tstamp' => $category['tstamp'],
749
                'crdate' => $category['crdate'],
750
                'cruser_id' => $category['cruser_id'],
751
                'deleted' => $category['deleted'],
752
                'hidden' => $category['hidden'],
753
                'starttime' => $category['starttime'],
754
                'endtime' => $category['endtime'],
755
                'sys_language_uid' => $category['sys_language_uid'],
756
                'l10n_parent' => $category['l18n_parent'],
757
                'l10n_diffsource' => $category['l18n_diffsource'],
758
                'title' => $category['title'],
759
                'parent' => (int)$category['parent_category'],
760
                'import_id' => self::IMPORT_PREFIX . (int)$category['uid'],
761
                'sorting' => $category['sorting'],
762
            ];
763
764
            $q->resetQueryParts()->resetRestrictions();
765
766
            $q->insert('sys_category')->values($sysCategoryRecord);
767
            $dbQueries[] = $q->getSQL();
768
769
            $q->execute();
770
        }
771
772
        // second rewrite the tree
773
        $variables = [
774
            'table' => 'sys_category',
775
            'dbQueries' => $dbQueries,
776
            'calIds' => $calIds,
777
        ];
778
779
        $q->resetQueryParts()->resetRestrictions();
780
781
        $q->select('*')
782
            ->from($variables['table'])
783
            ->where(
784
                $q->expr()->neq('import_id', $q->createNamedParameter(''))
785
            );
786
787
        $dbQueries[] = $q->getSQL();
788
        $selectResults = $q->execute()->fetchAll();
789
790
        foreach ($selectResults as $sysCategory) {
791
            // update parent, because there are just the old uids
792
            $updateRecord = [
793
                'parent' => $this->getSysCategoryParentUid(self::IMPORT_PREFIX . (int)$sysCategory['parent']),
794
            ];
795
796
            $q->resetQueryParts()->resetRestrictions();
797
            $q->update('sys_category')
798
                ->where(
799
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$sysCategory['uid'], \PDO::PARAM_INT))
800
                )
801
                ->values($updateRecord);
802
803
            $dbQueries[] = $q->getSQL();
804
805
            $q->execute();
806
        }
807
    }
808
809
    /**
810
     * Return the parentUid for the 'sys_category' entry on base of the import_id.
811
     *
812
     * @param string $importId
813
     *
814
     * @return int
815
     */
816
    protected function getSysCategoryParentUid($importId)
817
    {
818
        $table = 'sys_category';
819
        $db = HelperUtility::getDatabaseConnection($table);
820
        $q = $db->createQueryBuilder();
821
822
        $q->select('uid')
823
            ->from($table)
824
            ->where(
825
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
826
            );
827
828
        $dbQueries[] = $q->getSQL();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$dbQueries was never initialized. Although not strictly required by PHP, it is generally a good practice to add $dbQueries = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
829
830
        $result = $q->execute()->fetchAll();
831
832
        return (int)$result['uid'];
833
    }
834
835
    /**
836
     * Get the event uid on base of the given import_id.
837
     * The import_id is the original tx_cal_event id prefixed with the IMPORT_PREFIX.
838
     *
839
     * @param string $importId
840
     * @param array  $dbQueries
841
     * @param array  $customMessages
842
     *
843
     * @return int
844
     */
845
    protected function getCalendarizeEventUid($importId, &$dbQueries, &$customMessages)
846
    {
847
        $variables = [
848
            'table' => self::EVENT_TABLE,
849
            'dbQueries' => $dbQueries,
850
        ];
851
852
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
853
854
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
855
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
856
857
        $q->select('uid')
858
            ->from($variables['table'])
859
            ->where(
860
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
861
            );
862
863
        $dbQueries[] = $q->getSQL();
864
865
        $result = $q->execute()->fetchAll();
866
        $uid = (int)$result['uid'];
867
868
        return $uid;
869
    }
870
871
    /**
872
     * Get the sys_category uid on base of the given import_id.
873
     * The import_id is the original tx_cal_category id prefixed with the IMPORT_PREFIX.
874
     *
875
     * @see CalMigrationUpdate::IMPORT_PREFIX
876
     *
877
     * @param string $importId
878
     * @param array  $dbQueries
879
     * @param array  $customMessages
880
     *
881
     * @return int
882
     */
883
    protected function getCalendarizeCategoryUid($importId, &$dbQueries, &$customMessages)
884
    {
885
        $variables = [
886
            'table' => 'sys_category',
887
            'dbQueries' => $dbQueries,
888
        ];
889
890
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
891
892
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
893
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
894
895
        $q->select('uid')
896
            ->from($variables['table'])
897
            ->where(
898
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
899
            );
900
901
        $dbQueries[] = $q->getSQL();
902
903
        $result = $q->execute()->fetchAll();
904
        $uid = (int)$result['uid'];
905
906
        return $uid;
907
    }
908
909
    /**
910
     * Build configurations.
911
     *
912
     * @param $calEventRow
913
     * @param $dbQueries
914
     *
915
     * @return int
916
     */
917
    protected function buildConfigurations($calEventRow, &$dbQueries)
918
    {
919
        $configurationRow = [
920
            'pid' => $calEventRow['pid'],
921
            'tstamp' => $calEventRow['tstamp'],
922
            'crdate' => $calEventRow['crdate'],
923
            'type' => 'time',
924
            'handling' => 'include',
925
            'start_date' => $this->migrateDate($calEventRow['start_date']),
926
            'end_date' => $this->migrateDate($calEventRow['end_date']),
927
            'start_time' => $calEventRow['start_time'],
928
            'end_time' => $calEventRow['end_time'],
929
            'all_day' => $calEventRow['allday'],
930
            'frequency' => $this->mapFrequency($calEventRow['freq']),
931
            'till_date' => $this->migrateDate($calEventRow['until']),
932
            'counter_amount' => (int)$calEventRow['cnt'],
933
            'counter_interval' => (int)$calEventRow['interval'],
934
        ];
935
936
        $variables = [
937
            'table' => self::CONFIGURATION_TABLE,
938
            'configurationRow' => $configurationRow,
939
            'calEventRow' => $calEventRow,
940
            'dbQueries' => $dbQueries,
941
        ];
942
943
        $db = HelperUtility::getDatabaseConnection($variables['table']);
944
        $q = $db->createQueryBuilder();
945
946
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
947
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
948
949
        $q->insert($variables['table'])
950
            ->values($variables['configurationRow']);
951
952
        $dbQueries[] = $q->getSQL();
953
        $q->execute();
954
        $recordId = $db->lastInsertId($variables['table']);
955
956
        $variables = [
957
            'table' => $variables['table'],
958
            'configurationRow' => $configurationRow,
959
            'calEventRow' => $calEventRow,
960
            'recordId' => $recordId,
961
            'dbQueries' => $dbQueries,
962
        ];
963
964
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
965
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variables);
966
967
        return $variables['recordId'];
968
    }
969
970
    /**
971
     * Migrate date.
972
     *
973
     * @param $oldFormat
974
     *
975
     * @return int|string
976
     */
977
    protected function migrateDate($oldFormat)
978
    {
979
        try {
980
            $date = new \DateTime((string)$oldFormat);
981
982
            return $date->getTimestamp();
983
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
984
        }
985
986
        return '';
987
    }
988
989
    /**
990
     * Get the non migrated cal IDs.
991
     *
992
     * @return array
993
     */
994
    protected function getNonMigratedCalIds()
995
    {
996
        if (!ExtensionManagementUtility::isLoaded('cal')) {
997
            return [];
998
        }
999
1000
        $checkImportIds = [];
1001
        $nonMigrated = [];
1002
1003
        $table = 'tx_cal_event';
1004
        $q = HelperUtility::getDatabaseConnection($table)->createQueryBuilder();
1005
        $q->getRestrictions()
1006
            ->removeAll()
1007
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1008
1009
        $events = $q->select('uid')
1010
            ->from($table)
1011
            ->execute()
1012
            ->fetchAll();
1013
1014
        foreach ($events as $event) {
1015
            $checkImportIds[] = '"' . self::IMPORT_PREFIX . $event['uid'] . '"';
1016
            $nonMigrated[(int)$event['uid']] = (int)$event['uid'];
1017
        }
1018
1019
        $countOriginal = \count($checkImportIds);
1020
        if (0 === $countOriginal) {
1021
            return [];
1022
        }
1023
1024
        $variables = [
1025
            'table' => self::EVENT_TABLE,
1026
        ];
1027
1028
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1029
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreSelect', $variables);
1030
1031
        $q->resetQueryParts();
1032
1033
        $migratedRows = $q->select('uid', 'import_id')
1034
            ->from($variables['table'])
1035
            ->where(
1036
                $q->expr()->in('import_id', $checkImportIds)
1037
            );
1038
1039
        foreach ($migratedRows as $migratedRow) {
1040
            $importId = (int)\str_replace(self::IMPORT_PREFIX, '', $migratedRow['import_id']);
1041
            if (isset($nonMigrated[$importId])) {
1042
                unset($nonMigrated[$importId]);
1043
            }
1044
        }
1045
1046
        $variables = [
1047
            'table' => $variables['table'],
1048
            'migratedRows' => $migratedRows,
1049
            'nonMigrated' => $nonMigrated,
1050
        ];
1051
1052
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1053
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'ReadyParsed', $variables);
1054
1055
        return $variables['nonMigrated'];
1056
    }
1057
1058
    public function getIdentifier(): string
1059
    {
1060
        return "calendarizeCalMigrationUpdate";
1061
    }
1062
1063
    public function getTitle(): string
1064
    {
1065
        return "";
1066
    }
1067
1068
    public function getDescription(): string
1069
    {
1070
        return "";
1071
    }
1072
1073
    public function updateNecessary(): bool
1074
    {
1075
        return false;
1076
    }
1077
1078
    public function getPrerequisites(): array
1079
    {
1080
        return [
1081
            DatabaseUpdatedPrerequisite::class
1082
        ];
1083
    }
1084
}
1085