Completed
Push — master ( 622973...64593a )
by Tim
24s queued 11s
created

CalMigrationUpdate   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 1034
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 61
lcom 1
cbo 6
dl 0
loc 1034
rs 2.984
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A checkForUpdate() 0 12 4
A executeUpdate() 0 16 2
B performCalEventUpdate() 0 76 4
A performExceptionEventUpdate() 0 42 2
B performLinkEventToConfigurationGroup() 0 56 3
A performSysFileReferenceUpdate() 0 47 3
A performLinkEventToCategory() 0 44 4
A updateEventWithConfiguration() 0 30 3
A addValueToCsv() 0 14 2
A addConfigurationIdToEvent() 0 11 2
A updateEvent() 0 29 2
A findEventByImportId() 0 23 1
A findEventExcludeConfiguration() 0 31 2
B getExceptionConfigurationForExceptionGroup() 0 75 8
A mapFrequency() 0 16 2
B performSysCategoryUpdate() 0 83 3
A getSysCategoryParentUid() 0 18 1
A getCalendarizeEventUid() 0 24 1
A getCalendarizeCategoryUid() 0 24 1
A buildConfigurations() 0 52 4
B getNonMigratedCalIds() 0 61 5
A updateNecessary() 0 12 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\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
        $this->performSysCategoryUpdate($calIds, $dbQueries, $customMessages);
110
        $this->performSysFileReferenceUpdate($calIds, $dbQueries, $customMessages);
111
        $this->performExceptionEventUpdate($calIds, $dbQueries, $customMessages);
112
        $this->performCalEventUpdate($calIds, $dbQueries, $customMessages);
113
        $this->performLinkEventToCategory($calIds, $dbQueries, $customMessages);
114
        $this->performLinkEventToConfigurationGroup($calIds, $dbQueries, $customMessages);
115
116
        return true;
117
    }
118
119
    /**
120
     * Perform CAL event update.
121
     *
122
     * @param       $calIds
123
     * @param array $dbQueries
124
     * @param       $customMessages
125
     *
126
     * @return bool
127
     */
128
    public function performCalEventUpdate($calIds, array &$dbQueries, &$customMessages)
129
    {
130
        $table = 'tx_cal_event';
131
        $db = HelperUtility::getDatabaseConnection($table);
132
        $q = $db->createQueryBuilder();
133
        $q->getRestrictions()
134
            ->removeAll()
135
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
136
137
        $locationTable = 'tx_cal_location';
138
        $locations = HelperUtility::getDatabaseConnection($locationTable)
139
            ->createQueryBuilder()
140
            ->select('*')
141
            ->from($locationTable)
142
            ->execute()
143
            ->fetchAll();
144
        $locationByUid = [];
145
        foreach ($locations as $location) {
146
            $locationByUid[$location['uid']] = $location['name'];
147
        }
148
149
        $events = $q->select('*')->from($table)->where(
150
            $q->expr()->in('uid', $calIds)
151
        )->execute()->fetchAll();
152
153
        foreach ($events as $event) {
154
            $calendarizeEventRecord = [
155
                'pid' => $event['pid'],
156
                'import_id' => self::IMPORT_PREFIX . (int)$event['uid'],
157
                'tstamp' => $event['tstamp'],
158
                'crdate' => $event['crdate'],
159
                'hidden' => $event['hidden'],
160
                'starttime' => $event['starttime'],
161
                'endtime' => $event['endtime'],
162
                'title' => $event['title'],
163
                'organizer' => $event['organizer'],
164
                'location' => $event['location_id'] > 0 ? $locationByUid[$event['location_id']] : $event['location'],
165
                'abstract' => $event['teaser'],
166
                'description' => $event['description'],
167
                'images' => (int)$event['image'],
168
                'downloads' => (int)$event['attachment'],
169
                'calendarize' => $this->buildConfigurations($event, $dbQueries),
170
            ];
171
172
            $variables = [
173
                'calendarizeEventRecord' => $calendarizeEventRecord,
174
                'event' => $event,
175
                'table' => self::EVENT_TABLE,
176
                'dbQueries' => $dbQueries,
177
            ];
178
179
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
180
            $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
181
182
            $q->insert($variables['table'])->values($variables['calendarizeEventRecord']);
183
            $dbQueries[] = $q->getSQL();
184
185
            $q->execute();
186
187
            $variablesPostInsert = [
188
                'calendarizeEventRecord' => $calendarizeEventRecord,
189
                'event' => $event,
190
                'table' => $variables['table'],
191
                'recordId' => $db->lastInsertId($variables['table']),
192
                'dbQueries' => $dbQueries,
193
            ];
194
195
            $dispatcher = HelperUtility::getSignalSlotDispatcher();
196
            $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variablesPostInsert);
197
        }
