Completed
Pull Request — master (#375)
by
unknown
02:06
created

IndexRepository::addDateFrameConstraints()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 9.328
c 0
b 0
f 0
cc 1
nc 1
nop 3
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\Domain\Model\Request\OptionRequest;
13
use HDNET\Calendarize\Utility\ConfigurationUtility;
14
use HDNET\Calendarize\Utility\DateTimeUtility;
15
use HDNET\Calendarize\Utility\ExtensionConfigurationUtility;
16
use TYPO3\CMS\Core\Database\ConnectionPool;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;
19
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
20
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
21
use TYPO3\CMS\Extbase\Object\ObjectManager;
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
        $query->getQuerySettings()->setLanguageMode($this->getIndexLanguageMode());
62
63
        return $query;
64
    }
65
66
    /**
67
     * Set the index types.
68
     *
69
     * @param array $types
70
     */
71
    public function setIndexTypes(array $types)
72
    {
73
        $this->indexTypes = $types;
74
    }
75
76
    /**
77
     * Override page IDs.
78
     *
79
     * @param array $overridePageIds
80
     */
81
    public function setOverridePageIds($overridePageIds)
82
    {
83
        $this->overridePageIds = $overridePageIds;
84
    }
85
86
    /**
87
     * Select indecies for Backend.
88
     *
89
     * @param OptionRequest $options
90
     *
91
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
92
     */
93
    public function findAllForBackend(OptionRequest $options)
94
    {
95
        $query = $this->createQuery();
96
        $query->getQuerySettings()->setIgnoreEnableFields(true);
97
        $query->getQuerySettings()->setRespectSysLanguage(false);
98
        $query->getQuerySettings()->setLanguageOverlayMode(false);
99
        $query->getQuerySettings()->setLanguageMode('ignore');
100
101
        // Notice Selection without any language handling
102
        unset($GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['languageField'], $GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['transOrigPointerField']);
103
104
        if ('asc' === $options->getDirection()) {
105
            $query->setOrderings([
106
                'start_date' => QueryInterface::ORDER_ASCENDING,
107
                'start_time' => QueryInterface::ORDER_ASCENDING,
108
            ]);
109
        } else {
110
            $query->setOrderings([
111
                'start_date' => QueryInterface::ORDER_DESCENDING,
112
                'start_time' => QueryInterface::ORDER_DESCENDING,
113
            ]);
114
        }
115
116
        if ((int) $options->getPid() > 0) {
117
            $query->matching($query->equals('pid', (int) $options->getPid()));
118
        }
119
120
        $result = $query->execute();
121
122
        return $result;
123
    }
124
125
    /**
126
     * Find List.
127
     *
128
     * @param int        $limit
129
     * @param int|string $listStartTime
130
     * @param int        $startOffsetHours
131
     * @param int        $overrideStartDate
132
     * @param int        $overrideEndDate
133
     *
134
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
135
     */
136
    public function findList(
137
        $limit = 0,
138
        $listStartTime = 0,
139
        $startOffsetHours = 0,
140
        $overrideStartDate = 0,
141
        $overrideEndDate = 0
142
    ) {
143
        if ($overrideStartDate > 0) {
144
            $startTimestamp = $overrideStartDate;
145
        } else {
146
            $now = DateTimeUtility::getNow();
147
            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...
148
                $now->setTime(0, 0, 0);
149
            }
150
            $now->modify($startOffsetHours . ' hours');
151
            $startTimestamp = $now->getTimestamp();
152
        }
153
        $endTimestamp = null;
154
        if ($overrideEndDate > 0) {
155
            $endTimestamp = $overrideEndDate;
156
        }
157
158
        $result = $this->findByTimeSlot($startTimestamp, $endTimestamp);
159
        if ($limit > 0) {
160
            $query = $result->getQuery();
161
            $query->setLimit($limit);
162
            $result = $query->execute();
163
        }
164
165
        return $result;
166
    }
167
168
    /**
169
     * Find by custom search.
170
     *
171
     * @param \DateTime $startDate
172
     * @param \DateTime $endDate
173
     * @param array     $customSearch
174
     * @param int       $limit
175
     *
176
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
177
     */
178
    public function findBySearch(\DateTime $startDate = null, \DateTime $endDate = null, array $customSearch = [], int $limit = 0)
179
    {
180
        $arguments = [
181
            'indexIds' => [],
182
            'startDate' => $startDate,
183
            'endDate' => $endDate,
184
            'customSearch' => $customSearch,
185
            'indexTypes' => $this->indexTypes,
186
            'emptyPreResult' => false,
187
        ];
188
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__ . 'Pre', $arguments);
189
190
        $query = $this->createQuery();
