EventRepository   F
last analyzed

Complexity

Total Complexity 72

Size/Duplication

Total Lines 380
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 169
dl 0
loc 380
rs 2.64
c 4
b 0
f 0
wmc 72

19 Methods

Rating   Name   Duplication   Size   Complexity  
A setLocationConstraint() 0 4 3
B setDisplayModeConstraint() 0 49 11
A initializeObject() 0 4 1
A findDemanded() 0 37 2
A setStoragePageConstraint() 0 8 2
A setCategoryConstraint() 0 20 6
A setLocationCityConstraint() 0 7 3
A setTopEventConstraint() 0 4 2
A getCategoryConstraint() 0 21 5
A setYearMonthDayRestriction() 0 24 4
A findByUidIncludeHidden() 0 10 1
A setLocationCountryConstraint() 0 7 3
B setStartEndDateConstraint() 0 25 8
A setSearchConstraint() 0 19 6
A setOrderingsFromDemand() 0 10 6
A setSpeakerConstraint() 0 4 3
A injectEventDispatcher() 0 3 1
A setQueryLimitFromDemand() 0 4 2
A setOrganisatorConstraint() 0 7 3

How to fix   Complexity   

Complex Class

Complex classes like EventRepository often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EventRepository, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace DERHANSEN\SfEventMgt\Domain\Repository;
13
14
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
15
use DERHANSEN\SfEventMgt\Domain\Model\Event;
16
use DERHANSEN\SfEventMgt\Event\ModifyEventQueryConstraintsEvent;
17
use DERHANSEN\SfEventMgt\Service\CategoryService;
18
use Psr\EventDispatcher\EventDispatcherInterface;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persis...Qom\ConstraintInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persis...eric\Typo3QuerySettings was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persistence\QueryInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persistence\QueryResultInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use TYPO3\CMS\Extbase\Persistence\Repository;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Persistence\Repository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use UnexpectedValueException;
26
27
class EventRepository extends Repository
28
{
29
    protected $defaultOrderings = [
30
        'startdate' => QueryInterface::ORDER_ASCENDING,
31
    ];
32
33
    protected EventDispatcherInterface $eventDispatcher;
34
35
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher): void
36
    {
37
        $this->eventDispatcher = $eventDispatcher;
38
    }
39
40
    /**
41
     * Disable the use of storage records, because the StoragePage can be set
42
     * in the plugin
43
     */
44
    public function initializeObject(): void
45
    {
46
        $this->defaultQuerySettings = GeneralUtility::makeInstance(Typo3QuerySettings::class);
0 ignored issues
show
Bug Best Practice introduced by
The property defaultQuerySettings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
47
        $this->defaultQuerySettings->setRespectStoragePage(false);
48
    }
49
50
    /**
51
     * Returns the objects of this repository matching the given demand
52
     */
53
    public function findDemanded(EventDemand $eventDemand): QueryResultInterface
54
    {
55
        $constraints = [];
56
        $query = $this->createQuery();
57
        $query->getQuerySettings()->setIgnoreEnableFields($eventDemand->getIgnoreEnableFields());
58
59
        $this->setStoragePageConstraint($query, $eventDemand, $constraints);
60
        $this->setDisplayModeConstraint($query, $eventDemand, $constraints);
61
        $this->setCategoryConstraint($query, $eventDemand, $constraints);
62
        $this->setLocationConstraint($query, $eventDemand, $constraints);
63
        $this->setLocationCityConstraint($query, $eventDemand, $constraints);
64
        $this->setLocationCountryConstraint($query, $eventDemand, $constraints);
65
        $this->setSpeakerConstraint($query, $eventDemand, $constraints);
66
        $this->setOrganisatorConstraint($query, $eventDemand, $constraints);
67
        $this->setStartEndDateConstraint($query, $eventDemand, $constraints);
68
        $this->setSearchConstraint($query, $eventDemand, $constraints);
69
        $this->setTopEventConstraint($query, $eventDemand, $constraints);
70
        $this->setYearMonthDayRestriction($query, $eventDemand, $constraints);
71
72
        $modifyEventQueryConstraintsEvent = new ModifyEventQueryConstraintsEvent(
73
            $constraints,
74
            $query,
75
            $eventDemand,
76
            $this
77
        );
78
        $this->eventDispatcher->dispatch($modifyEventQueryConstraintsEvent);
79
        $constraints = $modifyEventQueryConstraintsEvent->getConstraints();
80
81
        $this->setOrderingsFromDemand($query, $eventDemand);
82
83
        if (count($constraints) > 0) {
84
            $query->matching($query->logicalAnd(...$constraints));
85
        }
86
87
        $this->setQueryLimitFromDemand($query, $eventDemand);
88
89
        return $query->execute();
90
    }
