Completed
Push — master ( 50d0e2...486efe )
by Tim
02:10
created

IndexRepository::getIndexLanguageMode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
/**
4
 * Index repository.
5
 */
6
declare(strict_types=1);
7
8
namespace HDNET\Calendarize\Domain\Repository;
9
10
use Exception;
11
use HDNET\Calendarize\Domain\Model\Index;
12
use HDNET\Calendarize\Utility\DateTimeUtility;
13
use HDNET\Calendarize\Utility\ExtensionConfigurationUtility;
14
use TYPO3\CMS\Core\Utility\GeneralUtility;
15
use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;
16
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
17
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
18
use TYPO3\CMS\Extbase\Object\ObjectManager;
19
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
20
21
/**
22
 * Index repository.
23
 */
24
class IndexRepository extends AbstractRepository
25
{
26
    /**
27
     * Default orderings for index records.
28
     *
29
     * @var array
30
     */
31
    protected $defaultOrderings = [
32
        'start_date' => QueryInterface::ORDER_ASCENDING,
33
        'start_time' => QueryInterface::ORDER_ASCENDING,
34
    ];
35
36
    /**
37
     * Index types for selection.
38
     *
39
     * @var array
40
     */
41
    protected $indexTypes = [];
42
43
    /**
44
     * Override page ids.
45
     *
46
     * @var array
47
     */
48
    protected $overridePageIds = [];
49
50
    /**
51
     * @return QueryInterface
52
     */
53
    public function createQuery()
54
    {
55
        $query = parent::createQuery();
56
        $query->getQuerySettings()->setLanguageMode($this->getIndexLanguageMode());
57
        return $query;
58
    }
59
60
    /**
61
     * Get index language mode
62
     *
63
     * @return string
64
     */
65
    protected function getIndexLanguageMode()
66
    {
67
        static $mode;
68
        if ($mode !== null) {
69
            return $mode;
70
        }
71
72
        $objectManager = new ObjectManager();
73
        /** @var ConfigurationManagerInterface $config */
74
        $config = $objectManager->get(ConfigurationManagerInterface::class);
75
        $pluginConfig = $config->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
76
77
        $mode = isset($pluginConfig['indexLanguageMode']) ? (string) $pluginConfig['indexLanguageMode'] : 'strict';
78
        return $mode;
79
    }
80
81
    /**
82
     * Set the index types.
83
     *
84
     * @param array $types
85
     */
86
    public function setIndexTypes(array $types)
87
    {
88
        $this->indexTypes = $types;
89
    }
90
91
    /**
92
     * Override page IDs.
93
     *
94
     * @param array $overridePageIds
95
     */
96
    public function setOverridePageIds($overridePageIds)
97
    {
98
        $this->overridePageIds = $overridePageIds;
99
    }
100
101
    /**
102
     * Find List.
103
     *
104
     * @param int        $limit
105
     * @param int|string $listStartTime
106
     * @param int        $startOffsetHours
107
     * @param int        $overrideStartDate
108
     * @param int        $overrideEndDate
109
     *
110
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
111
     */
112
    public function findList(
113
        $limit = 0,
114
        $listStartTime = 0,
115
        $startOffsetHours = 0,
116
        $overrideStartDate = 0,
117
        $overrideEndDate = 0
118
    ) {
119
        if ($overrideStartDate > 0) {
120
            $startTimestamp = $overrideStartDate;
121
        } else {
122
            $now = DateTimeUtility::getNow();
123
            if ('now' !== $listStartTime) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of 'now' (string) and $listStartTime (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
124
                $now->setTime(0, 0, 0);
125
            }
126
            $now->modify($startOffsetHours . ' hours');
127
            $startTimestamp = $now->getTimestamp();
128
        }
129
        $endTimestamp = null;
130
        if ($overrideEndDate > 0) {
131
            $endTimestamp = $overrideEndDate;
132
        }
133
134
        $result = $this->findByTimeSlot($startTimestamp, $endTimestamp);
135
        if ($limit > 0) {
136
            $query = $result->getQuery();
137
            $query->setLimit($limit);
138
            $result = $query->execute();
139
        }
140
141
        return $result;
142
    }
143
144
    /**
145
     * Find by custom search.
146
     *
147
     * @param \DateTime $startDate
148
     * @param \DateTime $endDate
149
     * @param array $customSearch
150
     * @param int $limit
151
     *
152
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
153
     */
154
    public function findBySearch(\DateTime $startDate = null, \DateTime $endDate = null, array $customSearch = [], int $limit = 0)
155
    {
156
        $arguments = [
157
            'indexIds' => [],
158
            'startDate' => $startDate,
159
            'endDate' => $endDate,
160
            'customSearch' => $customSearch,
161
            'indexTypes' => $this->indexTypes,
162
            'emptyPreResult' => false,
163
        ];
164
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__ . 'Pre', $arguments);
165
166
        $query = $this->createQuery();
167
        $constraints = $this->getDefaultConstraints($query);
168
169
        if ($limit > 0) {
170
            $query->setLimit($limit);
171
        }
172
173
        $this->addTimeFrameConstraints(
174
            $constraints,
175
            $query,
176
            $arguments['startDate'] instanceof \DateTime ? DateTimeUtility::getDayStart($arguments['startDate']) : null,
0 ignored issues
show
Bug introduced by
It seems like $arguments['startDate'] ...ts['startDate']) : null can also be of type object<DateTime>; however, HDNET\Calendarize\Domain...dTimeFrameConstraints() does only seem to accept integer|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
177
            $arguments['endDate'] instanceof \DateTime ? DateTimeUtility::getDayEnd($arguments['endDate']) : null
0 ignored issues
show
Bug introduced by
It seems like $arguments['endDate'] in...ents['endDate']) : null can also be of type object<DateTime>; however, HDNET\Calendarize\Domain...dTimeFrameConstraints() does only seem to accept integer|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
178
        );
