Completed
Push — master ( 498091...9beb04 )
by Tim
15s queued 12s
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 function gmmktime;
12
use HDNET\Calendarize\Domain\Model\Index;
13
use HDNET\Calendarize\Domain\Model\Request\OptionRequest;
14
use HDNET\Calendarize\Utility\ConfigurationUtility;
15
use HDNET\Calendarize\Utility\DateTimeUtility;
16
use HDNET\Calendarize\Utility\ExtensionConfigurationUtility;
17
use TYPO3\CMS\Core\Database\ConnectionPool;
18
use TYPO3\CMS\Core\Utility\GeneralUtility;
19
use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;
20
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
21
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
22
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
23
24
/**
25
 * Index repository.
26
 */
27
class IndexRepository extends AbstractRepository
28
{
29
    /**
30
     * Default orderings for index records.
31
     *
32
     * @var array
33
     */
34
    protected $defaultOrderings = [
35
        'start_date' => QueryInterface::ORDER_ASCENDING,
36
        'start_time' => QueryInterface::ORDER_ASCENDING,
37
    ];
38
39
    /**
40
     * Index types for selection.
41
     *
42
     * @var array
43
     */
44
    protected $indexTypes = [];
45
46
    /**
47
     * Override page ids.
48
     *
49
     * @var array
50
     */
51
    protected $overridePageIds;
52
53
    /**
54
     * Create query.
55
     *
56
     * @return QueryInterface
57
     */
58
    public function createQuery()
59
    {
60
        $query = parent::createQuery();
61
62
        return $query;
63
    }
64
65
    /**
66
     * Set the index types.
67
     *
68
     * @param array $types
69
     */
70
    public function setIndexTypes(array $types)
71
    {
72
        $this->indexTypes = $types;
73
    }
74
75
    /**
76
     * Override page IDs.
77
     *
78
     * @param array $overridePageIds
79
     */
80
    public function setOverridePageIds($overridePageIds)
81
    {
82
        $this->overridePageIds = $overridePageIds;
83
    }
84
85
    /**
86
     * Select indecies for Backend.
87
     *
88
     * @param OptionRequest $options
89
     *
90
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
91
     */
92
    public function findAllForBackend(OptionRequest $options)
93
    {
94
        $query = $this->createQuery();
95
        $query->getQuerySettings()->setIgnoreEnableFields(true);
96
        $query->getQuerySettings()->setRespectSysLanguage(false);
97
        $query->getQuerySettings()->setLanguageOverlayMode(false);
98
99
        // Notice Selection without any language handling
100
        unset($GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['languageField'], $GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['transOrigPointerField']);
101
102
        if ('asc' === $options->getDirection()) {
103
            $query->setOrderings([
104
                'start_date' => QueryInterface::ORDER_ASCENDING,
105
                'start_time' => QueryInterface::ORDER_ASCENDING,
106
            ]);
107
        } else {
108
            $query->setOrderings([
109
                'start_date' => QueryInterface::ORDER_DESCENDING,
110
                'start_time' => QueryInterface::ORDER_DESCENDING,
111
            ]);
112
        }
113
114
        if ((int)$options->getPid() > 0) {
115
            $query->matching($query->equals('pid', (int)$options->getPid()));
116
        }
117
118
        return $query->execute();
119
    }
120
121
    /**
122
     * Find List.
123
     *
124
     * @param int        $limit
125
     * @param int|string $listStartTime
126
     * @param int        $startOffsetHours
127
     * @param int        $overrideStartDate
128
     * @param int        $overrideEndDate
129
     *
130
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
131
     */
132
    public function findList(
133
        $limit = 0,
134
        $listStartTime = 0,
135
        $startOffsetHours = 0,
136
        $overrideStartDate = 0,
137
        $overrideEndDate = 0
138
    ) {
139
        if ($overrideStartDate > 0) {
140
            $startTimestamp = $overrideStartDate;
141
        } else {
142
            $now = DateTimeUtility::getNow();
143
            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...
144
                $now->setTime(0, 0, 0);
145
            }
146
            $now->modify($startOffsetHours . ' hours');
147
            $startTimestamp = $now->getTimestamp();
148
        }
149
        $endTimestamp = null;
150
        if ($overrideEndDate > 0) {
151
            $endTimestamp = $overrideEndDate;
152
        }
153
154
        $result = $this->findByTimeSlot($startTimestamp, $endTimestamp);
155
        if ($limit > 0) {
156
            $query = $result->getQuery();
157
            $query->setLimit($limit);
158
            $result = $query->execute();
159
        }
160
161
        return $result;
162
    }