191
        $constraints = $this->getDefaultConstraints($query);
192
193
        if ($limit > 0) {
194
            $query->setLimit($limit);
195
        }
196
197
        $this->addTimeFrameConstraints(
198
            $constraints,
199
            $query,
200
            $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...
201
            $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...
202
        );
203
204
        if ($arguments['indexIds']) {
205
            $constraints[] = $query->in('foreign_uid', $arguments['indexIds']);
206
        }
207
        if ($arguments['emptyPreResult']) {
208
            $constraints[] = $query->equals('uid', '-1');
209
        }
210
        $result = [
211
            'result' => $this->matchAndExecute($query, $constraints),
212
        ];
213
214
        $result = $this->callSignal(__CLASS__, __FUNCTION__ . 'Post', $result);
215
216
        return $result['result'];
217
    }
218
219
    /**
220
     * Find Past Events.
221
     *
222
     * @param int    $limit
223
     * @param string $sort
224
     *
225
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
226
     */
227
    public function findByPast(
228
        $limit,
229
        $sort
230
    ) {
231
        //create Query
232
        $query = $this->createQuery();
233
        //Get actual datetime
234
        $now = DateTimeUtility::getNow()->getTimestamp();
235
236
        $constraints = $this->getDefaultConstraints($query);
237
        $constraints[] = $query->lessThanOrEqual('startDate', $now);
238
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
239
        $query->setOrderings($this->getSorting($sort));
240
        $query->setLimit($limit);
241
242
        return $this->matchAndExecute($query, $constraints);
243
    }
244
245
    /**
246
     * Find by traversing information.
247
     *
248
     * @param Index      $index
249
     * @param bool|true  $future
250
     * @param bool|false $past
251
     * @param int        $limit
252
     * @param string     $sort
253
     * @param bool       $useIndexTime
254
     *
255
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
256
     */
257
    public function findByTraversing(
258
        Index $index,
259
        $future = true,
260
        $past = false,
261
        $limit = 100,
262
        $sort = QueryInterface::ORDER_ASCENDING,
263
        $useIndexTime = false
264
    ) {
265
        if (!$future && !$past) {
266
            return [];
267
        }
268
        $query = $this->createQuery();
269
270
        $now = DateTimeUtility::getNow()
271
            ->getTimestamp();
272
        if ($useIndexTime) {
273
            $now = $index->getStartDate()->getTimestamp();
274
        }
275
276
        $constraints = [];
277
        $constraints[] = $query->logicalNot($query->equals('uid', $index->getUid()));
278
        $constraints[] = $query->equals('foreignTable', $index->getForeignTable());
279
        $constraints[] = $query->equals('foreignUid', $index->getForeignUid());
280
        if (!$future) {
281
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
282
        }
283
        if (!$past) {
284
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
285
        }
286
287
        $query->setLimit($limit);
288
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
289
        $query->setOrderings($this->getSorting($sort));
290
291
        return $this->matchAndExecute($query, $constraints);
292
    }
293
294
    /**
295
     * Find by traversing information.
296
     *
297
     * @param DomainObjectInterface $event
298
     * @param bool|true             $future
299
     * @param bool|false            $past
300
     * @param int                   $limit
301
     * @param string                $sort
302
     *
303
     * @throws Exception
304
     *
305
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
306
     */
307
    public function findByEventTraversing(
308
        DomainObjectInterface $event,
309
        $future = true,
310
        $past = false,
311
        $limit = 100,
312
        $sort = QueryInterface::ORDER_ASCENDING
313
    ) {
314
        if (!$future && !$past) {
315
            return [];
316
        }
317
        $query = $this->createQuery();
318
319
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
320
321
        $this->setIndexTypes([$uniqueRegisterKey]);
322
323
        $now = DateTimeUtility::getNow()
324
            ->getTimestamp();
325
326
        $constraints = [];
327
328
        $localizedUid = $event->_getProperty('_localizedUid');
329
        $selectUid = $localizedUid ? $localizedUid : $event->getUid();
330
331
        $constraints[] = $query->equals('foreignUid', $selectUid);
332
        $constraints[] = $query->in('uniqueRegisterKey', $this->indexTypes);
333
        if (!$future) {
334
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
335
        }
336
        if (!$past) {
337
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
338
        }
339
340
        $query->setLimit($limit);
341
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
342
        $query->setOrderings($this->getSorting($sort));
343
344
        return $this->matchAndExecute($query, $constraints);
345
    }
346
347
    /**
348
     * find Year.
349
     *
350
     * @param int $year
351
     *
352
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
353
     */