198
199
        $indexer = GeneralUtility::makeInstance(IndexerService::class);
200
        $indexer->reindexAll();
201
202
        return true;
203
    }
204
205
    /**
206
     * Perform exception event update.
207
     *
208
     * @param       $calIds
209
     * @param array $dbQueries
210
     * @param array $customMessages
211
     *
212
     * @return bool
213
     */
214
    public function performExceptionEventUpdate($calIds, &$dbQueries, &$customMessages)
215
    {
216
        $table = 'tx_cal_exception_event_group';
217
        // ConfigurationGroup für jede ExceptionGroup
218
        $db = HelperUtility::getDatabaseConnection($table);
219
        $q = $db->createQueryBuilder();
220
221
        $variables = [
222
            'table' => $table,
223
            'dbQueries' => $dbQueries,
224
            'calIds' => $calIds,
225
        ];
226
227
        $q->getRestrictions()
228
            ->removeAll()
229
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
230
231
        $q->select('*')->from($variables['table']);
232
233
        $selectResults = $q->execute()->fetchAll();
234
        $dbQueries[] = $q->getSQL();
235
236
        foreach ($selectResults as $selectResult) {
237
            $group = [
238
                'pid' => $selectResult['pid'],
239
                'tstamp' => $selectResult['tstamp'],
240
                'crdate' => $selectResult['crdate'],
241
                'cruser_id' => $selectResult['cruser_id'],
242
                'title' => $selectResult['title'],
243
                'configurations' => $this->getExceptionConfigurationForExceptionGroup($selectResult['uid'], $dbQueries),
244
                'hidden' => $selectResult['hidden'],
245
                'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
246
            ];
247
248
            $q->insert(self::CONFIGURATION_GROUP_TABLE)->values($group);
249
            $dbQueries[] = $q->getSQL();
250
251
            $q->execute();
252
        }
253
254
        return true;
255
    }
256
257
    /**
258
     * Perform link event to configuration group.
259
     *
260
     * @param $calIds
261
     * @param $dbQueries
262
     * @param $customMessages
263
     *
264
     * @return bool
265
     */
266
    public function performLinkEventToConfigurationGroup($calIds, &$dbQueries, &$customMessages)
267
    {
268
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_GROUP_TABLE);
269
        $q = $db->createQueryBuilder();
270
        $now = new \DateTime();
271
272
        $variables = [
273
            'table' => self::CONFIGURATION_GROUP_TABLE,
274
            'dbQueries' => $dbQueries,
275
            'calIds' => $calIds,
276
        ];
277
278
        $selectResults = $q->select('*')->from($variables['table'])->execute()->fetchAll();
279
        $dbQueries[] = $q->getSQL();
280
281
        foreach ($selectResults as $group) {
282
            $importId = explode(':', $group['import_id']);
283
            $groupId = (int)$importId[1];
284
285
            $variables = [
286
                'table' => 'tx_cal_exception_event_mm',
287
                'dbQueries' => $dbQueries,
288
                'calIds' => $calIds,
289
            ];
290
291
            $q->resetQueryParts()->resetRestrictions();
292
293
            $q->select('uid_local')
294
                ->from($variables['table'])
295
                ->where(
296
                    $q->expr()->andX(
297
                        $q->expr()->eq('tablenames', $q->createNamedParameter('tx_cal_exception_event_group')),
298
                        $q->expr()->eq('uid_foreign', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT))
299
                    )
300
                );
301
302
            $dbQueries[] = $q->getSQL();
303
            $selectResults = $q->execute()->fetchAll();
