Completed
Push — master ( c077bb...f1d6f8 )
by Tim
02:09
created

CalMigrationUpdate::addConfigurationIdToEvent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 4
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
 *  *@return array
30
 *  *
31
 * public function getCalendarizeEventUid()
32
 * {
33
 *    $args = func_get_args();
34
 *    list($table, $dbQueries, $call) = $args;
35
 *
36
 *    $variables = [
37
 *        'table'     => self::EVENT_TABLE,
38
 *        'dbQueries' => $dbQueries
39
 *    ];
40
 *
41
 *    return $variables;
42
 * }
43
 */
44
class CalMigrationUpdate extends AbstractUpdate
45
{
46
    /**
47
     * Import prefix.
48
     */
49
    const IMPORT_PREFIX = 'calMigration:';
50
51
    /**
52
     * Event table.
53
     */
54
    const EVENT_TABLE = 'tx_calendarize_domain_model_event';
55
56
    /**
57
     * Configuration table.
58
     */
59
    const CONFIGURATION_TABLE = 'tx_calendarize_domain_model_configuration';
60
61
    /**
62
     * ConfigurationGroup table.
63
     */
64
    const CONFIGURATION_GROUP_TABLE = 'tx_calendarize_domain_model_configurationgroup';
65
66
    /**
67
     * The human-readable title of the upgrade wizard.
68
     *
69
     * @var string
70
     */
71
    protected $title = 'Migrate cal event structures to the new calendarize event structures.
72
    Try to migrate all cal information and place the new calendarize event models in the same folder
73
    as the cal-records. Please note: the migration will be create calendarize default models.';
74
75
    /**
76
     * Checks whether updates are required.
77
     *
78
     * @param string &$description The description for the update
79
     *
80
     * @return bool Whether an update is required (TRUE) or not (FALSE)
81
     */
82
    public function checkForUpdate(&$description)
83
    {
84
        $nonMigratedCalIds = $this->getNonMigratedCalIds();
85
        $count = \count($nonMigratedCalIds);
86
        if (0 === $count) {
87
            return false;
88
        }
89
        $description = 'There ' . ($count > 1 ? 'are ' . $count : 'is ' . $count) . ' non migrated EXT:cal event
90
        ' . ($count > 1 ? 's' : '') . '. Run the update process to migrate the events to EXT:calendarize events.';
91
92
        return true;
93
    }
94
95
    /**
96
     * Performs the accordant updates.
97
     *
98
     * @param array &$dbQueries      Queries done in this update
99
     * @param mixed &$customMessages Custom messages
100
     *
101
     * @return bool Whether everything went smoothly or not
102
     */
103
    public function executeUpdate(): bool
104
    {
105
        $calIds = $this->getNonMigratedCalIds();
106
        $dbQueries = [];
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
        $q->getRestrictions()
132
            ->removeAll()
133
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
134
135
        $locationTable = 'tx_cal_location';
136
        $locations = HelperUtility::getDatabaseConnection($locationTable)
137
            ->createQueryBuilder()
138
            ->select('*')
139
            ->from($locationTable)
140
            ->execute()
141
            ->fetchAll();
142
        $locationByUid = [];
143
        foreach ($locations as $location) {
144
            $locationByUid[$location['uid']] = $location['name'];
145
        }
146
147
        $events = $q->select('*')->from($table)->where(
148
            $q->expr()->in('uid', $calIds)
149
        )->execute()->fetchAll();
150
151
        foreach ($events as $event) {
152
            $calendarizeEventRecord = [
153
                'pid' => $event['pid'],
154
                'import_id' => self::IMPORT_PREFIX . (int)$event['uid'],
155
                'tstamp' => $event['tstamp'],
156
                'crdate' => $event['crdate'],
157
                'hidden' => $event['hidden'],
158
                'starttime' => $event['starttime'],
159
                'endtime' => $event['endtime'],
160
                'title' => $event['title'],
161
                'organizer' => $event['organizer'],
162
                'location' => $event['location_id'] > 0 ? $locationByUid[$event['location_id']] : $event['location'],
163
                'abstract' => $event['teaser'],
164
                'description' => $event['description'],
165
                'images' => $event['image'],
166
                'downloads' => $event['attachment'],
167
                'calendarize' => $this->buildConfigurations($event, $dbQueries),
168
            ];
169
170
            $variables = [
171
                'calendarizeEventRecord' => $calendarizeEventRecord,
172
                'event' => $event,
173
                'table' => self::EVENT_TABLE,
174
                'dbQueries' => $dbQueries,
175
            ];
176
177
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
178
            $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
179
180
            $q->insert($variables['table'])->values($variables['calendarizeEventRecord']);
181
            $dbQueries[] = $q->getSQL();
182
183
            $q->execute();
184
185
            $variablesPostInsert = [
186
                'calendarizeEventRecord' => $calendarizeEventRecord,
187
                'event' => $event,
188
                'table' => $variables['table'],
189
                'recordId' => $db->lastInsertId($variables['table']),
190
                'dbQueries' => $dbQueries,
191
            ];
192
193
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
194
            $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variablesPostInsert);
195
        }
196
197
        $indexer = GeneralUtility::makeInstance(IndexerService::class);
198
        $indexer->reindexAll();
199
200
        return true;
201
    }