354
    public function findYear(int $year)
355
    {
356
        return $this->findByTimeSlot(\mktime(0, 0, 0, 1, 1, $year), \mktime(0, 0, 0, 1, 1, $year + 1) - 1);
357
    }
358
359
    /**
360
     * find quarter.
361
     *
362
     * @param int $year
363
     * @param int $quarter
364
     *
365
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
366
     */
367
    public function findQuarter(int $year, int $quarter)
368
    {
369
        $startMonth = 1 + (3 * ($quarter - 1));
370
371
        return $this->findByTimeSlot(\mktime(0, 0, 0, $startMonth, 1, $year), \mktime(0, 0, 0, $startMonth + 3, 1, $year) - 1);
372
    }
373
374
    /**
375
     * find Month.
376
     *
377
     * @param int $year
378
     * @param int $month
379
     *
380
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
381
     */
382
    public function findMonth(int $year, int $month)
383
    {
384
        $startTime = \mktime(0, 0, 0, $month, 1, $year);
385
        $endTime = \mktime(0, 0, 0, $month + 1, 1, $year) - 1;
386
387
        return $this->findByTimeSlot($startTime, $endTime);
388
    }
389
390
    /**
391
     * find Week.
392
     *
393
     * @param int $year
394
     * @param int $week
395
     * @param int $weekStart See documentation for settings.weekStart
396
     *
397
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
398
     */
399
    public function findWeek($year, $week, $weekStart = 1)
400
    {
401
        $weekStart = (int) $weekStart;
402
        $daysShift = $weekStart - 1;
403
        $firstDay = DateTimeUtility::convertWeekYear2DayMonthYear($week, $year);
404
        $timezone = DateTimeUtility::getTimeZone();
405
        $firstDay->setTimezone($timezone);
406
        if (0 !== $daysShift) {
407
            $firstDay->modify('+' . $daysShift . ' days');
408
        }
409
        $endDate = clone $firstDay;
410
        $endDate->modify('+1 week');
411
        $endDate->modify('-1 second');
412
413
        return $this->findByTimeSlot($firstDay->getTimestamp(), $endDate->getTimestamp());
414
    }
415
416
    /**
417
     * Find different types and locations.
418
     *
419
     * @return array
420
     */
421
    public function findDifferentTypesAndLocations(): array
422
    {
423
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_calendarize_domain_model_index');
424
425
        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();
426
    }
427
428
    /**
429
     * find day.
430
     *
431
     * @param int $year
432
     * @param int $month
433
     * @param int $day
434
     *
435
     * @throws Exception
436
     *
437
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
438
     */
439
    public function findDay(int $year, int $month, int $day)
440
    {
441
        $startTime = \mktime(0, 0, 0, $month, $day, $year);
442
        $startDate = new \DateTime('@' . $startTime);
443
        $endDate = clone $startDate;
444
        $endDate->modify('+1 day');
445
        $endDate->modify('-1 second');
446
447
        return $this->findByTimeSlot($startDate->getTimestamp(), $endDate->getTimestamp());
448
    }
449
450
    /**
451
     * Set the default sorting direction.
452
     *
453
     * @param string $direction
454
     * @param string $field
455
     */
456
    public function setDefaultSortingDirection($direction, $field = '')
457
    {
458
        $this->defaultOrderings = $this->getSorting($direction, $field);
459
    }
460
461
    /**
462
     * Find by time slot.
463
     *
464
     * @param int      $startTime
465
     * @param int|null $endTime   null means open end
466
     *
467
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
468
     */
469
    public function findByTimeSlot($startTime, $endTime = null)
470
    {
471
        $query = $this->createQuery();
472
        $constraints = $this->getDefaultConstraints($query);
473
        $this->addTimeFrameConstraints($constraints, $query, $startTime, $endTime);
474
475
        return $this->matchAndExecute($query, $constraints);
476
    }
477
478
    /**
479
     * Find all indices by the given Event model.
480
     *
481
     * @param DomainObjectInterface $event
482
     *
483
     * @throws Exception
484
     *
485
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
486
     */
487
    public function findByEvent(DomainObjectInterface $event)
488
    {
489
        $query = $this->createQuery();
490
491
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
492
493
        $this->setIndexTypes([$uniqueRegisterKey]);
494
        $constraints = $this->getDefaultConstraints($query);
495
        $constraints[] = $query->equals('foreignUid', $event->getUid());
496
        $query->matching($query->logicalAnd($constraints));
497
498
        return $query->execute();
499
    }
500
501
    /**
502
     * Get index language mode.
503
     *
504
     * @return string
505
     */