179
180
        if ($arguments['indexIds']) {
181
            $constraints[] = $query->in('foreign_uid', $arguments['indexIds']);
182
        }
183
        if ($arguments['emptyPreResult']) {
184
            $constraints[] = $query->equals('uid', '-1');
185
        }
186
        $result = [
187
            'result' => $this->matchAndExecute($query, $constraints),
188
        ];
189
190
        $result = $this->callSignal(__CLASS__, __FUNCTION__ . 'Post', $result);
191
192
        return $result['result'];
193
    }
194
195
    /**
196
     * Find Past Events.
197
     *
198
     * @param int    $limit
199
     * @param string $sort
200
     *
201
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
202
     */
203
    public function findByPast(
204
        $limit,
205
        $sort
206
    ) {
207
        //create Query
208
        $query = $this->createQuery();
209
        //Get actual datetime
210
        $now = DateTimeUtility::getNow()->getTimestamp();
211
212
        $constraints = $this->getDefaultConstraints($query);
213
        $constraints[] = $query->lessThanOrEqual('startDate', $now);
214
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
215
        $query->setOrderings($this->getSorting($sort));
216
        $query->setLimit($limit);
217
218
        return $this->matchAndExecute($query, $constraints);
219
    }
220
221
    /**
222
     * Find by traversing information.
223
     *
224
     * @param Index      $index
225
     * @param bool|true  $future
226
     * @param bool|false $past
227
     * @param int        $limit
228
     * @param string     $sort
229
     * @param bool       $useIndexTime
230
     *
231
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
232
     */
233
    public function findByTraversing(
234
        Index $index,
235
        $future = true,
236
        $past = false,
237
        $limit = 100,
238
        $sort = QueryInterface::ORDER_ASCENDING,
239
        $useIndexTime = false
240
    ) {
241
        if (!$future && !$past) {
242
            return [];
243
        }
244
        $query = $this->createQuery();
245
246
        $now = DateTimeUtility::getNow()
247
            ->getTimestamp();
248
        if ($useIndexTime) {
249
            $now = $index->getStartDate()->getTimestamp();
250
        }
251
252
        $constraints = [];
253
        $constraints[] = $query->logicalNot($query->equals('uid', $index->getUid()));
254
        $constraints[] = $query->equals('foreignTable', $index->getForeignTable());
255
        $constraints[] = $query->equals('foreignUid', $index->getForeignUid());
256
        if (!$future) {
257
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
258
        }
259
        if (!$past) {
260
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
261
        }
262
263
        $query->setLimit($limit);
264
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
265
        $query->setOrderings($this->getSorting($sort));
266
267
        return $this->matchAndExecute($query, $constraints);
268
    }
269
270
    /**
271
     * Find by traversing information.
272
     *
273
     * @param DomainObjectInterface $event
274
     * @param bool|true             $future
275
     * @param bool|false            $past
276
     * @param int                   $limit
277
     * @param string                $sort
278
     *
279
     * @throws Exception
280
     *
281
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
282
     */
283
    public function findByEventTraversing(
284
        DomainObjectInterface $event,
285
        $future = true,
286
        $past = false,
287
        $limit = 100,
288
        $sort = QueryInterface::ORDER_ASCENDING
289
    ) {
290
        if (!$future && !$past) {
291
            return [];
292
        }
293
        $query = $this->createQuery();
294
295
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
296
297
        $this->setIndexTypes([$uniqueRegisterKey]);
298
299
        $now = DateTimeUtility::getNow()
300
            ->getTimestamp();
301
302
        $constraints = [];
303
304
        $constraints[] = $query->equals('foreignUid', $event->getUid());
305
        if (!$future) {
306
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
307
        }
308
        if (!$past) {
309
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
310
        }
311
312
        $query->setLimit($limit);
313
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
314
        $query->setOrderings($this->getSorting($sort));
315
316
        return $this->matchAndExecute($query, $constraints);
317
    }