202
203
    /**
204
     * Perform exception event update.
205
     *
206
     * @param       $calIds
207
     * @param array $dbQueries
208
     * @param array $customMessages
209
     *
210
     * @return bool
211
     */
212
    public function performExceptionEventUpdate($calIds, &$dbQueries, &$customMessages)
213
    {
214
        $table = 'tx_cal_exception_event_group';
215
        // ConfigurationGroup für jede ExceptionGroup
216
        $db = HelperUtility::getDatabaseConnection($table);
217
        $q = $db->createQueryBuilder();
218
219
        $variables = [
220
            'table' => $table,
221
            'dbQueries' => $dbQueries,
222
            'calIds' => $calIds,
223
        ];
224
225
        $q->getRestrictions()
226
            ->removeAll()
227
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
228
229
        $q->select('*')->from($variables['table']);
230
231
        $selectResults = $q->execute()->fetchAll();
232
        $dbQueries[] = $q->getSQL();
233
234
        foreach ($selectResults as $selectResult) {
235
            $group = [
236
                'pid' => $selectResult['pid'],
237
                'tstamp' => $selectResult['tstamp'],
238
                'crdate' => $selectResult['crdate'],
239
                'cruser_id' => $selectResult['cruser_id'],
240
                'title' => $selectResult['title'],
241
                'configurations' => $this->getExceptionConfigurationForExceptionGroup($selectResult['uid'], $dbQueries),
242
                'hidden' => $selectResult['hidden'],
243
                'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
244
            ];
245
246
            $q->insert(self::CONFIGURATION_GROUP_TABLE)->values($group);
247
            $dbQueries[] = $q->getSQL();
248
249
            $q->execute();
250
        }
251
252
        return true;
253
    }
254
255
    /**
256
     * Perform link event to configuration group.
257
     *
258
     * @param $calIds
259
     * @param $dbQueries
260
     * @param $customMessages
261
     *
262
     * @return bool
263
     */
264
    public function performLinkEventToConfigurationGroup($calIds, &$dbQueries, &$customMessages)
265
    {
266
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_GROUP_TABLE);
267
        $q = $db->createQueryBuilder();
268
        $now = new \DateTime();
269
270
        $variables = [
271
            'table' => self::CONFIGURATION_GROUP_TABLE,
272
            'dbQueries' => $dbQueries,
273
            'calIds' => $calIds,
274
        ];
275
276
        $selectResults = $q->select('*')->from($variables['table'])->execute()->fetchAll();
277
        $dbQueries[] = $q->getSQL();
278
279
        foreach ($selectResults as $group) {
280
            $importId = explode(':', $group['import_id']);
281
            $groupId = (int)$importId[1];
282
283
            $variables = [
284
                'table' => 'tx_cal_exception_event_mm',
285
                'dbQueries' => $dbQueries,
286
                'calIds' => $calIds,
287
            ];
288
289
            $q->resetQueryParts()->resetRestrictions();
290
291
            $q->select('uid_local')
292
                ->from($variables['table'])
293
                ->where(
294
                    $q->expr()->andX(
295
                        $q->expr()->eq('tablenames', 'tx_cal_exception_event_group'),
296
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT))
297
                    )
298
                );
299
300
            $dbQueries[] = $q->getSQL();