304
305
            foreach ($selectResults as $eventUid) {
306
                $eventImportId = self::IMPORT_PREFIX . (int)$eventUid['uid_local'];
307
                $configurationRow = [
308
                    'pid' => (int)$group['pid'],
309
                    'tstamp' => $now->getTimestamp(),
310
                    'crdate' => $now->getTimestamp(),
311
                    'type' => 'group',
312
                    'handling' => 'exclude',
313
                    'groups' => $group['uid'],
314
                ];
315
316
                $this->updateEventWithConfiguration($eventImportId, $configurationRow, $dbQueries, $customMessages);
317
            }
318
        }
319
320
        return true;
321
    }
322
323
    /**
324
     * Migrate the 'sys_file_reference' entries from 'tx_cal_event' to 'tx_calendarize_domain_model_event'.
325
     * Mark the imported entries with the import-id.
326
     *
327
     * @param       $calIds
328
     * @param array $dbQueries
329
     * @param       $customMessages
330
     */
331
    public function performSysFileReferenceUpdate($calIds, array &$dbQueries, &$customMessages)
332
    {
333
        $db = HelperUtility::getDatabaseConnection('tx_cal_event');
334
        $q = $db->createQueryBuilder();
335
336
        $variables = [
337
            'table' => 'tx_cal_event',
338
            'fieldnames' => ['image', 'attachment'],
339
            'dbQueries' => $dbQueries,
340
            'calIds' => $calIds,
341
        ];
342
343
        // select all not migrated entries
344
        $fieldnames = 'fieldname = \'' . implode('\' OR fieldname = \'', $variables['fieldnames']) . '\'';
345
        $selectWhere = 'tablenames = \'' . $variables['table'] . '\' AND (' . $fieldnames . ')';
346
        $selectWhere .= ' AND NOT EXISTS (SELECT NULL FROM sys_file_reference sfr2 WHERE sfr2.import_id = CONCAT(\'' . self::IMPORT_PREFIX . '\', sfr1.uid))';
347
348
        $q->select('*')
349
            ->from('sys_file_reference', 'sfr1')
350
            ->where($selectWhere);
351
352
        $dbQueries[] = $q->getSQL();
353
        $selectResults = $q->execute()->fetchAll();
354
355
        $variables = [
356
            'table' => self::EVENT_TABLE,
357
            'fieldnames' => $variables['fieldnames'],
358
            'dbQueries' => $dbQueries,
359
            'calIds' => $calIds,
360
            'selectResults' => $selectResults,
361
        ];
362
363
        // create new entry with import_id
364
        foreach ($variables['selectResults'] as $selectResult) {
365
            $selectResult['tablenames'] = $variables['table'];
366
            $selectResult['import_id'] = self::IMPORT_PREFIX . $selectResult['uid'];
367
            $selectResult['fieldname'] = ('image' === $selectResult['fieldname']) ? 'images' : 'downloads';
368
            unset($selectResult['uid_foreign'], $selectResult['uid']);
369
370
            $q->resetQueryParts()->resetRestrictions();
371
            $q->insert('sys_file_reference')->values($selectResult);
372
373
            $dbQueries[] = $q->getSQL();
374
375
            $q->execute();
376
        }
377
    }
378
379
    /**
380
     * Link the Events to the migrated Categories.
381
     * This build up the 'sys_category_record_mm' table on base of the 'tx_cal_event_category_mm' table.
382
     *
383
     * @param       $calIds
384
     * @param array $dbQueries
385
     * @param array $customMessages
386
     */
387
    public function performLinkEventToCategory($calIds, &$dbQueries, &$customMessages)
388
    {
389
        $table = 'tx_cal_event_category_mm';
390
391
        $db = HelperUtility::getDatabaseConnection($table);
392
        $q = $db->createQueryBuilder();
393
394
        $q->select('*')->from($table);
395
        $dbQueries[] = $q->getSQL();
396
397
        $selectResults = $q->execute()->fetchAll();
398
399
        $variables = [
400
            'tablenames' => self::EVENT_TABLE,
401
            'fieldname' => 'categories',
402
            'dbQueries' => $dbQueries,
403
        ];
404
405
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
406
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
407
408
        foreach ($selectResults as $mm) {
409
            $eventUid = (int)$this->getCalendarizeEventUid(self::IMPORT_PREFIX . $mm['uid_local'], $dbQueries, $customMessages);
410
            $categoryUid = (int)$this->getCalendarizeCategoryUid(
411
                self::IMPORT_PREFIX . $mm['uid_foreign'],
412
                $dbQueries,
413
                $customMessages
414
            );
415
416
            if (0 !== $eventUid && 0 !== $categoryUid) {
417
                $insertValues = [
418
                    'uid_local' => $categoryUid,
419
                    'uid_foreign' => $eventUid,
420
                    'tablenames' => $variables['tablenames'],
421
                    'fieldname' => $variables['fieldname'],
422
                ];
423
424
                $q->insert('sys_category_record_mm')->values($insertValues);
425
                $dbQueries[] = $q->getSQL();
426
427
                $q->execute();
428
            }
429
        }
430
    }