318
319
    /**
320
     * find Year.
321
     *
322
     * @param int $year
323
     *
324
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
325
     */
326
    public function findYear(int $year)
327
    {
328
        return $this->findByTimeSlot(\mktime(0, 0, 0, 1, 1, $year), \mktime(0, 0, 0, 1, 1, $year + 1) - 1);
329
    }
330
331
    /**
332
     * find Month.
333
     *
334
     * @param int $year
335
     * @param int $month
336
     *
337
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
338
     */
339
    public function findMonth(int $year, int $month)
340
    {
341
        $startTime = \mktime(0, 0, 0, $month, 1, $year);
342
        $endTime = \mktime(0, 0, 0, $month + 1, 1, $year) - 1;
343
344
        return $this->findByTimeSlot($startTime, $endTime);
345
    }
346
347
    /**
348
     * find Week.
349
     *
350
     * @param int $year
351
     * @param int $week
352
     * @param int $weekStart See documentation for settings.weekStart
353
     *
354
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
355
     */
356
    public function findWeek($year, $week, $weekStart = 1)
357
    {
358
        $weekStart = (int) $weekStart;
359
        $daysShift = DateTimeUtility::SECONDS_DAY * ($weekStart - 1);
360
        $firstDay = DateTimeUtility::convertWeekYear2DayMonthYear($week, $year);
361
        $timezone = DateTimeUtility::getTimeZone();
362
        $firstDay->setTimezone($timezone);
363
        $timeStampStart = $firstDay->getTimestamp() + $daysShift;
364
365
        return $this->findByTimeSlot($timeStampStart, $timeStampStart + DateTimeUtility::SECONDS_WEEK - 1);
366
    }
367
368
    /**
369
     * Find different types and locations
370
     *
371
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
372
     */
373
    public function findDifferentTypesAndLocations()
374
    {
375
        $query = $this->createQuery();
376
        return $query
0 ignored issues
show
Bug introduced by
The method statement() does not exist on TYPO3\CMS\Extbase\Persistence\QueryInterface. Did you maybe mean getStatement()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
377
            ->statement('SELECT *'
378
                . 'FROM tx_calendarize_domain_model_index '
379
                . 'GROUP BY pid,foreign_table')
380
            ->execute();
381
    }
382
383
    /**
384
     * find day.
385
     *
386
     * @param int $year
387
     * @param int $month
388
     * @param int $day
389
     *
390
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
391
     */
392
    public function findDay(int $year, int $month, int $day)
393
    {
394
        $startTime = \mktime(0, 0, 0, $month, $day, $year);
395
396
        return $this->findByTimeSlot($startTime, $startTime + DateTimeUtility::SECONDS_DAY - 1);
397
    }
398
399
    /**
400
     * Set the default sorting direction.
401
     *
402
     * @param string $direction
403
     * @param string $field
404
     */
405
    public function setDefaultSortingDirection($direction, $field = '')
406
    {
407
        $this->defaultOrderings = $this->getSorting($direction, $field);
408
    }
409
410
    /**
411
     * Find by time slot.
412
     *
413
     * @param int      $startTime
414
     * @param int|null $endTime   null means open end
415
     *
416
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
417
     */
418
    public function findByTimeSlot($startTime, $endTime = null)
419
    {
420
        $query = $this->createQuery();
421
        $constraints = $this->getDefaultConstraints($query);
422
        $this->addTimeFrameConstraints($constraints, $query, $startTime, $endTime);
423
424
        return $this->matchAndExecute($query, $constraints);
425
    }
426
427
    /**
428
     * Find all indices by the given Event model.
429
     *
430
     * @param DomainObjectInterface $event
431
     *
432
     * @throws Exception
433
     *
434
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
435
     */
436
    public function findByEvent(DomainObjectInterface $event)
437
    {
438
        $query = $this->createQuery();
439
440
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
441
442
        $this->setIndexTypes([$uniqueRegisterKey]);
443
        $constraints = $this->getDefaultConstraints($query);
444
        $constraints[] = $query->equals('foreignUid', $event->getUid());
445
        $query->matching($query->logicalAnd($constraints));
446
447
        return $query->execute();
448
    }
449
450
    /**
451
     * storage page selection.
452
     *
453
     * @return array
454
     */
455
    protected function getStoragePageIds()
