Completed
Push — master ( e5ed3f...eba3fc )
by Tim
02:31
created

IndexRepository::findByUids()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 1
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\Event\AddTimeFrameConstraintsEvent;
14
use HDNET\Calendarize\Utility\ConfigurationUtility;
15
use HDNET\Calendarize\Utility\DateTimeUtility;
16
use HDNET\Calendarize\Utility\ExtensionConfigurationUtility;
17
use Psr\EventDispatcher\EventDispatcherInterface;
18
use TYPO3\CMS\Core\Database\ConnectionPool;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;
21
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
22
use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
23
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
24
25
/**
26
 * Index repository.
27
 */
28
class IndexRepository extends AbstractRepository
29
{
30
    /**
31
     * Default orderings for index records.
32
     *
33
     * @var array
34
     */
35
    protected $defaultOrderings = [
36
        'start_date' => QueryInterface::ORDER_ASCENDING,
37
        'start_time' => QueryInterface::ORDER_ASCENDING,
38
    ];
39
40
    /**
41
     * Index types for selection.
42
     *
43
     * @var array
44
     */
45
    protected $indexTypes = [];
46
47
    /**
48
     * Override page ids.
49
     *
50
     * @var array
51
     */
52
    protected $overridePageIds;
53
54
    /**
55
     * @var EventDispatcherInterface
56
     */
57
    protected $eventDispatcher;
58
59
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher): void
60
    {
61
        $this->eventDispatcher = $eventDispatcher;
62
    }
63
64
    /**
65
     * Create query.
66
     *
67
     * @return QueryInterface
68
     */
69
    public function createQuery()
70
    {
71
        $query = parent::createQuery();
72
73
        return $query;
74
    }
75
76
    /**
77
     * Set the index types.
78
     *
79
     * @param array $types
80
     */
81
    public function setIndexTypes(array $types)
82
    {
83
        $this->indexTypes = $types;
84
    }
85
86
    /**
87
     * Override page IDs.
88
     *
89
     * @param array $overridePageIds
90
     */
91
    public function setOverridePageIds($overridePageIds)
92
    {
93
        $this->overridePageIds = $overridePageIds;
94
    }
95
96
    /**
97
     * Select indecies for Backend.
98
     *
99
     * @param OptionRequest $options
100
     * @param limit values to these pages
101
     *
102
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
103
     */
104
    public function findAllForBackend(OptionRequest $options, array $allowedPages = [])
105
    {
106
        $query = $this->createQuery();
107
        $query->getQuerySettings()->setIgnoreEnableFields(true);
108
        $query->getQuerySettings()->setRespectSysLanguage(false);
109
        $query->getQuerySettings()->setLanguageOverlayMode(false);
110
111
        // Notice Selection without any language handling
112
        unset($GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['languageField'], $GLOBALS['TCA']['tx_calendarize_domain_model_index']['ctrl']['transOrigPointerField']);
113
114
        if ('asc' === $options->getDirection()) {
115
            $query->setOrderings([
116
                'start_date' => QueryInterface::ORDER_ASCENDING,
117
                'start_time' => QueryInterface::ORDER_ASCENDING,
118
            ]);
119
        } else {
120
            $query->setOrderings([
121
                'start_date' => QueryInterface::ORDER_DESCENDING,
122
                'start_time' => QueryInterface::ORDER_DESCENDING,
123
            ]);
124
        }
125
126
        if ((int)$options->getPid() > 0) {
127
            $query->matching($query->equals('pid', (int)$options->getPid()));
128
        } elseif ($allowedPages) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $allowedPages 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...
129
            $query->matching($query->in('pid', $allowedPages));
130
        }
131
132
        return $query->execute();
133
    }
134
135
    /**
136
     * Find List.
137
     *
138
     * @param int        $limit
139
     * @param int|string $listStartTime
140
     * @param int        $startOffsetHours
141
     * @param int        $overrideStartDate
142
     * @param int        $overrideEndDate
143
     *
144
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
145
     */
146
    public function findList(
147
        $limit = 0,
148
        $listStartTime = 0,
149
        $startOffsetHours = 0,
150
        $overrideStartDate = 0,
151
        $overrideEndDate = 0
152
    ) {
153
        $startTime = DateTimeUtility::getNow();
154
        $endTime = null;
155
156
        if ($overrideStartDate > 0) {
157
            // Note: setTimestamp does not change the timezone
158
            $startTime->setTimestamp($overrideStartDate);
159
        } else {
160
            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...
161
                $startTime->setTime(0, 0, 0);
162
            }
163
            $startTime->modify($startOffsetHours . ' hours');
164
        }