91
92
    /**
93
     * Returns the event with the given UID and also respects the hidden state
94
     */
95
    public function findByUidIncludeHidden(int $uid): ?Event
96
    {
97
        $query = $this->createQuery();
98
        $query->getQuerySettings()->setIgnoreEnableFields(true);
99
        return $query->matching(
100
            $query->logicalAnd(
101
                $query->equals('uid', $uid),
102
                $query->equals('deleted', 0)
103
            )
104
        )->execute()->getFirst();
105
    }
106
107
    /**
108
     * Sets a query limit to the given query for the given demand
109
     */
110
    protected function setQueryLimitFromDemand(QueryInterface $query, EventDemand $eventDemand): void
111
    {
112
        if ($eventDemand->getQueryLimit() > 0) {
113
            $query->setLimit($eventDemand->getQueryLimit());
114
        }
115
    }
116
117
    /**
118
     * Sets the ordering to the given query for the given demand
119
     */
120
    protected function setOrderingsFromDemand(QueryInterface $query, EventDemand $eventDemand): void
121
    {
122
        $orderings = [];
123
        $orderFieldAllowed = GeneralUtility::trimExplode(',', $eventDemand->getOrderFieldAllowed(), true);
124
        if ($eventDemand->getOrderField() !== '' && $eventDemand->getOrderDirection() !== '' &&
125
            !empty($orderFieldAllowed) && in_array($eventDemand->getOrderField(), $orderFieldAllowed, true)) {
126
            $orderings[$eventDemand->getOrderField()] = ((strtolower($eventDemand->getOrderDirection()) === 'desc') ?
127
                QueryInterface::ORDER_DESCENDING :
128
                QueryInterface::ORDER_ASCENDING);
129
            $query->setOrderings($orderings);
130
        }
131
    }
132
133
    /**
134
     * Sets the storagePage constraint to the given constraints array
135
     */
136
    protected function setStoragePageConstraint(
137
        QueryInterface $query,
138
        EventDemand $eventDemand,
139
        array &$constraints
140
    ): void {
141
        if ($eventDemand->getStoragePage() !== '') {
142
            $pidList = GeneralUtility::intExplode(',', $eventDemand->getStoragePage(), true);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Core\Utility\G...alUtility::intExplode() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

142
            $pidList = /** @scrutinizer ignore-deprecated */ GeneralUtility::intExplode(',', $eventDemand->getStoragePage(), true);
Loading history...
143
            $constraints['storagePage'] = $query->in('pid', $pidList);
144
        }
145
    }
146
147
    /**
148
     * Sets the displayMode constraint to the given constraints array
149
     */