506
    protected function getIndexLanguageMode()
507
    {
508
        static $mode;
509
        if (null !== $mode) {
510
            return $mode;
511
        }
512
513
        $objectManager = new ObjectManager();
514
        /** @var ConfigurationManagerInterface $config */
515
        $config = $objectManager->get(ConfigurationManagerInterface::class);
516
        $pluginConfig = $config->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
517
518
        $mode = isset($pluginConfig['indexLanguageMode']) ? (string) $pluginConfig['indexLanguageMode'] : 'strict';
519
520
        return $mode;
521
    }
522
523
    /**
524
     * storage page selection.
525
     *
526
     * @return array
527
     */
528
    protected function getStoragePageIds()
529
    {
530
        if (!empty($this->overridePageIds)) {
531
            return $this->overridePageIds;
532
        }
533
534
        $configurationManager = $this->objectManager->get(ConfigurationManagerInterface::class);
535
        $frameworkConfig = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
536
        $storagePages = isset($frameworkConfig['persistence']['storagePid']) ? GeneralUtility::intExplode(
537
            ',',
538
            $frameworkConfig['persistence']['storagePid']
539
        ) : [];
540
        if (!empty($storagePages)) {
541
            return $storagePages;
542
        }
543
        if ($frameworkConfig instanceof BackendConfigurationManager) {
544
            return GeneralUtility::trimExplode(',', $frameworkConfig->getDefaultBackendStoragePid(), true);
545
        }
546
547
        return $storagePages;
548
    }
549
550
    /**
551
     * Get the default constraint for the queries.
552
     *
553
     * @param QueryInterface $query
554
     *
555
     * @return array
556
     */
557
    protected function getDefaultConstraints(QueryInterface $query)
558
    {
559
        $constraints = [];
560
        if (!empty($this->indexTypes)) {
561
            $indexTypes = $this->indexTypes;
562
            $constraints[] = $query->in('uniqueRegisterKey', $indexTypes);
563
        }
564
565
        $storagePages = $this->getStoragePageIds();
566
        if (!empty($storagePages)) {
567
            $constraints[] = $query->in('pid', $storagePages);
568
        }
569
570
        $arguments = [
571
            'indexIds' => [],
572
            'indexTypes' => $this->indexTypes,
573
        ];
574
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
575
576
        if ($arguments['indexIds']) {
577
            $constraints[] = $query->in('foreign_uid', $arguments['indexIds']);
578
        }
579
580
        return $constraints;
581
    }
582
583
    /**
584
     * Add time frame related queries.
585
     *
586
     * @param array          $constraints
587
     * @param QueryInterface $query
588
     * @param int            $startTime
589
     * @param int|null       $endTime
590
     *
591
     * @see IndexUtility::isIndexInRange
592
     */
593
    protected function addTimeFrameConstraints(&$constraints, QueryInterface $query, $startTime = null, $endTime = null)
594
    {
595
        $arguments = [
596
            'constraints' => &$constraints,
597
            'query' => $query,
598
            'startTime' => $startTime,
599
            'endTime' => $endTime,
600
        ];
601
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
602
603
        if (null === $arguments['startTime'] && null === $arguments['endTime']) {
604
            return;
605
        }
606
        if (null === $arguments['startTime']) {
607
            // Simulate start time
608
            $arguments['startTime'] = DateTimeUtility::getNow()->getTimestamp() - DateTimeUtility::SECONDS_DECADE;
609
        } elseif (null === $arguments['endTime']) {
610
            // Simulate end time
611
            $arguments['endTime'] = DateTimeUtility::getNow()->getTimestamp() + DateTimeUtility::SECONDS_DECADE;
612
        }
613
614
        if ((bool)ConfigurationUtility::get('respectTimesInTimeFrameConstraints')) {
615
            $this->addDateTimeFrameConstraints($constraints, $query, $arguments);
616
        } else {
617
            $this->addDateFrameConstraints($constraints, $query, $arguments);
618
        }
619
    }
620
621
    /**
622
     * Adds time frame constraints which respect the actual index times.
623
     * Do not call this method directly. Call IndexRepository::addTimeFrameConstraints instead.
624
     *
625
     * @param array          $constraints
626
     * @param QueryInterface $query
627
     * @param array          $arguments
628
     *
629
     * @see IndexRepository::addTimeFrameConstraints
630
     */
631
    protected function addDateTimeFrameConstraints(&$constraints, QueryInterface $query, array $arguments)