301
            $selectResults = $q->execute()->fetchAll();
302
303
            foreach ($selectResults as $eventUid) {
304
                $eventImportId = self::IMPORT_PREFIX . (int)$eventUid['uid_local'];
305
                $configurationRow = [
306
                    'pid' => (int)$group['pid'],
307
                    'tstamp' => $now->getTimestamp(),
308
                    'crdate' => $now->getTimestamp(),
309
                    'type' => 'group',
310
                    'handling' => 'exclude',
311
                    'groups' => $group['uid'],
312
                ];
313
314
                $this->updateEventWithConfiguration($eventImportId, $configurationRow, $dbQueries, $customMessages);
315
            }
316
        }
317
318
        return true;
319
    }
320
321
    /**
322
     * Migrate the 'sys_file_reference' entries from 'tx_cal_event' to 'tx_calendarize_domain_model_event'.
323
     * Mark the imported entries with the import-id.
324
     *
325
     * @param       $calIds
326
     * @param array $dbQueries
327
     * @param       $customMessages
328
     */
329
    public function performSysFileReferenceUpdate($calIds, array &$dbQueries, &$customMessages)
330
    {
331
        $db = HelperUtility::getDatabaseConnection('tx_cal_event');
332
        $q = $db->createQueryBuilder();
333
334
        $variables = [
335
            'table' => 'tx_cal_event',
336
            'fieldnames' => ['image', 'attachment'],
337
            'dbQueries' => $dbQueries,
338
            'calIds' => $calIds,
339
        ];
340
341
        // select all not migrated entries
342
        $fieldnames = 'fieldname = \'' . implode('\' OR fieldname = \'', $variables['fieldnames']) . '\'';
343
        $selectWhere = 'tablenames = \'' . $variables['table'] . '\' AND (' . $fieldnames . ')';
344
        $selectWhere .= ' AND NOT EXISTS (SELECT NULL FROM sys_file_reference sfr2 WHERE sfr2.import_id = CONCAT(\'' . self::IMPORT_PREFIX . '\', sfr1.uid))';
345
346
        $q->select('*')
347
            ->from('sys_file_reference', 'sfr1')
348
            ->where($selectWhere);
349
350
        $dbQueries[] = $q->getSQL();
351
        $selectResults = $q->execute()->fetchAll();
352
353
        $variables = [
354
            'table' => self::EVENT_TABLE,
355
            'fieldnames' => $variables['fieldnames'],
356
            'dbQueries' => $dbQueries,
357
            'calIds' => $calIds,
358
            'selectResults' => $selectResults,
359
        ];
360
361
        // create new entry with import_id
362
        foreach ($variables['selectResults'] as $selectResult) {
363
            $selectResult['tablenames'] = $variables['table'];
364
            $selectResult['import_id'] = self::IMPORT_PREFIX . $selectResult['uid'];
365
            $selectResult['fieldname'] = ('image' === $selectResult['fieldname']) ? 'images' : 'downloads';
366
            unset($selectResult['uid_foreign'], $selectResult['uid']);
367
368
            $q->resetQueryParts()->resetRestrictions();
369
            $q->insert('sys_file_reference')->values($selectResult);
370
371
            $dbQueries[] = $q->getSQL();
372
373
            $q->execute();
374
        }
375
    }
376
377
    /**
378
     * Link the Events to the migrated Categories.
379
     * This build up the 'sys_category_record_mm' table on base of the 'tx_cal_event_category_mm' table.
380
     *
381
     * @param       $calIds
382
     * @param array $dbQueries
383
     * @param array $customMessages
384
     */
385
    public function performLinkEventToCategory($calIds, &$dbQueries, &$customMessages)