431
432
    /**
433
     * Update event with configuration.
434
     *
435
     * @param $eventImportId
436
     * @param $configuration
437
     * @param $dbQueries
438
     * @param $customMessages
439
     *
440
     * @return array
441
     */
442
    protected function updateEventWithConfiguration($eventImportId, $configuration, &$dbQueries, &$customMessages)
443
    {
444
        $db = HelperUtility::getDatabaseConnection(self::CONFIGURATION_TABLE);
445
        $q = $db->createQueryBuilder();
446
447
        $configurationRow = $this->findEventExcludeConfiguration($eventImportId, $dbQueries, $customMessages);
448
        if ($configurationRow) {
449
            $configurationRow['groups'] = $this->addValueToCsv($configurationRow['groups'], $configuration['groups']);
450
451
            unset($configurationRow['uid']);
452
453
            $q->update(self::CONFIGURATION_GROUP_TABLE)
454
                ->where('uid', $q->createNamedParameter((int)$configuration['uid'], \PDO::PARAM_INT));
455
            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...
456
                $q->set($key, $value);
457
            }
458
459
            $dbQueries[] = $q->getSQL();
460
            $results = $q->execute();
461
        } else {
462
            $q->insert(self::CONFIGURATION_TABLE)->values($configuration);
463
            $dbQueries[] = $q->getSQL();
464
465
            $configurationId = $db->lastInsertId(self::CONFIGURATION_TABLE);
466
467
            $results = $this->addConfigurationIdToEvent($eventImportId, $configurationId, $dbQueries, $customMessages);
468
        }
469
470
        return $results;
471
    }
472
473
    /**
474
     * Add Value to CSV.
475
     *
476
     * @param string $csv
477
     * @param string $value
478
     *
479
     * @return string
480
     */
481
    protected function addValueToCsv($csv, $value)
482
    {
483
        $csvArray = GeneralUtility::trimExplode(',', $csv);
484
485
        // check for doubles
486
        $values = array_flip($csvArray);
487
        if (isset($values[$value])) {
488
            return $csv;
489
        }
490
        $csvArray[] = $value;
491
        $csv = implode(',', $csvArray);
492
493
        return $csv;
494
    }
495
496
    /**
497
     * Add configuration ID to event.
498
     *
499
     * @param string $eventImportId
500
     * @param int    $configurationId
501
     * @param array  $dbQueries
502
     * @param array  $customMessages
503
     *
504
     * @return array|bool
505
     */
506
    protected function addConfigurationIdToEvent($eventImportId, $configurationId, &$dbQueries, &$customMessages)
507
    {
508
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
509
        if (!$event) {
510
            return false;
511
        }
512
513
        $event['calendarize'] = $this->addValueToCsv($event['calendarize'], $configurationId);
514
515
        return $this->updateEvent($event['uid'], $event, $dbQueries, $customMessages);
516
    }
517
518
    /**
519
     * Update event.
520
     *
521
     * @param int   $eventId
522
     * @param array $values
523
     * @param array $dbQueries
524
     * @param array $customMessages
525
     *
526
     * @return array
527
     */
528
    protected function updateEvent($eventId, $values, &$dbQueries, &$customMessages)
529
    {
530
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
531
        $q = $db->createQueryBuilder();
532
533
        $variables = [
534
            'table' => self::EVENT_TABLE,
535
            'eventId' => (int)$eventId,
536
            'values' => $values,
537
            'dbQueries' => $dbQueries,
538
        ];
539
540
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
541
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
542
543
        $q->update($variables['table'])
544
            ->where(
545
                $q->expr()->eq('uid', $q->createNamedParameter((int)$eventId, \PDO::PARAM_INT))
546
            );
547
        foreach ($variables['values'] as $key => $value) {
548
            $q->set($key, $value);
549
        }
550
551
        unset($values['uid']);
552
553
        $dbQueries[] = $q->getSQL();
554
555
        return $q->execute()->fetchAll();
556
    }