163
164
    /**
165
     * Find by custom search.
166
     *
167
     * @param \DateTime $startDate
168
     * @param \DateTime $endDate
169
     * @param array     $customSearch
170
     * @param int       $limit
171
     *
172
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
173
     */
174
    public function findBySearch(\DateTime $startDate = null, \DateTime $endDate = null, array $customSearch = [], int $limit = 0)
175
    {
176
        $arguments = [
177
            'indexIds' => [],
178
            'startDate' => $startDate,
179
            'endDate' => $endDate,
180
            'customSearch' => $customSearch,
181
            'indexTypes' => $this->indexTypes,
182
            'emptyPreResult' => false,
183
        ];
184
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__ . 'Pre', $arguments);
185
186
        $query = $this->createQuery();
187
        $constraints = $this->getDefaultConstraints($query);
188
189
        if ($limit > 0) {
190
            $query->setLimit($limit);
191
        }
192
193
        $this->addTimeFrameConstraints(
194
            $constraints,
195
            $query,
196
            $arguments['startDate'] instanceof \DateTime ? DateTimeUtility::getDayStart($arguments['startDate'])->getTimestamp() : null,
197
            $arguments['endDate'] instanceof \DateTime ? DateTimeUtility::getDayEnd($arguments['endDate'])->getTimestamp() : null
198
        );
199
200
        if ($arguments['indexIds']) {
201
            $indexIds = [];
202
            $tabledIndexIds = [];
203
            foreach ($arguments['indexIds'] as $key => $indexId) {
204
                if (\is_int($key)) {
205
                    // Plain integers (= deprecated old way, stays in for compatibility)
206
                    $indexIds[] = $indexId;
207
                } elseif (\is_string($key) && \is_array($indexId)) {
208
                    // Table based values with array of foreign uids
209
                    $tabledIndexIds[] = [
210
                        'table' => $key,
211
                        'indexIds' => $indexId,
212
                    ];
213
                } elseif (\is_string($key) && \is_int($indexId)) {
214
                    // Table based single return value
215
                    $tabledIndexIds[] = [
216
                         'table' => $key,
217
                         'indexIds' => [$indexId],
218
                    ];
219
                }
220
            }
221
            $foreignIdConstraints = [];
222
            // Old way, just accept foreignUids as provided, not checking the table.
223
            // This has a caveat solved with the $tabledIndexIds
224
            if ($indexIds) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $indexIds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
225
                $foreignIdConstraints[] = $query->in('foreignUid', $indexIds);
226
            }
227
            if ($tabledIndexIds) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tabledIndexIds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
228
                // Handle each table individually on the filters
229
                // allowing for uids to be table specific.
230
                // If 1,3,5 on table_a are ok and 4,5,7 on table_b are ok,
231
                // don't show uid 1 from table_b
232
                foreach ($tabledIndexIds as $tabledIndexId) {
233
                    if ($tabledIndexId['indexIds']) {
234
                        // This table has used filters and returned some allowed uids.
235
                        // Providing non-existing values e.g.: -1 will remove everything
236
                        // unless other elements have found elements with the filters
237
                        $foreignIdConstraints[] = $query->logicalAnd([
238
                            $query->equals('foreignTable', $tabledIndexId['table']),
239
                            $query->in('foreignUid', $tabledIndexId['indexIds']),
240
                        ]);
241
                    }
242
                }
243
            }
244
            if (\count($foreignIdConstraints) > 1) {
245
                // Multiple valid tables should be grouped by "OR"
246
                // so it's either table_a with uids 1,3,4 OR table_b with uids 1,5,7
247
                $foreignIdConstraint = $query->logicalOr($foreignIdConstraints);
248
            } else {
249
                // Single constraint or no constraint should just be simply added
250
                $foreignIdConstraint = array_shift($foreignIdConstraints);
251
            }
252
            // If any foreignUid constraint survived, use it on the query
253
            if ($foreignIdConstraint) {
254
                $constraints[] = $foreignIdConstraint;
255
            }
256
        }
257
        if ($arguments['emptyPreResult']) {
258
            $constraints[] = $query->equals('uid', '-1');
259
        }
260
        $result = [
261
            'result' => $this->matchAndExecute($query, $constraints),
262
        ];