386
    {
387
        $table = 'tx_cal_event_category_mm';
388
389
        $db = HelperUtility::getDatabaseConnection($table);
390
        $q = $db->createQueryBuilder();
391
392
        $q->select('*')->from($table);
393
        $dbQueries[] = $q->getSQL();
394
395
        $selectResults = $q->execute()->fetchAll();
396
397
        $variables = [
398
            'tablenames' => self::EVENT_TABLE,
399
            'fieldname' => 'categories',
400
            'dbQueries' => $dbQueries,
401
        ];
402
403
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
404
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
405
406
        foreach ($selectResults as $mm) {
407
            $eventUid = (int)$this->getCalendarizeEventUid(self::IMPORT_PREFIX . $mm['uid_local'], $dbQueries, $customMessages);
408
            $categoryUid = (int)$this->getCalendarizeCategoryUid(
409
                self::IMPORT_PREFIX . $mm['uid_foreign'],
410
                $dbQueries,
411
                $customMessages
412
            );
413
414
            if($eventUid !== 0 && $categoryUid !== 0) {
415
                $insertValues = [
416
                    'uid_local' => $categoryUid,
417
                    'uid_foreign' => $eventUid,
418
                    'tablenames' => $variables['tablenames'],
419
                    'fieldname' => $variables['fieldname'],
420
                ];
421
422
                $q->insert('sys_category_record_mm')->values($insertValues);
423
                $dbQueries[] = $q->getSQL();
424
425
                $q->execute();
426
            }
427
        }
428
    }
429
430
    /**
431
     * Update event with configuration.
432
     *
433
     * @param $eventImportId
434
     * @param $configuration
435
     * @param $dbQueries
436
     * @param $customMessages
437
     *
438
     * @return array
439
     */
440
    protected function updateEventWithConfiguration($eventImportId, $configuration, &$dbQueries, &$customMessages)
441
    {
442
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_TABLE);
443
        $q = $db->createQueryBuilder();
444
445
        $configurationRow = $this->findEventExcludeConfiguration($eventImportId, $dbQueries, $customMessages);
446
        if ($configurationRow) {
447
            $configurationRow['groups'] = $this->addValueToCsv($configurationRow['groups'], $configuration['groups']);
448
449
            unset($configurationRow['uid']);
450
451
            $q->update(self::CONFIGURATION_GROUP_TABLE)
452
                ->where('uid', $q->createNamedParameter((int)$configuration['uid'], \PDO::PARAM_INT));
453
            foreach ($configurationRow as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $configurationRow of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
454
                $q->set($key, $value);
455
            }
456
457
            $dbQueries[] = $q->getSQL();
458
            $results = $q->execute();
459
        } else {
460
            $q->insert(self::CONFIGURATION_TABLE)->values($configuration);
461
            $dbQueries[] = $q->getSQL();
462
463
            $configurationId = $db->lastInsertId(self::CONFIGURATION_TABLE);
464
465
            $results = $this->addConfigurationIdToEvent($eventImportId, $configurationId, $dbQueries, $customMessages);
466
        }
467
468
        return $results;
469
    }
470
471
    /**
472
     * Add Value to CSV.
473
     *
474
     * @param string $csv
475
     * @param string $value
476
     *
477
     * @return string
478
     */
479
    protected function addValueToCsv($csv, $value)
480
    {
481
        $csvArray = GeneralUtility::trimExplode(',', $csv);
482
483
        // check for doubles
484
        $values = array_flip($csvArray);
485
        if (isset($values[$value])) {
486
            return $csv;
487
        }
488
        $csvArray[] = $value;
489
        $csv = implode(',', $csvArray);
490
491
        return $csv;
492
    }
493
494
    /**
495
     * Add configuration ID to event.
496
     *
497
     * @param string $eventImportId
498
     * @param int    $configurationId
499
     * @param array  $dbQueries
500
     * @param array  $customMessages
501
     *
502
     * @return array|bool
503
     */
504
    protected function addConfigurationIdToEvent($eventImportId, $configurationId, &$dbQueries, &$customMessages)
505
    {
506
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
507
        if (!$event) {
508
            return false;
509
        }
510
511
        $event['calendarize'] = $this->addValueToCsv($event['calendarize'], $configurationId);
512
513
        return $this->updateEvent($event['uid'], $event, $dbQueries, $customMessages);
514
    }
515
516
    /**
517
     * Update event.
518
     *
519
     * @param int   $eventId
520
     * @param array $values
521
     * @param array $dbQueries
522
     * @param array $customMessages
523
     *
524
     * @return array
525
     */
526
    protected function updateEvent($eventId, $values, &$dbQueries, &$customMessages)