557
558
    /**
559
     * Find event by import ID.
560
     *
561
     * @param $eventImportId
562
     * @param $dbQueries
563
     * @param $customMessages
564
     *
565
     * @return array|bool
566
     */
567
    protected function findEventByImportId($eventImportId, &$dbQueries, &$customMessages)
568
    {
569
        $db = HelperUtility::getDatabaseConnection(self::EVENT_TABLE);
570
        $q = $db->createQueryBuilder();
571
572
        $variables = [
573
            'table' => self::EVENT_TABLE,
574
            'dbQueries' => $dbQueries,
575
            'eventImportId' => $eventImportId,
576
        ];
577
578
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
579
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
580
581
        $q->select('*')->from($variables['table'])
582
            ->where(
583
                $q->expr()->eq('import_id', $q->createNamedParameter($eventImportId))
584
            );
585
586
        $dbQueries[] = $q->getSQL();
587
588
        return $q->execute()->fetchAll();
589
    }
590
591
    /**
592
     * Find event exclude configuration.
593
     *
594
     * @param string $eventImportId
595
     * @param array  $dbQueries
596
     * @param array  $customMessages
597
     *
598
     * @return array|bool
599
     */
600
    protected function findEventExcludeConfiguration($eventImportId, &$dbQueries, &$customMessages)
601
    {
602
        $event = $this->findEventByImportId($eventImportId, $dbQueries, $customMessages);
603
604
        if (!$event) {
605
            return false;
606
        }
607
608
        $variables = [
609
            'table' => self::CONFIGURATION_TABLE,
610
            'dbQueries' => $dbQueries,
611
            'event' => $event,
612
        ];
613
614
        $db = HelperUtility::getDatabaseConnection($variables['table']);
615
        $q = $db->createQueryBuilder();
616
617
        $q->select('*')
618
            ->from($variables['table'])
619
            ->where(
620
                $q->expr()->andX(
621
                    $q->expr()->eq('type', 'group'),
622
                    $q->expr()->eq('handling', 'exclude'),
623
                    $q->expr()->in('uid', $variables['event']['calendarize'])
624
                )
625
            );
626
627
        $dbQueries[] = $q->getSQL();
628
629
        return $q->execute()->fetchAll();
630
    }
631
632
    /**
633
     * Get exception configuration for exception group.
634
     *
635
     * @param       $groupId
636
     * @param array $dbQueries
637
     *
638
     * @return string
639
     */
640
    protected function getExceptionConfigurationForExceptionGroup($groupId, &$dbQueries)
641
    {
642
        $recordIds = [];
643
        $variables = [
644
            'table' => 'tx_cal_exception_event_group_mm',
645
            'dbQueries' => $dbQueries,
646
        ];
647
648
        $db = HelperUtility::getDatabaseConnection($variables['table']);
649
        $q = $db->createQueryBuilder();
650
651
        $q->select('*')
652
            ->from($variables['table'])
653
            ->where('uid_local', $q->createNamedParameter((int)$groupId, \PDO::PARAM_INT));
654
655
        $dbQueries[] = $q->getSQL();
656
657
        $mmResults = $q->execute()->fetchAll();
658
        foreach ($mmResults as $mmResult) {
659
            $variables = [
660
                'table' => 'tx_cal_exception_event',
661
                'dbQueries' => $dbQueries,
662
            ];
663
664
            $q->resetQueryParts()->resetRestrictions();
665
            $q->select('*')
666
                ->from($variables['table'])
667
                ->where(
668
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$mmResult['uid_foreign'], \PDO::PARAM_INT))
669
                );
670
671
            $dbQueries[] = $q->getSQL();
672
673
            $selectResults = $q->execute()->fetchAll();