150
    protected function setDisplayModeConstraint(
151
        QueryInterface $query,
152
        EventDemand $eventDemand,
153
        array &$constraints
154
    ): void {
155
        switch ($eventDemand->getDisplayMode()) {
156
            case 'future':
157
                $constraints['displayMode'] = $query->greaterThan('startdate', $eventDemand->getCurrentDateTime());
158
                break;
159
            case 'current_future':
160
                $constraints['displayMode'] = $query->logicalOr(
161
                    $query->greaterThan('startdate', $eventDemand->getCurrentDateTime()),
162
                    $query->greaterThanOrEqual('enddate', $eventDemand->getCurrentDateTime()),
163
                );
164
                break;
165
            case 'past':
166
                $constraints['displayMode'] = $query->logicalAnd(
167
                    $query->greaterThan('enddate', 0),
168
                    $query->lessThanOrEqual('enddate', $eventDemand->getCurrentDateTime()),
169
                );
170
                break;
171
            case 'time_restriction':
172
                $includeCurrentConstraint = null;
173
                if (!empty($eventDemand->getTimeRestrictionLow())) {
174
                    $timeRestriction = strtotime($eventDemand->getTimeRestrictionLow());
175
                    $timeRestrictionConstraints['timeRestrictionLow'] = $query->greaterThanOrEqual('startdate', $timeRestriction);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$timeRestrictionConstraints was never initialized. Although not strictly required by PHP, it is generally a good practice to add $timeRestrictionConstraints = array(); before regardless.
Loading history...
176
177
                    if ($eventDemand->getIncludeCurrent()) {
178
                        $includeCurrentConstraint = $query->logicalAnd(
179
                            $query->lessThan('startdate', $timeRestriction),
180
                            $query->greaterThan('enddate', $timeRestriction),
181
                        );
182
                    }
183
                }
184
                if (!empty($eventDemand->getTimeRestrictionHigh())) {
185
                    $timeRestrictionHigh = strtotime($eventDemand->getTimeRestrictionHigh());
186
                    $timeRestrictionConstraints['timeRestrictionHigh'] = $query->lessThanOrEqual('startdate', $timeRestrictionHigh);
187
                }
188
                if (isset($timeRestrictionConstraints)) {
189
                    if ($eventDemand->getIncludeCurrent() && $includeCurrentConstraint) {
190
                        $constraints['displayMode'] = $query->logicalOr(
191
                            $includeCurrentConstraint,
192
                            $query->logicalAnd(...$timeRestrictionConstraints),
193
                        );
194
                    } else {
195
                        $constraints['displayMode'] = $query->logicalAnd(...$timeRestrictionConstraints);
196
                    }
197
                }
198
                break;
199
        }
200
    }
201
202
    /**
203
     * Sets the category constraint to the given constraints array
204
     */
205
    protected function setCategoryConstraint(QueryInterface $query, EventDemand $eventDemand, array &$constraints): void
206
    {
207
        // If no category constraint is set, categories should not be respected in the query
208
        if ($eventDemand->getCategoryConjunction() === '') {
209
            return;
210
        }
211
212
        if ($eventDemand->getCategory() !== '') {
213
            $categoryConstraints = [];
214
            if ($eventDemand->getIncludeSubcategories()) {
215
                $categoryList = CategoryService::getCategoryListWithChilds($eventDemand->getCategory());
216
                $categories = GeneralUtility::intExplode(',', $categoryList, true);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Core\Utility\G...alUtility::intExplode() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

216
                $categories = /** @scrutinizer ignore-deprecated */ GeneralUtility::intExplode(',', $categoryList, true);
Loading history...
217
            } else {
218
                $categories = GeneralUtility::intExplode(',', $eventDemand->getCategory(), true);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Core\Utility\G...alUtility::intExplode() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

218
                $categories = /** @scrutinizer ignore-deprecated */ GeneralUtility::intExplode(',', $eventDemand->getCategory(), true);
Loading history...
219
            }
220
            foreach ($categories as $category) {
221
                $categoryConstraints[] = $query->contains('category', $category);
222
            }
223
            if (count($categoryConstraints) > 0) {
224
                $constraints['category'] = $this->getCategoryConstraint($query, $eventDemand, $categoryConstraints);
225
            }
226
        }
227
    }
228
229
    /**
230
     * Returns the category constraint depending on the category conjunction configured in eventDemand
231
     */