527
    {
528
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
529
        $q = $db->createQueryBuilder();
530
531
        $variables = [
532
            'table' => self::EVENT_TABLE,
533
            'eventId' => (int)$eventId,
534
            'values' => $values,
535
            'dbQueries' => $dbQueries,
536
        ];
537
538
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
539
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
540
541
        $q->update($variables['table'])
542
            ->where(
543
                $q->expr()->eq('uid', $q->createNamedParameter((int)$eventId, \PDO::PARAM_INT))
544
            );
545
        foreach ($variables['values'] as $key => $value) {
546
            $q->set($key, $value);
547
        }
548
549
        unset($values['uid']);
550
551
        $dbQueries[] = $q->getSQL();
552
553
        return $q->execute()->fetchAll();
554
    }
555
556
    /**
557
     * Find event by import ID.
558
     *
559
     * @param $eventImportId
560
     * @param $dbQueries
561
     * @param $customMessages
562
     *
563
     * @return array|bool
564
     */
565
    protected function findEventByImportId($eventImportId, &$dbQueries, &$customMessages)
566
    {
567
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
568
        $q = $db->createQueryBuilder();
569
570
        $variables = [
571
            'table' => self::EVENT_TABLE,
572
            'dbQueries' => $dbQueries,
573
            'eventImportId' => $eventImportId,
574
        ];
575
576
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
577
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
578
579
        $q->select('*')->from($variables['table'])
580
            ->where(
581
                $q->expr()->eq('import_id', $q->createNamedParameter($eventImportId))
582
            );
583
584
        $dbQueries[] = $q->getSQL();
585
586
        return $q->execute()->fetchAll();
587
    }
588
589
    /**
590
     * Find event exclude configuration.
591
     *
592
     * @param string $eventImportId
593
     * @param array  $dbQueries
594
     * @param array  $customMessages
595
     *
596
     * @return array|bool
597
     */
598
    protected function findEventExcludeConfiguration($eventImportId, &$dbQueries, &$customMessages)
599
    {
600
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
601
602
        if (!$event) {
603
            return false;
604
        }
605
606
        $variables = [
607
            'table' => self::CONFIGURATION_TABLE,
608
            'dbQueries' => $dbQueries,
609
            'event' => $event,
610
        ];
611
612
        $db = HelperUtility::getDatabaseConnection($variables['table']);
613
        $q = $db->createQueryBuilder();
614
615
        $q->select('*')
616
            ->from($variables['table'])
617
            ->where(
618
                $q->expr()->andX(
619
                    $q->expr()->eq('type', 'group'),
620
                    $q->expr()->eq('handling', 'exclude'),
621
                    $q->expr()->in('uid', $variables['event']['calendarize'])
622
                )
623
            );
624
625
        $dbQueries[] = $q->getSQL();
626
627
        return $q->execute()->fetchAll();
628
    }
629
630
    /**
631
     * Get exception configuration for exception group.
632
     *
633
     * @param       $groupId
634
     * @param array $dbQueries
635
     *
636
     * @return string
637
     */
638
    protected function getExceptionConfigurationForExceptionGroup($groupId, &$dbQueries)
639
    {
640
        $recordIds = [];
641
        $variables = [
642
            'table' => 'tx_cal_exception_event_group_mm',
643
            'dbQueries' => $dbQueries,
644
        ];
645
646
        $db = HelperUtility::getDatabaseConnection($variables['table']);
647
        $q = $db->createQueryBuilder();
648
649
        $q->select('*')
650
            ->from($variables['table'])
651
            ->where('uid_local', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT));
652
653
        $dbQueries[] = $q->getSQL();
654
655
        $mmResults = $q->execute()->fetchAll();
656
        foreach ($mmResults as $mmResult) {
657
            $variables = [
658
                'table' => 'tx_cal_exception_event',
659
                'dbQueries' => $dbQueries,
660
            ];
661
662
            $q->resetQueryParts()->resetRestrictions();
663
            $q->select('*')
664
                ->from($variables['table'])
665
                ->where(
666
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$mmResult['uid_foreign'], \PDO::PARAM_INT))
667
                );
668
669
            $dbQueries[] = $q->getSQL();
670
671
            $selectResults = $q->execute()->fetchAll();