674
675
            foreach ($selectResults as $selectResult) {
676
                $configurationRow = [
677
                    'pid' => $selectResult['pid'],
678
                    'tstamp' => $selectResult['tstamp'],
679
                    'crdate' => $selectResult['crdate'],
680
                    'type' => 'time',
681
                    'handling' => 'include',
682
                    'start_date' => (string)$selectResult['start_date'] ?: null,
683
                    'end_date' => (string)$selectResult['end_date'] ?: null,
684
                    'start_time' => (int)$selectResult['start_time'],
685
                    'end_time' => (int)$selectResult['end_time'],
686
                    'all_day' => (null === $selectResult['start_time'] && null === $selectResult['end_time']) ? 1 : 0,
687
                    'frequency' => $this->mapFrequency($selectResult['freq']),
688
                    'till_date' => (string)$selectResult['until'] ?: null,
689
                    'counter_amount' => (int)$selectResult['cnt'],
690
                    'counter_interval' => (int)$selectResult['interval'],
691
                    'import_id' => self::IMPORT_PREFIX . $selectResult['uid'],
692
                ];
693
694
                $variables = [
695
                    'table' => self::CONFIGURATION_TABLE,
696
                    'configurationRow' => $configurationRow,
697
                ];
698
699
                $dispatcher = HelperUtility::getSignalSlotDispatcher();
700
                $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
701
702
                $q->resetQueryParts()->resetRestrictions();
703
                $q->insert($variables['table'])->values($variables['configurationRow']);
704
705
                $dbQueries[] = $q->getSQL();
706
707
                $q->execute();
708
709
                $recordIds[] = $db->lastInsertId($variables['table']);
710
            }
711
        }
712
713
        return implode(',', $recordIds);
714
    }
715
716
    /**
717
     * Map frequency.
718
     *
719
     * @param string $calFrequency
720
     *
721
     * @return string
722
     */
723
    protected function mapFrequency($calFrequency)
724
    {
725
        $freq = [
726
            'none' => null,
727
            'day' => 'daily',
728
            'week' => 'weekly',
729
            'month' => 'monthly',
730
            'year' => 'yearly',
731
        ];
732
733
        if (!isset($freq[$calFrequency])) {
734
            return '';
735
        }
736
737
        return $freq[$calFrequency];
738
    }
739
740
    /**
741
     * Migrate the 'tx_cal_category' table to the 'sys_category' table.
742
     *
743
     * @param       $calIds
744
     * @param array $dbQueries
745
     * @param       $customMessages
746
     */
747
    protected function performSysCategoryUpdate($calIds, array &$dbQueries, &$customMessages)
748
    {
749
        // first migrate from tx_cal_category to sys_category
750
        $variables = [
751
            'table' => 'tx_cal_category',
752
            'dbQueries' => $dbQueries,
753
            'calIds' => $calIds,
754
        ];
755
756
        $db = HelperUtility::getDatabaseConnection($variables['table']);
757
        $q = $db->createQueryBuilder();
758
        $q->getRestrictions()
759
            ->removeAll()
760
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
761
762
        $q->select('*')
763
            ->from($variables['table']);
764
765
        $dbQueries[] = $q->getSQL();
766
767
        $selectResults = $q->execute()->fetchAll();
768
769
        foreach ($selectResults as $category) {
770
            $sysCategoryRecord = [
771
                'pid' => $category['pid'],
772
                'tstamp' => $category['tstamp'],
773
                'crdate' => $category['crdate'],
774
                'cruser_id' => $category['cruser_id'],
775
                'deleted' => $category['deleted'],
776
                'hidden' => $category['hidden'],
777
                'starttime' => $category['starttime'],
778
                'endtime' => $category['endtime'],
779
                'sys_language_uid' => $category['sys_language_uid'],
780
                'l10n_parent' => $category['l18n_parent'],
781
                'l10n_diffsource' => $category['l18n_diffsource'],
782
                'title' => $category['title'],
783
                'parent' => (int)$category['parent_category'],
784
                'import_id' => self::IMPORT_PREFIX . (int)$category['uid'],
785
                'sorting' => $category['sorting'],
786
            ];
787
788
            $q->resetQueryParts()->resetRestrictions();
789
790
            $q->insert('sys_category')->values($sysCategoryRecord);
791
            $dbQueries[] = $q->getSQL();
792
793
            $q->execute();
794
        }
795
796
        // second rewrite the tree
797
        $variables = [
798
            'table' => 'sys_category',
799
            'dbQueries' => $dbQueries,
800
            'calIds' => $calIds,
801
        ];
802
803
        $q->resetQueryParts()->resetRestrictions();
804
805
        $q->select('*')
806
            ->from($variables['table'])
807
            ->where(
808
                $q->expr()->neq('import_id', $q->createNamedParameter(''))
809
            );
810
811
        $dbQueries[] = $q->getSQL();
812
        $selectResults = $q->execute()->fetchAll();
813
814
        foreach ($selectResults as $sysCategory) {
815
            // update parent, because there are just the old uids
816
            $q->resetQueryParts()->resetRestrictions();
817
            $q->update('sys_category')
818
                ->where(
819
                    $q->expr()->eq('uid', $q->createNamedParameter((int)$sysCategory['uid'], \PDO::PARAM_INT))
820
                )->set(
821
                    'parent',
822
                    $this->getSysCategoryParentUid(self::IMPORT_PREFIX . (int)$sysCategory['parent'])
823
                );
824
825
            $dbQueries[] = $q->getSQL();
826
827
            $q->execute();
828
        }
829
    }