232
    public function getCategoryConstraint(
233
        QueryInterface $query,
234
        EventDemand $eventDemand,
235
        array $categoryConstraints
236
    ): ConstraintInterface {
237
        switch (strtolower($eventDemand->getCategoryConjunction())) {
238
            case 'and':
239
                $constraint = $query->logicalAnd(...$categoryConstraints);
240
                break;
241
            case 'notor':
242
                $constraint = $query->logicalNot($query->logicalOr(...$categoryConstraints));
243
                break;
244
            case 'notand':
245
                $constraint = $query->logicalNot($query->logicalAnd(...$categoryConstraints));
246
                break;
247
            case 'or':
248
            default:
249
                $constraint = $query->logicalOr(...$categoryConstraints);
250
        }
251
252
        return $constraint;
253
    }
254
255
    /**
256
     * Sets the location constraint to the given constraints array
257
     */
258
    protected function setLocationConstraint(QueryInterface $query, EventDemand $eventDemand, array &$constraints): void
259
    {
260
        if ($eventDemand->getLocation() !== null && $eventDemand->getLocation() !== '') {
261
            $constraints['location'] = $query->equals('location', $eventDemand->getLocation());
262
        }
263
    }
264
265
    /**
266
     * Sets the location.city constraint to the given constraints array
267
     */
268
    protected function setLocationCityConstraint(
269
        QueryInterface $query,
270
        EventDemand $eventDemand,
271
        array &$constraints
272
    ): void {
273
        if ($eventDemand->getLocationCity() !== null && $eventDemand->getLocationCity() !== '') {
274
            $constraints['locationCity'] = $query->equals('location.city', $eventDemand->getLocationCity());
275
        }
276
    }
277
278
    /**
279
     * Sets the location.country constraint to the given constraints array
280
     */
281
    protected function setLocationCountryConstraint(
282
        QueryInterface $query,
283
        EventDemand $eventDemand,
284
        array &$constraints
285
    ): void {
286
        if ($eventDemand->getLocationCountry() !== null && $eventDemand->getLocationCountry() !== '') {
287
            $constraints['locationCountry'] = $query->equals('location.country', $eventDemand->getLocationCountry());
288
        }
289
    }
290
291
    /**
292
     * Sets the speaker constraint to the given constraints array
293
     */
294
    protected function setSpeakerConstraint(QueryInterface $query, EventDemand $eventDemand, array &$constraints): void
295
    {
296
        if ($eventDemand->getSpeaker() !== null && $eventDemand->getSpeaker() !== '') {
297
            $constraints['speaker'] = $query->contains('speaker', $eventDemand->getSpeaker());
298
        }
299
    }
300
301
    /**
302
     * Sets the organisator constraint to the given constraints array
303
     */
304
    protected function setOrganisatorConstraint(
305
        QueryInterface $query,
306
        EventDemand $eventDemand,
307
        array &$constraints
308
    ): void {
309
        if ($eventDemand->getOrganisator() !== null && $eventDemand->getOrganisator() !== '') {
310
            $constraints['organisator'] = $query->equals('organisator', $eventDemand->getOrganisator());
311
        }
312
    }
313
314
    /**
315
     * Sets the start- and enddate constraint to the given constraints array
316
     */
317
    protected function setStartEndDateConstraint(
318
        QueryInterface $query,
319
        EventDemand $eventDemand,
320
        array &$constraints
321
    ): void {
322
        if ($eventDemand->getSearchDemand() && $eventDemand->getSearchDemand()->getStartDate() !== null &&
323
            $eventDemand->getSearchDemand()->getEndDate() !== null
324
        ) {
325
            /* StartDate and EndDate  - Search for events between two given dates */
326
            $begin = $eventDemand->getSearchDemand()->getStartDate();
327
            $end = $eventDemand->getSearchDemand()->getEndDate();
328
            $constraints['startEndDate'] = $query->logicalOr(
329
                $query->between('startdate', $begin, $end),
330
                $query->between('enddate', $begin, $end),
331
                $query->logicalAnd(
332
                    $query->greaterThanOrEqual('enddate', $begin),
333
                    $query->lessThanOrEqual('startdate', $begin),
334
                ),
335
            );
336
        } elseif ($eventDemand->getSearchDemand() && $eventDemand->getSearchDemand()->getStartDate() !== null) {
337
            /* StartDate - Search for events beginning at a given date */
338
            $constraints['startDate'] = $query->greaterThanOrEqual('startdate', $eventDemand->getSearchDemand()->getStartDate());
339
        } elseif ($eventDemand->getSearchDemand() && $eventDemand->getSearchDemand()->getEndDate() !== null) {
340
            /* EndDate - Search for events ending on a given date */
341
            $constraints['endDate'] = $query->lessThanOrEqual('enddate', $eventDemand->getSearchDemand()->getEndDate());
342
        }
343
    }