672
673
            foreach ($selectResults as $selectResult) {
674
                $configurationRow = [
675
                    'pid' => $selectResult['pid'],
676
                    'tstamp' => $selectResult['tstamp'],
677
                    'crdate' => $selectResult['crdate'],
678
                    'type' => 'time',
679
                    'handling' => 'include',
680
                    'start_date' => $this->migrateDate($selectResult['start_date']),
681
                    'end_date' => $this->migrateDate($selectResult['end_date']),
682
                    'start_time' => (int)$selectResult['start_time'],
683
                    'end_time' => (int)$selectResult['end_time'],
684
                    'all_day' => (null === $selectResult['start_time'] && null === $selectResult['end_time']) ? 1 : 0,
685
                    'frequency' => $this->mapFrequency($selectResult['freq']),
686
                    'till_date' => $this->migrateDate($selectResult['until']),
687
                    'counter_amount' => (int)$selectResult['cnt'],
688
                    'counter_interval' => (int)$selectResult['interval'],
689
                    'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
690
                ];
691
692
                $variables = [
693
                    'table' => self::CONFIGURATION_TABLE,
694
                    'configurationRow' => $configurationRow,
695
                ];
696
697
                $dispatcher = HelperUtility::getSignalSlotDispatcher();
698
                $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
699
700
                $q->resetQueryParts()->resetRestrictions();
701
                $q->insert($variables['table'])->values($variables['configurationRow']);
702
703
                $dbQueries[] = $q->getSQL();
704
705
                $q->execute();
706
707
                $recordIds[] = $db->lastInsertId($variables['table']);
708
            }
709
        }
710
711
        return implode(',', $recordIds);
712
    }
713
714
    /**
715
     * Map frequency.
716
     *
717
     * @param string $calFrequency
718
     *
719
     * @return string
720
     */
721
    protected function mapFrequency($calFrequency)
722
    {
723
        $freq = [
724
            'none' => null,
725
            'day' => 'daily',
726
            'week' => 'weekly',
727
            'month' => 'monthly',
728
            'year' => 'yearly',
729
        ];
730
731
        if (!isset($freq[$calFrequency])) {
732
            return '';
733
        }
734
735
        return $freq[$calFrequency];
736
    }
737
738
    /**
739
     * Migrate the 'tx_cal_category' table to the 'sys_category' table.
740
     *
741
     * @param       $calIds
742
     * @param array $dbQueries
743
     * @param       $customMessages
744
     */
745
    protected function performSysCategoryUpdate($calIds, array &$dbQueries, &$customMessages)
746
    {
747
        // first migrate from tx_cal_category to sys_category
748
        $variables = [
749
            'table' => 'tx_cal_category',
750
            'dbQueries' => $dbQueries,
751
            'calIds' => $calIds,
752
        ];
753
754
        $db = HelperUtility::getDatabaseConnection($variables['table']);
755
        $q = $db->createQueryBuilder();
756
        $q->getRestrictions()
757
            ->removeAll()
758
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
759
760
        $q->select('*')
761
            ->from($variables['table']);
762
763
        $dbQueries[] = $q->getSQL();
764
765
        $selectResults = $q->execute()->fetchAll();
766
767
        foreach ($selectResults as $category) {
768
            $sysCategoryRecord = [
769
                'pid' => $category['pid'],
770
                'tstamp' => $category['tstamp'],
771
                'crdate' => $category['crdate'],
772
                'cruser_id' => $category['cruser_id'],
773
                'deleted' => $category['deleted'],
774
                'hidden' => $category['hidden'],
775
                'starttime' => $category['starttime'],
776
                'endtime' => $category['endtime'],
777
                'sys_language_uid' => $category['sys_language_uid'],
778
                'l10n_parent' => $category['l18n_parent'],
779
                'l10n_diffsource' => $category['l18n_diffsource'],
780
                'title' => $category['title'],
781
                'parent' => (int)$category['parent_category'],
782
                'import_id' => self::IMPORT_PREFIX . (int)$category['uid'],
783
                'sorting' => $category['sorting'],
784
            ];
785
786
            $q->resetQueryParts()->resetRestrictions();
787
788
            $q->insert('sys_category')->values($sysCategoryRecord);
789
            $dbQueries[] = $q->getSQL();
790
791
            $q->execute();
792
        }
793
794
        // second rewrite the tree
795
        $variables = [
796
            'table' => 'sys_category',
797
            'dbQueries' => $dbQueries,
798
            'calIds' => $calIds,
799
        ];
800
801
        $q->resetQueryParts()->resetRestrictions();
802
803
        $q->select('*')
804
            ->from($variables['table'])
805
            ->where(
806
                $q->expr()->neq('import_id', $q->createNamedParameter(''))
807
            );
808
809
        $dbQueries[] = $q->getSQL();
810
        $selectResults = $q->execute()->fetchAll();
811
812
        foreach ($selectResults as $sysCategory) {
813
            // update parent, because there are just the old uids
814
            $q->resetQueryParts()->resetRestrictions();
815
            $q->update('sys_category')
816
                ->where(
817
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$sysCategory['uid'], \PDO::PARAM_INT))
818
                )->set(
819
                    'parent',
820
                    $this->getSysCategoryParentUid(self::IMPORT_PREFIX . (int) $sysCategory['parent'])
821
                );