263
264
        $result = $this->callSignal(__CLASS__, __FUNCTION__ . 'Post', $result);
265
266
        return $result['result'];
267
    }
268
269
    /**
270
     * Find Past Events.
271
     *
272
     * @param int    $limit
273
     * @param string $sort
274
     *
275
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
276
     */
277
    public function findByPast(
278
        $limit,
279
        $sort
280
    ) {
281
        //create Query
282
        $query = $this->createQuery();
283
        //Get actual datetime
284
        $now = DateTimeUtility::getNow();
285
286
        $constraints = $this->getDefaultConstraints($query);
287
        $constraints[] = $query->lessThanOrEqual('startDate', $now->format('Y-m-d'));
288
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
289
        $query->setOrderings($this->getSorting($sort));
290
        $query->setLimit($limit);
291
292
        return $this->matchAndExecute($query, $constraints);
293
    }
294
295
    /**
296
     * Find by traversing information.
297
     *
298
     * @param Index      $index
299
     * @param bool|true  $future
300
     * @param bool|false $past
301
     * @param int        $limit
302
     * @param string     $sort
303
     * @param bool       $useIndexTime
304
     *
305
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
306
     */
307
    public function findByTraversing(
308
        Index $index,
309
        $future = true,
310
        $past = false,
311
        $limit = 100,
312
        $sort = QueryInterface::ORDER_ASCENDING,
313
        $useIndexTime = false
314
    ) {
315
        if (!$future && !$past) {
316
            return [];
317
        }
318
        $query = $this->createQuery();
319
320
        $now = DateTimeUtility::getNow();
321
        if ($useIndexTime) {
322
            $now = $index->getStartDate();
323
        }
324
325
        $constraints = [];
326
        $constraints[] = $query->logicalNot($query->equals('uid', $index->getUid()));
327
        $constraints[] = $query->equals('foreignTable', $index->getForeignTable());
328
        $constraints[] = $query->equals('foreignUid', $index->getForeignUid());
329
        if (!$future) {
330
            $constraints[] = $query->lessThanOrEqual('startDate', $now->format('Y-m-d'));
331
        }
332
        if (!$past) {
333
            $constraints[] = $query->greaterThanOrEqual('startDate', $now->format('Y-m-d'));
334
        }
335
336
        $query->setLimit($limit);
337
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
338
        $query->setOrderings($this->getSorting($sort));
339
340
        return $this->matchAndExecute($query, $constraints);
341
    }
342
343
    /**
344
     * Find by traversing information.
345
     *
346
     * @param DomainObjectInterface $event
347
     * @param bool|true             $future
348
     * @param bool|false            $past
349
     * @param int                   $limit
350
     * @param string                $sort
351
     *
352
     * @throws Exception
353
     *
354
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
355
     */
356
    public function findByEventTraversing(
357
        DomainObjectInterface $event,
358
        $future = true,
359
        $past = false,
360
        $limit = 100,
361
        $sort = QueryInterface::ORDER_ASCENDING
362
    ) {
363
        if (!$future && !$past) {
364
            return [];
365
        }
366
        $query = $this->createQuery();
367
368
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
369
370
        $this->setIndexTypes([$uniqueRegisterKey]);
371
372
        $now = DateTimeUtility::getNow()
373
            ->getTimestamp();
374
375
        $constraints = [];
376
377
        $localizedUid = $event->_getProperty('_localizedUid');
378
        $selectUid = $localizedUid ? $localizedUid : $event->getUid();
379
380
        $constraints[] = $query->equals('foreignUid', $selectUid);
381
        $constraints[] = $query->in('uniqueRegisterKey', $this->indexTypes);
382
        if (!$future) {
383
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
384
        }
385
        if (!$past) {
386
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
387
        }
388
389
        $query->setLimit($limit);
390
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
391
        $query->setOrderings($this->getSorting($sort));
392
393
        return $this->matchAndExecute($query, $constraints);
394
    }
395
396
    /**
397
     * find Year.
398
     *
399
     * @param int $year
400
     *
401
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
402
     */
403
    public function findYear(int $year)
404
    {
405
        return $this->findByTimeSlot(gmmktime(0, 0, 0, 1, 1, $year), gmmktime(0, 0, 0, 1, 1, $year + 1) - 1);
406
    }
407
408
    /**
409
     * find quarter.
410
     *
411
     * @param int $year
412
     * @param int $quarter
413
     *
414
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
415
     */