632
    {
633
        $timezone = new \DateTimeZone('UTC');
634
635
        // store values for start_date and start_time in separate variables
636
        $startDateTime = new \DateTime('@'.$arguments['startTime'], $timezone);
637
        $restrictionLowTime = DateTimeUtility::getDaySecondsOfDateTime($startDateTime);
638
        $restrictionLowDay = DateTimeUtility::resetTime($startDateTime)->getTimestamp();
639
640
        // store values for end_date and end_time in separate variables
641
        $endDateTime = new \DateTime('@'.$arguments['endTime'], $timezone);
642
        $restrictionHighTime = DateTimeUtility::getDaySecondsOfDateTime($endDateTime);
643
        $restrictionHighDay = DateTimeUtility::resetTime($endDateTime)->getTimestamp();
644
645
        $constraints[] = $query->logicalAnd([
646
            // (end_date === restrictionLowDay && end_time >= restrictionLowTime) || end_date > restrictionLowDay || (all_day === true && end_date >= restrictionLowDay)
647
            $query->logicalOr([
648
                $query->logicalAnd([
649
                    $query->equals('end_date', $restrictionLowDay),
650
                    $query->greaterThanOrEqual('end_time', $restrictionLowTime),
651
                ]),
652
                $query->greaterThan('end_date', $restrictionLowDay),
653
                $query->logicalAnd([
654
                    $query->equals('all_day', true),
655
                    $query->greaterThanOrEqual('end_date', $restrictionLowDay),
656
                ])
657
            ]),
658
            // (start_date === restrictionHighDay && start_time <= restrictionHighTime) || start_date < restrictionHighDay || (all_day === true && start_date <= restrictionHighDay)
659
            $query->logicalOr([
660
                $query->logicalAnd([
661
                    $query->equals('start_date', $restrictionHighDay),
662
                    $query->lessThanOrEqual('start_time', $restrictionHighTime),
663
                ]),
664
                $query->lessThan('start_date', $restrictionHighDay),
665
                $query->logicalAnd([
666
                    $query->equals('all_day', true),
667
                    $query->lessThanOrEqual('start_date', $restrictionHighDay),
668
                ])
669
            ]),
670
        ]);
671
    }
672
673
    /**
674
     * Adds time frame constraints which respect only the index dates, not the actual index times.
675
     * Do not call this method directly. Call IndexRepository::addTimeFrameConstraints instead.
676
     *
677
     * @param array          $constraints
678
     * @param QueryInterface $query
679
     * @param array          $arguments
680
     *
681
     * @see IndexRepository::addTimeFrameConstraints
682
     */
683
    protected function addDateFrameConstraints(&$constraints, QueryInterface $query, array $arguments)
684
    {
685
        $orConstraint = [];
686
687
        // before - in
688
        $beforeIn = [
689
            $query->lessThan('start_date', $arguments['startTime']),
690
            $query->greaterThanOrEqual('end_date', $arguments['startTime']),
691
            $query->lessThan('end_date', $arguments['endTime']),
692
        ];
693
        $orConstraint[] = $query->logicalAnd($beforeIn);
694
695
        // in - in
696
        $inIn = [
697
            $query->greaterThanOrEqual('start_date', $arguments['startTime']),
698
            $query->lessThan('end_date', $arguments['endTime']),
699
        ];
700
        $orConstraint[] = $query->logicalAnd($inIn);
701
702
        // in - after
703
        $inAfter = [
704
            $query->greaterThanOrEqual('start_date', $arguments['startTime']),
705
            $query->lessThan('start_date', $arguments['endTime']),
706
            $query->greaterThanOrEqual('end_date', $arguments['endTime']),
707
        ];
708
        $orConstraint[] = $query->logicalAnd($inAfter);
709
710
        // before - after
711
        $beforeAfter = [
712
            $query->lessThan('start_date', $arguments['startTime']),
713
            $query->greaterThan('end_date', $arguments['endTime']),
714
        ];
715
        $orConstraint[] = $query->logicalAnd($beforeAfter);
716
717
        // finish
718
        $constraints[] = $query->logicalOr($orConstraint);
719
    }
720
721
    /**
722
     * Get the sorting.
723
     *
724
     * @param string $direction
725
     * @param string $field
726
     *
727
     * @return array
728
     */
729
    protected function getSorting($direction, $field = '')
730
    {
731
        if ('withrangelast' === $field) {
732
            return [
733
                'end_date' => $direction,
734
                'start_date' => $direction,
735
                'start_time' => $direction,
736
            ];
737
        }
738
        if ('end' !== $field) {
739
            $field = 'start';
740
        }
741
742
        return [
743
            $field . '_date' => $direction,
744
            $field . '_time' => $direction,
745
        ];
746
    }
747
}
748