822
823
            $dbQueries[] = $q->getSQL();
824
825
            $q->execute();
826
        }
827
    }
828
829
    /**
830
     * Return the parentUid for the 'sys_category' entry on base of the import_id.
831
     *
832
     * @param string $importId
833
     *
834
     * @return int
835
     */
836
    protected function getSysCategoryParentUid($importId)
837
    {
838
        $table = 'sys_category';
839
        $db = HelperUtility::getDatabaseConnection($table);
840
        $q = $db->createQueryBuilder();
841
842
        $q->select('uid')
843
            ->from($table)
844
            ->where(
845
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
846
            );
847
848
        $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...
849
850
        $result = $q->execute()->fetchAll();
851
852
        return (int)$result[0]['uid'];
853
    }
854
855
    /**
856
     * Get the event uid on base of the given import_id.
857
     * The import_id is the original tx_cal_event id prefixed with the IMPORT_PREFIX.
858
     *
859
     * @param string $importId
860
     * @param array  $dbQueries
861
     * @param array  $customMessages
862
     *
863
     * @return int
864
     */
865
    protected function getCalendarizeEventUid($importId, &$dbQueries, &$customMessages)
866
    {
867
        $variables = [
868
            'table' => self::EVENT_TABLE,
869
            'dbQueries' => $dbQueries,
870
        ];
871
872
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
873
874
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
875
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
876
877
        $q->select('uid')
878
            ->from($variables['table'])
879
            ->where(
880
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
881
            );
882
883
        $dbQueries[] = $q->getSQL();
884
885
        $result = $q->execute()->fetchAll();
886
        return (int)$result[0]['uid'];
887
    }
888
889
    /**
890
     * Get the sys_category uid on base of the given import_id.
891
     * The import_id is the original tx_cal_category id prefixed with the IMPORT_PREFIX.
892
     *
893
     * @see CalMigrationUpdate::IMPORT_PREFIX
894
     *
895
     * @param string $importId
896
     * @param array  $dbQueries
897
     * @param array  $customMessages
898
     *
899
     * @return int
900
     */
901
    protected function getCalendarizeCategoryUid($importId, &$dbQueries, &$customMessages)
902
    {
903
        $variables = [
904
            'table' => 'sys_category',
905
            'dbQueries' => $dbQueries,
906
        ];
907
908
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
909
910
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
911
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
912
913
        $q->select('uid')
914
            ->from($variables['table'])
915
            ->where(
916
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
917
            );
918
919
        $dbQueries[] = $q->getSQL();
920
921
        $result = $q->execute()->fetchAll();
922
        return (int)$result[0]['uid'];
923
    }
924
925
    /**
926
     * Build configurations.
927
     *
928
     * @param $calEventRow
929
     * @param $dbQueries
930
     *
931
     * @return int
932
     */
933
    protected function buildConfigurations($calEventRow, &$dbQueries)