416
    public function findQuarter(int $year, int $quarter)
417
    {
418
        $startMonth = 1 + (3 * ($quarter - 1));
419
420
        return $this->findByTimeSlot(gmmktime(0, 0, 0, $startMonth, 1, $year), gmmktime(0, 0, 0, $startMonth + 3, 1, $year) - 1);
421
    }
422
423
    /**
424
     * find Month.
425
     *
426
     * @param int $year
427
     * @param int $month
428
     *
429
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
430
     */
431
    public function findMonth(int $year, int $month)
432
    {
433
        $startTime = gmmktime(0, 0, 0, $month, 1, $year);
434
        $endTime = gmmktime(0, 0, 0, $month + 1, 1, $year) - 1;
435
436
        return $this->findByTimeSlot($startTime, $endTime);
437
    }
438
439
    /**
440
     * find Week.
441
     *
442
     * @param int $year
443
     * @param int $week
444
     * @param int $weekStart See documentation for settings.weekStart
445
     *
446
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
447
     */
448
    public function findWeek($year, $week, $weekStart = 1)
449
    {
450
        $firstDayLocal = DateTimeUtility::convertWeekYear2DayMonthYear($week, $year, $weekStart);
451
        // Convert local date to utc date
452
        $firstDay = new \Datetime($firstDayLocal->format('Y-m-d'), DateTimeUtility::getUtcTimeZone());
453
        $endDate = clone $firstDay;
454
        $endDate->modify('+1 week');
455
        $endDate->modify('-1 second');
456
457
        return $this->findByTimeSlot($firstDay->getTimestamp(), $endDate->getTimestamp());
458
    }
459
460
    /**
461
     * Find different types and locations.
462
     *
463
     * @return array
464
     */
465
    public function findDifferentTypesAndLocations(): array
466
    {
467
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_calendarize_domain_model_index');
468
469
        return (array)$queryBuilder->select('unique_register_key', 'pid', 'foreign_table')->from('tx_calendarize_domain_model_index')->groupBy('pid', 'foreign_table', 'unique_register_key')->execute()->fetchAll();
470
    }
471
472
    /**
473
     * find day.
474
     *
475
     * @param int $year
476
     * @param int $month
477
     * @param int $day
478
     *
479
     * @throws Exception
480
     *
481
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
482
     */
483
    public function findDay(int $year, int $month, int $day)
484
    {
485
        $startTime = gmmktime(0, 0, 0, $month, $day, $year);
486
        $startDate = new \DateTime('@' . $startTime);
487
        $endDate = clone $startDate;
488
        $endDate->modify('+1 day');
489
        $endDate->modify('-1 second');
490
491
        return $this->findByTimeSlot($startDate->getTimestamp(), $endDate->getTimestamp());
492
    }
493
494
    /**
495
     * Set the default sorting direction.
496
     *
497
     * @param string $direction
498
     * @param string $field
499
     */
500
    public function setDefaultSortingDirection($direction, $field = '')
501
    {
502
        $this->defaultOrderings = $this->getSorting($direction, $field);
503
    }
504
505
    /**
506
     * Find by time slot.
507
     *
508
     * @param int      $startTime
509
     * @param int|null $endTime   null means open end
510
     *
511
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
512
     */
513
    public function findByTimeSlot($startTime, $endTime = null)
514
    {
515
        $query = $this->createQuery();
516
        $constraints = $this->getDefaultConstraints($query);
517
        $this->addTimeFrameConstraints($constraints, $query, $startTime, $endTime);
518
519
        $arguments = [
520
            'constraints' => $constraints,
521
            'query' => $query,
522
        ];
523
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
524
        $constraints = $arguments['constraints'] ?: $constraints;
525
526
        return $this->matchAndExecute($query, $constraints);
527
    }
528
529
    /**
530
     * Find all indices by the given Event model.
531
     *
532
     * @param DomainObjectInterface $event
533
     *
534
     * @throws Exception
535
     *
536
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
537
     */
538
    public function findByEvent(DomainObjectInterface $event)
539
    {
540
        $query = $this->createQuery();
541
542
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
543
544
        $this->setIndexTypes([$uniqueRegisterKey]);
545
        $constraints = $this->getDefaultConstraints($query);
546
        $constraints[] = $query->equals('foreignUid', $event->getUid());
547
        $query->matching($query->logicalAnd($constraints));
548
549
        return $query->execute();
550
    }