830
831
    /**
832
     * Return the parentUid for the 'sys_category' entry on base of the import_id.
833
     *
834
     * @param string $importId
835
     *
836
     * @return int
837
     */
838
    protected function getSysCategoryParentUid($importId)
839
    {
840
        $table = 'sys_category';
841
        $db = HelperUtility::getDatabaseConnection($table);
842
        $q = $db->createQueryBuilder();
843
844
        $q->select('uid')
845
            ->from($table)
846
            ->where(
847
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
848
            );
849
850
        $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...
851
852
        $result = $q->execute()->fetchAll();
853
854
        return (int)$result[0]['uid'];
855
    }
856
857
    /**
858
     * Get the event uid on base of the given import_id.
859
     * The import_id is the original tx_cal_event id prefixed with the IMPORT_PREFIX.
860
     *
861
     * @param string $importId
862
     * @param array  $dbQueries
863
     * @param array  $customMessages
864
     *
865
     * @return int
866
     */
867
    protected function getCalendarizeEventUid($importId, &$dbQueries, &$customMessages)
868
    {
869
        $variables = [
870
            'table' => self::EVENT_TABLE,
871
            'dbQueries' => $dbQueries,
872
        ];
873
874
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
875
876
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
877
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
878
879
        $q->select('uid')
880
            ->from($variables['table'])
881
            ->where(
882
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
883
            );
884
885
        $dbQueries[] = $q->getSQL();
886
887
        $result = $q->execute()->fetchAll();
888
889
        return (int)$result[0]['uid'];
890
    }
891
892
    /**
893
     * Get the sys_category uid on base of the given import_id.
894
     * The import_id is the original tx_cal_category id prefixed with the IMPORT_PREFIX.
895
     *
896
     * @see CalMigrationUpdate::IMPORT_PREFIX
897
     *
898
     * @param string $importId
899
     * @param array  $dbQueries
900
     * @param array  $customMessages
901
     *
902
     * @return int
903
     */
904
    protected function getCalendarizeCategoryUid($importId, &$dbQueries, &$customMessages)
905
    {
906
        $variables = [
907
            'table' => 'sys_category',
908
            'dbQueries' => $dbQueries,
909
        ];
910
911
        $q = HelperUtility::getDatabaseConnection($variables['table'])->createQueryBuilder();
912
913
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
914
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__, $variables);
915
916
        $q->select('uid')
917
            ->from($variables['table'])
918
            ->where(
919
                $q->expr()->eq('import_id', $q->createNamedParameter($importId))
920
            );
921
922
        $dbQueries[] = $q->getSQL();
923
924
        $result = $q->execute()->fetchAll();
925
926
        return (int)$result[0]['uid'];
927
    }
928
929
    /**
930
     * Build configurations.
931
     *
932
     * @param $calEventRow
933
     * @param $dbQueries
934
     *
935
     * @return int
936
     */
937
    protected function buildConfigurations($calEventRow, &$dbQueries)