165
166
        if ($overrideEndDate > 0) {
167
            $endTime = DateTimeUtility::getNow()->setTimestamp($overrideEndDate);
168
        }
169
170
        $result = $this->findByTimeSlot($startTime, $endTime);
171
        if ($limit > 0) {
172
            $query = $result->getQuery();
173
            $query->setLimit($limit);
174
            $result = $query->execute();
175
        }
176
177
        return $result;
178
    }
179
180
    /**
181
     * Find by custom search.
182
     *
183
     * @param \DateTimeInterface|null $startDate
184
     * @param \DateTimeInterface|null $endDate
185
     * @param array                   $customSearch
186
     * @param int                     $limit
187
     *
188
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
189
     */
190
    public function findBySearch(
191
        \DateTimeInterface $startDate = null,
192
        \DateTimeInterface $endDate = null,
193
        array $customSearch = [],
194
        int $limit = 0
195
    ) {
196
        $arguments = [
197
            'indexIds' => [],
198
            'startDate' => $startDate,
199
            'endDate' => $endDate,
200
            'customSearch' => $customSearch,
201
            'indexTypes' => $this->indexTypes,
202
            'emptyPreResult' => false,
203
        ];
204
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__ . 'Pre', $arguments);
205
206
        $query = $this->createQuery();
207
        $constraints = $this->getDefaultConstraints($query);
208
209
        if ($limit > 0) {
210
            $query->setLimit($limit);
211
        }
212
213
        $this->addTimeFrameConstraints(
214
            $constraints,
215
            $query,
216
            $arguments['startDate'],
217
            $arguments['endDate']
218
        );
219
220
        if ($arguments['indexIds']) {
221
            $indexIds = [];
222
            $tabledIndexIds = [];
223
            foreach ($arguments['indexIds'] as $key => $indexId) {
224
                if (\is_int($key)) {
225
                    // Plain integers (= deprecated old way, stays in for compatibility)
226
                    $indexIds[] = $indexId;
227
                } elseif (\is_string($key) && \is_array($indexId)) {
228
                    // Table based values with array of foreign uids
229
                    $tabledIndexIds[] = [
230
                        'table' => $key,
231
                        'indexIds' => $indexId,
232
                    ];
233
                } elseif (\is_string($key) && \is_int($indexId)) {
234
                    // Table based single return value
235
                    $tabledIndexIds[] = [
236
                         'table' => $key,
237
                         'indexIds' => [$indexId],
238
                    ];
239
                }
240
            }
241
            $foreignIdConstraints = [];
242
            // Old way, just accept foreignUids as provided, not checking the table.
243
            // This has a caveat solved with the $tabledIndexIds
244
            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...
245
                $foreignIdConstraints[] = $query->in('foreignUid', $indexIds);
246
            }
247
            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...
248
                // Handle each table individually on the filters
249
                // allowing for uids to be table specific.
250
                // If 1,3,5 on table_a are ok and 4,5,7 on table_b are ok,
251
                // don't show uid 1 from table_b
252
                foreach ($tabledIndexIds as $tabledIndexId) {
253
                    if ($tabledIndexId['indexIds']) {
254
                        // This table has used filters and returned some allowed uids.
255
                        // Providing non-existing values e.g.: -1 will remove everything
256
                        // unless other elements have found elements with the filters
257
                        $foreignIdConstraints[] = $query->logicalAnd([
258
                            $query->equals('foreignTable', $tabledIndexId['table']),
259
                            $query->in('foreignUid', $tabledIndexId['indexIds']),
260
                        ]);
261
                    }
262
                }
263
            }
264
            if (\count($foreignIdConstraints) > 1) {
265
                // Multiple valid tables should be grouped by "OR"
266
                // so it's either table_a with uids 1,3,4 OR table_b with uids 1,5,7
267
                $foreignIdConstraint = $query->logicalOr($foreignIdConstraints);
268
            } else {
269
                // Single constraint or no constraint should just be simply added
270
                $foreignIdConstraint = array_shift($foreignIdConstraints);
271
            }
272
            // If any foreignUid constraint survived, use it on the query
273
            if ($foreignIdConstraint) {
274
                $constraints[] = $foreignIdConstraint;
275
            }