551
552
    /**
553
     * storage page selection.
554
     *
555
     * @return array
556
     */
557
    protected function getStoragePageIds()
558
    {
559
        if (null !== $this->overridePageIds) {
560
            return $this->overridePageIds;
561
        }
562
563
        $configurationManager = $this->objectManager->get(ConfigurationManagerInterface::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
564
        $frameworkConfig = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
565
        $storagePages = isset($frameworkConfig['persistence']['storagePid']) ? GeneralUtility::intExplode(
566
            ',',
567
            $frameworkConfig['persistence']['storagePid']
568
        ) : [];
569
        if (!empty($storagePages)) {
570
            return $storagePages;
571
        }
572
        if ($frameworkConfig instanceof BackendConfigurationManager) {
573
            return GeneralUtility::trimExplode(',', $frameworkConfig->getDefaultBackendStoragePid(), true);
574
        }
575
576
        return $storagePages;
577
    }
578
579
    /**
580
     * Get the default constraint for the queries.
581
     *
582
     * @param QueryInterface $query
583
     *
584
     * @return array
585
     */
586
    protected function getDefaultConstraints(QueryInterface $query)
587
    {
588
        $constraints = [];
589
        if (!empty($this->indexTypes)) {
590
            $indexTypes = $this->indexTypes;
591
            $constraints[] = $query->in('uniqueRegisterKey', $indexTypes);
592
        }
593
594
        $storagePages = $this->getStoragePageIds();
595
        if (!empty($storagePages)) {
596
            $constraints[] = $query->in('pid', $storagePages);
597
        }
598
599
        $arguments = [
600
            'indexIds' => [],
601
            'indexTypes' => $this->indexTypes,
602
        ];
603
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
604
605
        if ($arguments['indexIds']) {
606
            $constraints[] = $query->in('foreignUid', $arguments['indexIds']);
607
        }
608
609
        return $constraints;
610
    }
611
612
    /**
613
     * Add time frame related queries.
614
     *
615
     * @param array          $constraints
616
     * @param QueryInterface $query
617
     * @param int            $startTime
618
     * @param int|null       $endTime
619
     *
620
     * @see IndexUtility::isIndexInRange
621
     */
622
    protected function addTimeFrameConstraints(&$constraints, QueryInterface $query, $startTime = null, $endTime = null)
623
    {
624
        $arguments = [
625
            'constraints' => &$constraints,
626
            'query' => $query,
627
            'startTime' => $startTime,
628
            'endTime' => $endTime,
629
        ];
630
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
631
632
        if (null === $arguments['startTime'] && null === $arguments['endTime']) {
633
            return;
634
        }
635
        if (null === $arguments['startTime']) {
636
            // Simulate start time
637
            $arguments['startTime'] = DateTimeUtility::getNow()->getTimestamp() - DateTimeUtility::SECONDS_DECADE;
638
        } elseif (null === $arguments['endTime']) {
639
            // Simulate end time
640
            $arguments['endTime'] = DateTimeUtility::getNow()->getTimestamp() + DateTimeUtility::SECONDS_DECADE;
641
        }
642
643
        if ((bool)ConfigurationUtility::get('respectTimesInTimeFrameConstraints')) {
644
            $this->addDateTimeFrameConstraints($constraints, $query, $arguments);
645
        } else {
646
            $this->addDateFrameConstraints($constraints, $query, $arguments);
647
        }
648
    }
649
650
    /**
651
     * Adds time frame constraints which respect the actual index times.
652
     * Do not call this method directly. Call IndexRepository::addTimeFrameConstraints instead.
653
     *
654
     * @param array          $constraints
655
     * @param QueryInterface $query
656
     * @param array          $arguments
657
     *
658
     * @see IndexRepository::addTimeFrameConstraints
659
     */
660
    protected function addDateTimeFrameConstraints(&$constraints, QueryInterface $query, array $arguments)
661
    {
662
        $timezone = DateTimeUtility::getUtcTimeZone();
663
664
        // store values for start_date and start_time in separate variables
665
        $startDateTime = new \DateTime('@' . $arguments['startTime'], $timezone);
666
        $restrictionLowTime = DateTimeUtility::getDaySecondsOfDateTime($startDateTime);
667
        $restrictionLowDay = DateTimeUtility::resetTime($startDateTime)->format('Y-m-d');
668
669
        // store values for end_date and end_time in separate variables
670
        $endDateTime = new \DateTime('@' . $arguments['endTime'], $timezone);
671
        $restrictionHighTime = DateTimeUtility::getDaySecondsOfDateTime($endDateTime);
672
        $restrictionHighDay = DateTimeUtility::resetTime($endDateTime)->format('Y-m-d');
673
674
        $constraints[] = $query->logicalAnd([
675
            // (end_date === restrictionLowDay && end_time >= restrictionLowTime) || end_date > restrictionLowDay || (all_day === true && end_date >= restrictionLowDay)
676
            $query->logicalOr([
677
                $query->logicalAnd([
678
                    $query->equals('endDate', $restrictionLowDay),
679
                    $query->greaterThanOrEqual('endTime', $restrictionLowTime),
680
                ]),
681
                $query->greaterThan('endDate', $restrictionLowDay),
682
                $query->logicalAnd([
683
                    $query->equals('allDay', true),
684
                    $query->greaterThanOrEqual('endDate', $restrictionLowDay),
685
                ]),
686
            ]),
687
            // (start_date === restrictionHighDay && start_time <= restrictionHighTime) || start_date < restrictionHighDay || (all_day === true && start_date <= restrictionHighDay)
688
            $query->logicalOr([
689
                $query->logicalAnd([
690
                    $query->equals('startDate', $restrictionHighDay),
691
                    $query->lessThanOrEqual('startTime', $restrictionHighTime),
692
                ]),
693
                $query->lessThan('startDate', $restrictionHighDay),
694
                $query->logicalAnd([
695
                    $query->equals('allDay', true),
696
                    $query->lessThanOrEqual('startDate', $restrictionHighDay),
697
                ]),
698
            ]),
699
        ]);
700
    }
701
702
    /**
703
     * Adds time frame constraints which respect only the index dates, not the actual index times.
704
     * Do not call this method directly. Call IndexRepository::addTimeFrameConstraints instead.
705
     *
706
     * @param array          $constraints
707
     * @param QueryInterface $query
708
     * @param array          $arguments
709
     *
710
     * @see IndexRepository::addTimeFrameConstraints
711
     */
712
    protected function addDateFrameConstraints(&$constraints, QueryInterface $query, array $arguments)
713
    {
714
        $orConstraint = [];
715
716
        // DateTimeUtility::getTimeZone() ?!
717
        $startDate = (new \DateTime('@' . $arguments['startTime']))->format('Y-m-d');
718
        $endDate = (new \DateTime('@' . $arguments['endTime']))->format('Y-m-d');
719
720
        // before - in
721
        $beforeIn = [
722
            $query->lessThan('startDate', $startDate),
723
            $query->greaterThanOrEqual('endDate', $startDate),
724
            $query->lessThan('endDate', $endDate),
725
        ];
726
        $orConstraint[] = $query->logicalAnd($beforeIn);
727
728
        // in - in
729
        $inIn = [
730
            $query->greaterThanOrEqual('startDate', $startDate),
731
            $query->lessThanOrEqual('endDate', $endDate),
732
        ];
733
        $orConstraint[] = $query->logicalAnd($inIn);
734
735
        // in - after
736
        $inAfter = [
737
            $query->greaterThanOrEqual('startDate', $startDate),
738
            $query->lessThan('startDate', $endDate),
739
            $query->greaterThanOrEqual('endDate', $endDate),
740
        ];
741
        $orConstraint[] = $query->logicalAnd($inAfter);
742
743
        // before - after
744
        $beforeAfter = [
745
            $query->lessThan('startDate', $startDate),
746
            $query->greaterThan('endDate', $endDate),
747
        ];
748
        $orConstraint[] = $query->logicalAnd($beforeAfter);
749
750
        // finish
751
        $constraints[] = $query->logicalOr($orConstraint);
752
    }
753
754
    /**
755
     * Get the sorting.
756
     *
757
     * @param string $direction
758
     * @param string $field
759
     *
760
     * @return array
761
     */
762
    protected function getSorting($direction, $field = '')
763
    {
764
        if ('withrangelast' === $field) {
765
            return [
766
                'endDate' => $direction,
767
                'startDate' => $direction,
768
                'startTime' => $direction,
769
            ];
770
        }
771
        if ('end' !== $field) {
772
            $field = 'start';
773
        }
774
775
        return [
776
            $field . 'Date' => $direction,
777
            $field . 'Time' => $direction,
778
        ];
779
    }
780
}
781