344
345
    /**
346
     * Sets the search constraint to the given constraints array
347
     */
348
    protected function setSearchConstraint(QueryInterface $query, EventDemand $eventDemand, array &$constraints): void
349
    {
350
        if ($eventDemand->getSearchDemand() &&
351
            $eventDemand->getSearchDemand()->getSearch() !== null &&
352
            $eventDemand->getSearchDemand()->getSearch() !== ''
353
        ) {
354
            $searchFields = GeneralUtility::trimExplode(',', $eventDemand->getSearchDemand()->getFields(), true);
355
            $searchConstraints = [];
356
357
            if (count($searchFields) === 0) {
358
                throw new UnexpectedValueException('No search fields defined', 1318497755);
359
            }
360
361
            $searchSubject = $eventDemand->getSearchDemand()->getSearch();
362
            foreach ($searchFields as $field) {
363
                $searchConstraints[] = $query->like($field, '%' . addcslashes($searchSubject, '_%') . '%');
364
            }
365
366
            $constraints['search'] = $query->logicalOr(...$searchConstraints);
367
        }
368
    }
369
370
    /**
371
     * Sets the topEvent constraint to the given constraints array
372
     */
373
    protected function setTopEventConstraint(QueryInterface $query, EventDemand $eventDemand, array &$constraints): void
374
    {
375
        if ($eventDemand->getTopEventRestriction() > 0) {
376
            $constraints['topEvent'] = $query->equals('topEvent', (bool)($eventDemand->getTopEventRestriction() - 1));
377
        }
378
    }
379
380
    /**
381
     * Sets the restriction for year, year/month or year/month/day to the given constraints array
382
     */
383
    protected function setYearMonthDayRestriction(
384
        QueryInterface $query,
385
        EventDemand $eventDemand,
386
        array &$constraints
387
    ): void {
388
        if ($eventDemand->getYear() > 0) {
389
            if ($eventDemand->getMonth() > 0) {
390
                if ($eventDemand->getDay() > 0) {
391
                    $begin = mktime(0, 0, 0, $eventDemand->getMonth(), $eventDemand->getDay(), $eventDemand->getYear());
392
                    $end = mktime(23, 59, 59, $eventDemand->getMonth(), $eventDemand->getDay(), $eventDemand->getYear());
393
                } else {
394
                    $begin = mktime(0, 0, 0, $eventDemand->getMonth(), 1, $eventDemand->getYear());
395
                    $end = mktime(23, 59, 59, ($eventDemand->getMonth() + 1), 0, $eventDemand->getYear());
396
                }
397
            } else {
398
                $begin = mktime(0, 0, 0, 1, 1, $eventDemand->getYear());
399
                $end = mktime(23, 59, 59, 12, 31, $eventDemand->getYear());
400
            }
401
            $constraints['yearMonthDay'] = $query->logicalOr(
402
                $query->between('startdate', $begin, $end),
403
                $query->between('enddate', $begin, $end),
404
                $query->logicalAnd(
405
                    $query->greaterThanOrEqual('enddate', $begin),
406
                    $query->lessThanOrEqual('startdate', $begin),
407
                ),
408
            );
409
        }
410
    }
411
}
412