276
        }
277
        if ($arguments['emptyPreResult']) {
278
            $constraints[] = $query->equals('uid', '-1');
279
        }
280
        $result = [
281
            'result' => $this->matchAndExecute($query, $constraints),
282
        ];
283
284
        $result = $this->callSignal(__CLASS__, __FUNCTION__ . 'Post', $result);
285
286
        return $result['result'];
287
    }
288
289
    /**
290
     * Find Past Events.
291
     *
292
     * @param int    $limit
293
     * @param string $sort
294
     *
295
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
296
     */
297
    public function findByPast(
298
        $limit,
299
        $sort
300
    ) {
301
        //create Query
302
        $query = $this->createQuery();
303
        //Get actual datetime
304
        $now = DateTimeUtility::getNow();
305
306
        $constraints = $this->getDefaultConstraints($query);
307
        $constraints[] = $query->lessThanOrEqual('startDate', $now->format('Y-m-d'));
308
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
309
        $query->setOrderings($this->getSorting($sort));
310
        if ($limit > 0) {
311
            $query->setLimit($limit);
312
        }
313
314
        return $this->matchAndExecute($query, $constraints);
315
    }
316
317
    /**
318
     * Find by Index UIDs.
319
     *
320
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
321
     */
322
    public function findByUids(
323
        array $uids
324
    ) {
325
        $query = $this->createQuery();
326
        $query->setOrderings($this->getSorting(QueryInterface::ORDER_ASCENDING));
327
        $constraints = [
328
            $query->in('uid', $uids)
329
        ];
330
331
        return $this->matchAndExecute($query, $constraints);
332
    }
333
334
    /**
335
     * Find by traversing information.
336
     *
337
     * @param Index      $index
338
     * @param bool|true  $future
339
     * @param bool|false $past
340
     * @param int        $limit
341
     * @param string     $sort
342
     * @param bool       $useIndexTime
343
     *
344
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
345
     */
346
    public function findByTraversing(
347
        Index $index,
348
        $future = true,
349
        $past = false,
350
        $limit = 100,
351
        $sort = QueryInterface::ORDER_ASCENDING,
352
        $useIndexTime = false
353
    ) {
354
        if (!$future && !$past) {
355
            return [];
356
        }
357
        $query = $this->createQuery();
358
359
        $now = DateTimeUtility::getNow();
360
        if ($useIndexTime) {
361
            $now = $index->getStartDate();
362
        }
363
364
        $constraints = [];
365
        $constraints[] = $query->logicalNot($query->equals('uid', $index->getUid()));
366
        $constraints[] = $query->equals('foreignTable', $index->getForeignTable());
367
        $constraints[] = $query->equals('foreignUid', $index->getForeignUid());
368
        if (!$future) {
369
            $constraints[] = $query->lessThanOrEqual('startDate', $now->format('Y-m-d'));
370
        }
371
        if (!$past) {
372
            $constraints[] = $query->greaterThanOrEqual('startDate', $now->format('Y-m-d'));
373
        }
374
375
        $query->setLimit($limit);
376
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
377
        $query->setOrderings($this->getSorting($sort));
378
379
        return $this->matchAndExecute($query, $constraints);
380
    }
381
382
    /**
383
     * Find by traversing information.
384
     *
385
     * @param DomainObjectInterface $event
386
     * @param bool|true             $future
387
     * @param bool|false            $past
388
     * @param int                   $limit
389
     * @param string                $sort
390
     *
391
     * @throws Exception
392
     *
393
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
394
     */
395
    public function findByEventTraversing(
396
        DomainObjectInterface $event,
397
        $future = true,
398
        $past = false,
399
        $limit = 100,
400
        $sort = QueryInterface::ORDER_ASCENDING
401
    ) {
402
        if (!$future && !$past) {
403
            return [];
404
        }
405
        $query = $this->createQuery();
406
407
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
408
409
        $this->setIndexTypes([$uniqueRegisterKey]);
410
411
        $now = DateTimeUtility::getNow()->format('Y-m-d');
412
413
        $constraints = [];
414
415
        $localizedUid = $event->_getProperty('_localizedUid');
416
        $selectUid = $localizedUid ?: $event->getUid();
417
418
        $constraints[] = $query->equals('foreignUid', $selectUid);
419
        $constraints[] = $query->in('uniqueRegisterKey', $this->indexTypes);
420
        if (!$future) {
421
            $constraints[] = $query->lessThanOrEqual('startDate', $now);
422
        }
423
        if (!$past) {
424
            $constraints[] = $query->greaterThanOrEqual('startDate', $now);
425
        }
426
427
        $query->setLimit($limit);
428
        $sort = QueryInterface::ORDER_ASCENDING === $sort ? QueryInterface::ORDER_ASCENDING : QueryInterface::ORDER_DESCENDING;
429
        $query->setOrderings($this->getSorting($sort));
430
431
        return $this->matchAndExecute($query, $constraints);
432
    }