934
    {
935
        $configurationRow = [
936
            'pid' => $calEventRow['pid'],
937
            'tstamp' => $calEventRow['tstamp'],
938
            'crdate' => $calEventRow['crdate'],
939
            'type' => 'time',
940
            'handling' => 'include',
941
            'start_date' => $this->migrateDate($calEventRow['start_date']),
942
            'end_date' => $this->migrateDate($calEventRow['end_date']),
943
            'start_time' => $calEventRow['start_time'],
944
            'end_time' => $calEventRow['end_time'],
945
            'all_day' => $calEventRow['allday'],
946
            'frequency' => $this->mapFrequency($calEventRow['freq']),
947
            'till_date' => $this->migrateDate($calEventRow['until']),
948
            'counter_amount' => (int)$calEventRow['cnt'],
949
            'counter_interval' => (int)$calEventRow['interval'],
950
        ];
951
952
        $variables = [
953
            'table' => self::CONFIGURATION_TABLE,
954
            'configurationRow' => $configurationRow,
955
            'calEventRow' => $calEventRow,
956
            'dbQueries' => $dbQueries,
957
        ];
958
959
        $db = HelperUtility::getDatabaseConnection($variables['table']);
960
        $q = $db->createQueryBuilder();
961
962
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
963
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
964
965
        $q->insert($variables['table'])
966
            ->values($variables['configurationRow']);
967
968
        $dbQueries[] = $q->getSQL();
969
        $q->execute();
970
        $recordId = $db->lastInsertId($variables['table']);
971
972
        $variables = [
973
            'table' => $variables['table'],
974
            'configurationRow' => $configurationRow,
975
            'calEventRow' => $calEventRow,
976
            'recordId' => $recordId,
977
            'dbQueries' => $dbQueries,
978
        ];
979
980
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
981
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variables);
982
983
        return $variables['recordId'];
984
    }
985
986
    /**
987
     * Migrate date.
988
     *
989
     * @param $oldFormat
990
     *
991
     * @return int|string
992
     */
993
    protected function migrateDate($oldFormat)
994
    {
995
        try {
996
            $date = new \DateTime((string)$oldFormat);
997
998
            return $date->getTimestamp();
999
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1000
        }
1001
1002
        return '';
1003
    }
1004
1005
    /**
1006
     * Get the non migrated cal IDs.
1007
     *
1008
     * @return array
1009
     */
1010
    protected function getNonMigratedCalIds()
1011
    {
1012
        if (!ExtensionManagementUtility::isLoaded('cal')) {
1013
            return [];
1014
        }
1015
1016
        $checkImportIds = [];
1017
        $nonMigrated = [];
1018
1019
        $table = 'tx_cal_event';
1020
        $q = HelperUtility::getDatabaseConnection($table)->createQueryBuilder();
1021
        $q->getRestrictions()
1022
            ->removeAll()
1023
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1024
1025
        $events = $q->select('uid')
1026
            ->from($table)
1027
            ->execute()
1028
            ->fetchAll();
1029
1030
        foreach ($events as $event) {
1031
            $checkImportIds[] = '"' . self::IMPORT_PREFIX . $event['uid'] . '"';
1032
            $nonMigrated[(int)$event['uid']] = (int)$event['uid'];
1033
        }
1034
1035
        $countOriginal = \count($checkImportIds);
1036
        if (0 === $countOriginal) {
1037
            return [];
1038
        }
1039
1040
        $variables = [
1041
            'table' => self::EVENT_TABLE,
1042
        ];
1043
1044
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1045
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreSelect', $variables);
1046
1047
        $q->resetQueryParts();
1048
1049
        $migratedRows = $q->select('uid', 'import_id')
1050
            ->from($variables['table'])
1051
            ->where(
1052
                $q->expr()->in('import_id', $checkImportIds)
1053
            )
1054
            ->execute()
1055
            ->fetchAll();
1056
1057
        foreach ($migratedRows as $migratedRow) {
1058
            $importId = (int)str_replace(self::IMPORT_PREFIX, '', $migratedRow['import_id']);
1059
            if (isset($nonMigrated[$importId])) {
1060
                unset($nonMigrated[$importId]);
1061
            }
1062
        }
1063
1064
        $variables = [
1065
            'table' => $variables['table'],
1066
            'migratedRows' => $migratedRows,
1067
            'nonMigrated' => $nonMigrated,
1068
        ];
1069
1070
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1071
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'ReadyParsed', $variables);
1072
1073
        return $variables['nonMigrated'];
1074
    }
1075
1076
    public function updateNecessary(): bool
1077
    {
1078
        return false;
1079
    }
1080
1081
    public function getPrerequisites(): array
1082
    {
1083
        return [
1084
            DatabaseUpdatedPrerequisite::class,
1085
        ];
1086
    }
1087
}
1088