456
    {
457
        if (!empty($this->overridePageIds)) {
458
            return $this->overridePageIds;
459
        }
460
461
        $configurationManager = $this->objectManager->get(ConfigurationManagerInterface::class);
462
        $frameworkConfig = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
463
        $storagePages = isset($frameworkConfig['persistence']['storagePid']) ? GeneralUtility::intExplode(
464
            ',',
465
            $frameworkConfig['persistence']['storagePid']
466
        ) : [];
467
        if (!empty($storagePages)) {
468
            return $storagePages;
469
        }
470
        if ($frameworkConfig instanceof BackendConfigurationManager) {
471
            return GeneralUtility::trimExplode(',', $frameworkConfig->getDefaultBackendStoragePid(), true);
472
        }
473
474
        return $storagePages;
475
    }
476
477
    /**
478
     * Get the default constraint for the queries.
479
     *
480
     * @param QueryInterface $query
481
     *
482
     * @return array
483
     */
484
    protected function getDefaultConstraints(QueryInterface $query)
485
    {
486
        $constraints = [];
487
        if (!empty($this->indexTypes)) {
488
            $indexTypes = $this->indexTypes;
489
            $constraints[] = $query->in('uniqueRegisterKey', $indexTypes);
490
        }
491
492
        $storagePages = $this->getStoragePageIds();
493
        if (!empty($storagePages)) {
494
            $constraints[] = $query->in('pid', $storagePages);
495
        }
496
497
        $arguments = [
498
            'indexIds' => [],
499
            'indexTypes' => $this->indexTypes,
500
        ];
501
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
502
503
        if ($arguments['indexIds']) {
504
            $constraints[] = $query->in('foreign_uid', $arguments['indexIds']);
505
        }
506
507
        return $constraints;
508
    }
509
510
    /**
511
     * Add time frame related queries.
512
     *
513
     * @param array          $constraints
514
     * @param QueryInterface $query
515
     * @param int            $startTime
516
     * @param int|null       $endTime
517
     *
518
     * @see IndexUtility::isIndexInRange
519
     */
520
    protected function addTimeFrameConstraints(&$constraints, QueryInterface $query, $startTime = null, $endTime = null)
521
    {
522
        $arguments = [
523
            'constraints' => &$constraints,
524
            'query' => $query,
525
            'startTime' => $startTime,
526
            'endTime' => $endTime,
527
        ];
528
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
529
530
        if (null === $arguments['startTime'] && null === $arguments['endTime']) {
531
            return;
532
        }
533
        if (null === $arguments['startTime']) {
534
            // Simulate start time
535
            $arguments['startTime'] = DateTimeUtility::getNow()->getTimestamp() - DateTimeUtility::SECONDS_DECADE;
536
        } elseif (null === $arguments['endTime']) {
537
            // Simulate end time
538
            $arguments['endTime'] = DateTimeUtility::getNow()->getTimestamp() + DateTimeUtility::SECONDS_DECADE;
539
        }
540
541
        $orConstraint = [];
542
543
        // before - in
544
        $beforeIn = [
545
            $query->lessThan('start_date', $arguments['startTime']),
546
            $query->greaterThanOrEqual('end_date', $arguments['startTime']),
547
            $query->lessThan('end_date', $arguments['endTime']),
548
        ];
549
        $orConstraint[] = $query->logicalAnd($beforeIn);
550
551
        // in - in
552
        $inIn = [
553
            $query->greaterThanOrEqual('start_date', $arguments['startTime']),
554
            $query->lessThan('end_date', $arguments['endTime']),
555
        ];
556
        $orConstraint[] = $query->logicalAnd($inIn);
557
558
        // in - after
559
        $inAfter = [
560
            $query->greaterThanOrEqual('start_date', $arguments['startTime']),
561
            $query->lessThan('start_date', $arguments['endTime']),
562
            $query->greaterThanOrEqual('end_date', $arguments['endTime']),
563
        ];
564
        $orConstraint[] = $query->logicalAnd($inAfter);
565
566
        // before - after
567
        $beforeAfter = [
568
            $query->lessThan('start_date', $arguments['startTime']),
569
            $query->greaterThan('end_date', $arguments['endTime']),
570
        ];
571
        $orConstraint[] = $query->logicalAnd($beforeAfter);
572
573
        // finish
574
        $constraints[] = $query->logicalOr($orConstraint);
575
    }
576
577
    /**
578
     * Get the sorting.
579
     *
580
     * @param string $direction
581
     * @param string $field
582
     *
583
     * @return array
584
     */
585
    protected function getSorting($direction, $field = '')
586
    {
587
        if ('end' !== $field) {
588
            $field = 'start';
589
        }
590
591
        return [
592
            $field . '_date' => $direction,
593
            $field . '_time' => $direction,
594
        ];
595
    }
596
}
597