433
434
    /**
435
     * find Year.
436
     *
437
     * @param int $year
438
     *
439
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
440
     */
441
    public function findYear(int $year)
442
    {
443
        $startTime = (new \DateTimeImmutable('midnight'))->setDate($year, 1, 1);
444
        $endTime = $startTime->modify('+1 year -1 second');
445
446
        return $this->findByTimeSlot($startTime, $endTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime defined by (new \DateTimeImmutable(...)->setDate($year, 1, 1) on line 443 can also be of type boolean; however, HDNET\Calendarize\Domain...itory::findByTimeSlot() does only seem to accept object<DateTimeInterface>|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...
447
    }
448
449
    /**
450
     * find quarter.
451
     *
452
     * @param int $year
453
     * @param int $quarter
454
     *
455
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
456
     */
457
    public function findQuarter(int $year, int $quarter)
458
    {
459
        $startMonth = 1 + (3 * ($quarter - 1));
460
        $startTime = (new \DateTimeImmutable('midnight'))->setDate($year, $startMonth, 1);
461
        $endTime = $startTime->modify('+3 months -1 second');
462
463
        return $this->findByTimeSlot($startTime, $endTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime defined by (new \DateTimeImmutable(...($year, $startMonth, 1) on line 460 can also be of type boolean; however, HDNET\Calendarize\Domain...itory::findByTimeSlot() does only seem to accept object<DateTimeInterface>|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...
464
    }
465
466
    /**
467
     * find Month.
468
     *
469
     * @param int $year
470
     * @param int $month
471
     *
472
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
473
     */
474
    public function findMonth(int $year, int $month)
475
    {
476
        $startTime = (new \DateTimeImmutable('midnight'))->setDate($year, $month, 1);
477
        $endTime = $startTime->modify('+1 month -1 second');
478
479
        return $this->findByTimeSlot($startTime, $endTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime defined by (new \DateTimeImmutable(...tDate($year, $month, 1) on line 476 can also be of type boolean; however, HDNET\Calendarize\Domain...itory::findByTimeSlot() does only seem to accept object<DateTimeInterface>|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...
480
    }
481
482
    /**
483
     * find Week.
484
     *
485
     * @param int $year
486
     * @param int $week
487
     * @param int $weekStart See documentation for settings.weekStart
488
     *
489
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
490
     */
491
    public function findWeek(int $year, int $week, int $weekStart = 1)
492
    {
493
        $startTime = \DateTimeImmutable::createFromMutable(DateTimeUtility::convertWeekYear2DayMonthYear($week, $year, $weekStart));
494
        $endTime = $startTime->modify('+1 week -1 second');
495
496
        return $this->findByTimeSlot($startTime, $endTime);
497
    }
498
499
    /**
500
     * find day.
501
     *
502
     * @param int $year
503
     * @param int $month
504
     * @param int $day
505
     *
506
     * @throws Exception
507
     *
508
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
509
     */
510
    public function findDay(int $year, int $month, int $day)
511
    {
512
        $startTime = (new \DateTimeImmutable('midnight'))->setDate($year, $month, $day);
513
        $endTime = $startTime->modify('+1 day -1 second');
514
515
        return $this->findByTimeSlot($startTime, $endTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime defined by (new \DateTimeImmutable(...te($year, $month, $day) on line 512 can also be of type boolean; however, HDNET\Calendarize\Domain...itory::findByTimeSlot() does only seem to accept object<DateTimeInterface>|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...
516
    }
517
518
    /**
519
     * Find different types and locations.
520
     *
521
     * @return array
522
     */
523
    public function findDifferentTypesAndLocations(): array
524
    {
525
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_calendarize_domain_model_index');
526
527
        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();
528
    }
529
530
    /**
531
     * Set the default sorting direction.
532
     *
533
     * @param string $direction
534
     * @param string $field
535
     */
536
    public function setDefaultSortingDirection($direction, $field = '')
537
    {
538
        $this->defaultOrderings = $this->getSorting($direction, $field);
539
    }
540
541
    /**
542
     * Find by time slot.
543
     *
544
     * @param \DateTimeInterface|null $startTime
545
     * @param \DateTimeInterface|null $endTime
546
     *
547
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
548
     */
549
    public function findByTimeSlot(?\DateTimeInterface $startTime, ?\DateTimeInterface $endTime = null)
550
    {
551
        $query = $this->createQuery();
552
        $constraints = $this->getDefaultConstraints($query);
553
        $this->addTimeFrameConstraints($constraints, $query, $startTime, $endTime);
554
555
        $arguments = [
556
            'constraints' => $constraints,
557
            'query' => $query,
558
        ];
559
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
560
        $constraints = $arguments['constraints'] ?: $constraints;
561
562
        return $this->matchAndExecute($query, $constraints);
563
    }
564
565
    /**
566
     * Find all indices by the given Event model.
567
     *
568
     * @param DomainObjectInterface $event
569
     *
570
     * @throws Exception
571
     *
572
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
573
     */
574
    public function findByEvent(DomainObjectInterface $event)
575
    {
576
        $query = $this->createQuery();
577
578
        $uniqueRegisterKey = ExtensionConfigurationUtility::getUniqueRegisterKeyForModel($event);
579
580
        $this->setIndexTypes([$uniqueRegisterKey]);
581
        $constraints = $this->getDefaultConstraints($query);
582
        $constraints[] = $query->equals('foreignUid', $event->getUid());
583
        $query->matching($query->logicalAnd($constraints));
584
585
        return $query->execute();
586
    }
587
588
    /**
589
     * storage page selection.
590
     *
591
     * @return array
592
     */
593
    protected function getStoragePageIds()
594
    {
595
        if (null !== $this->overridePageIds) {
596
            return $this->overridePageIds;
597
        }
598
599
        $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...
600
        $frameworkConfig = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
601
        $storagePages = isset($frameworkConfig['persistence']['storagePid']) ? GeneralUtility::intExplode(
602
            ',',
603
            $frameworkConfig['persistence']['storagePid']
604
        ) : [];
605
        if (!empty($storagePages)) {
606
            return $storagePages;
607
        }
608
        if ($frameworkConfig instanceof BackendConfigurationManager) {
609
            return GeneralUtility::trimExplode(',', $frameworkConfig->getDefaultBackendStoragePid(), true);
610
        }
611
612
        return $storagePages;
613
    }
614
615
    /**
616
     * Get the default constraint for the queries.
617
     *
618
     * @param QueryInterface $query
619
     *
620
     * @return array
621
     */
622
    protected function getDefaultConstraints(QueryInterface $query)
623
    {
624
        $constraints = [];
625
        if (!empty($this->indexTypes)) {
626
            $indexTypes = $this->indexTypes;
627
            $constraints[] = $query->in('uniqueRegisterKey', $indexTypes);
628
        }
629
630
        $storagePages = $this->getStoragePageIds();
631
        if (!empty($storagePages)) {
632
            $constraints[] = $query->in('pid', $storagePages);
633
        }
634
635
        $arguments = [
636
            'indexIds' => [],
637
            'indexTypes' => $this->indexTypes,
638
        ];
639
        $arguments = $this->callSignal(__CLASS__, __FUNCTION__, $arguments);
640
641
        if ($arguments['indexIds']) {
642
            $constraints[] = $query->in('foreignUid', $arguments['indexIds']);
643
        }
644
645
        return $constraints;
646
    }
647
648
    /**
649
     * Add time frame related queries.
650
     *
651
     * @param array                   $constraints
652
     * @param QueryInterface          $query
653
     * @param \DateTimeInterface|null $startTime
654
     * @param \DateTimeInterface|null $endTime
655
     *
656
     * @see IndexUtility::isIndexInRange
657
     */
658
    protected function addTimeFrameConstraints(
659
        array &$constraints,
660
        QueryInterface $query,
661
        ?\DateTimeInterface $startTime = null,
662
        ?\DateTimeInterface $endTime = null
663
    ): void {
664
        /** @var AddTimeFrameConstraintsEvent $event */
665
        $event = $this->eventDispatcher->dispatch(new AddTimeFrameConstraintsEvent(
0 ignored issues
show
Documentation introduced by
new \HDNET\Calendarize\E..., $startTime, $endTime) is of type object<HDNET\Calendarize...eFrameConstraintsEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
666
            $constraints,
667
            $query,
668
            $this->additionalSlotArguments,
669
            $startTime,
670
            $endTime
671
        ));
672
673
        $this->addDateTimeFrameConstraint(
674
            $constraints,
675
            $query,
676
            $event->getStart(),
677
            $event->getEnd(),
678
            (bool)ConfigurationUtility::get('respectTimesInTimeFrameConstraints')
679
        );
680
    }
681
682
    /**
683
     * Adds time frame constraints. The dates are formatted the timezone of the DateTime objects.
684
     * This includes all events, that have an "active" part in the range.
685
     * Do not call this method directly. Call IndexRepository::addTimeFrameConstraints instead.
686
     *
687
     * @param array                   $constraints
688
     * @param QueryInterface          $query
689
     * @param \DateTimeInterface|null $start
690
     * @param \DateTimeInterface|null $end         Inclusive end date
691
     * @param bool                    $respectTime if true, it will also respect the time of the indices
692
     *
693
     * @see IndexRepository::addTimeFrameConstraints
694
     */
695
    protected function addDateTimeFrameConstraint(
696
        array &$constraints,
697
        QueryInterface $query,
698
        ?\DateTimeInterface $start,
699
        ?\DateTimeInterface $end,
700
        bool $respectTime = false
701
    ): void {
702
        if (null === $start && null === $end) {
703
            return;
704
        }
705
        $dateConstraints = [];
706
707
        // No start means open end
708
        if (null !== $start) {
709
            $startDate = $start->format('Y-m-d');
710
711
            if (false === $respectTime) {
712
                // The endDate of an index must be after the range start, otherwise the event was in the past
713
                $dateConstraints[] = $query->greaterThanOrEqual('endDate', $startDate);
714
            } else {
715
                $startTime = DateTimeUtility::getDaySecondsOfDateTime($start);
716
717
                // We split up greaterThan and equal to check more conditions on the same day
718
                // e.g. if it is either allDay, openEnd or the end time is after the start time
719
                // (endDate > $startDate) || (endDate == $startDate && (allDay || openEndTime || endTime >= $startTime))
720
                $dateConstraints[] = $query->logicalOr([
721
                    $query->greaterThan('endDate', $startDate),
722
                    $query->logicalAnd([
723
                        $query->equals('endDate', $startDate),
724
                        $query->logicalOr([
725
                            $query->equals('allDay', true),
726
                            $query->equals('openEndTime', true),
727
                            $query->greaterThanOrEqual('endTime', $startTime),
728
                        ]),
729
                    ]),
730
                ]);
731
            }
732
        }
733
734
        // No end means open start
735
        if (null !== $end) {
736
            $endDate = $end->format('Y-m-d');
737
738
            if (false === $respectTime) {
739
                // The startDate of an index must be before the range end, otherwise the event is in the future
740
                $dateConstraints[] = $query->lessThanOrEqual('startDate', $endDate);
741
            } else {
742
                $endTime = DateTimeUtility::getDaySecondsOfDateTime($end);
743
744
                $dateConstraints[] = $query->logicalOr([
745
                    $query->lessThan('startDate', $endDate),
746
                    $query->logicalAnd([
747
                        $query->equals('startDate', $endDate),
748
                        $query->logicalOr([
749
                            $query->equals('allDay', true),
750
                            $query->lessThanOrEqual('startTime', $endTime),
751
                        ]),
752
                    ]),
753
                ]);
754
            }
755
        }
756
757
        $constraints['dateTimeFrame'] = $query->logicalAnd($dateConstraints);
758
    }
759
760
    /**
761
     * Get the sorting.
762
     *
763
     * @param string $direction
764
     * @param string $field
765
     *
766
     * @return array
767
     */
768
    protected function getSorting($direction, $field = '')
769
    {
770
        if ('withrangelast' === $field) {
771
            return [
772
                'endDate' => $direction,
773
                'startDate' => $direction,
774
                'startTime' => $direction,
775
            ];
776
        }
777
        if ('end' !== $field) {
778
            $field = 'start';
779
        }
780
781
        return [
782
            $field . 'Date' => $direction,
783
            $field . 'Time' => $direction,
784
        ];
785
    }
786
}
787