938
    {
939
        $configurationRow = [
940
            'pid' => $calEventRow['pid'],
941
            'tstamp' => $calEventRow['tstamp'],
942
            'crdate' => $calEventRow['crdate'],
943
            'type' => 'time',
944
            'handling' => 'include',
945
            'start_date' => (string)$calEventRow['start_date'] ?: null,
946
            'end_date' => (string)$calEventRow['end_date'] ?: null,
947
            'start_time' => (int)$calEventRow['start_time'],
948
            'end_time' => (int)$calEventRow['end_time'],
949
            'all_day' => $calEventRow['allday'],
950
            'frequency' => $this->mapFrequency($calEventRow['freq']),
951
            'till_date' => (string)$calEventRow['until'] ?: null,
952
            'counter_amount' => (int)$calEventRow['cnt'],
953
            'counter_interval' => (int)$calEventRow['interval'],
954
        ];
955
956
        $variables = [
957
            'table' => self::CONFIGURATION_TABLE,
958
            'configurationRow' => $configurationRow,
959
            'calEventRow' => $calEventRow,
960
            'dbQueries' => $dbQueries,
961
        ];
962
963
        $db = HelperUtility::getDatabaseConnection($variables['table']);
964
        $q = $db->createQueryBuilder();
965
966
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
967
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreInsert', $variables);
968
969
        $q->insert($variables['table'])
970
            ->values($variables['configurationRow']);
971
972
        $dbQueries[] = $q->getSQL();
973
        $q->execute();
974
        $recordId = $db->lastInsertId($variables['table']);
975
976
        $variables = [
977
            'table' => $variables['table'],
978
            'configurationRow' => $configurationRow,
979
            'calEventRow' => $calEventRow,
980
            'recordId' => $recordId,
981
            'dbQueries' => $dbQueries,
982
        ];
983
984
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
985
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PostInsert', $variables);
986
987
        return $variables['recordId'];
988
    }
989
990
    /**
991
     * Get the non migrated cal IDs.
992
     *
993
     * @return array
994
     */
995
    protected function getNonMigratedCalIds()
996
    {
997
        $checkImportIds = [];
998
        $nonMigrated = [];
999
1000
        $table = 'tx_cal_event';
1001
        $q = HelperUtility::getDatabaseConnection($table)->createQueryBuilder();
1002
        $q->getRestrictions()
1003
            ->removeAll()
1004
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1005
1006
        $events = $q->select('uid')
1007
            ->from($table)
1008
            ->execute()
1009
            ->fetchAll();
1010
1011
        foreach ($events as $event) {
1012
            $checkImportIds[] = '"' . self::IMPORT_PREFIX . $event['uid'] . '"';
1013
            $nonMigrated[(int)$event['uid']] = (int)$event['uid'];
1014
        }
1015
1016
        $countOriginal = \count($checkImportIds);
1017
        if (0 === $countOriginal) {
1018
            return [];
1019
        }
1020
1021
        $variables = [
1022
            'table' => self::EVENT_TABLE,
1023
        ];
1024
1025
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1026
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'PreSelect', $variables);
1027
1028
        $q->resetQueryParts();
1029
1030
        $migratedRows = $q->select('uid', 'import_id')
1031
            ->from($variables['table'])
1032
            ->where(
1033
                $q->expr()->in('import_id', $checkImportIds)
1034
            )
1035
            ->execute()
1036
            ->fetchAll();
1037
1038
        foreach ($migratedRows as $migratedRow) {
1039
            $importId = (int)str_replace(self::IMPORT_PREFIX, '', $migratedRow['import_id']);
1040
            if (isset($nonMigrated[$importId])) {
1041
                unset($nonMigrated[$importId]);
1042
            }
1043
        }
1044
1045
        $variables = [
1046
            'table' => $variables['table'],
1047
            'migratedRows' => $migratedRows,
1048
            'nonMigrated' => $nonMigrated,
1049
        ];
1050
1051
        $dispatcher = HelperUtility::getSignalSlotDispatcher();
1052
        $variables = $dispatcher->dispatch(__CLASS__, __FUNCTION__ . 'ReadyParsed', $variables);
1053
1054
        return $variables['nonMigrated'];
1055
    }
1056
1057
    public function updateNecessary(): bool
1058
    {
1059
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
1060
        $connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
1061
        $dbSchema = $connection->getSchemaManager()->createSchema();
1062
1063
        $tableNames = array_map(function ($table) {
1064
            return $table->getName();
1065
        }, $dbSchema->getTables());
1066
1067
        return \in_array('tx_cal_event', $tableNames);
1068
    }
1069
1070
    public function getPrerequisites(): array
1071
    {
1072
        return [
1073
            DatabaseUpdatedPrerequisite::class,
1074
        ];
1075
    }
1076
}
1077