BannerRepository::findDemanded()   B
last analyzed

Complexity

Conditions 7
Paths 24

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 8.3466
c 0
b 0
f 0
ccs 19
cts 19
cp 1
cc 7
nc 24
nop 1
crap 7
1
<?php
2
namespace DERHANSEN\SfBanners\Domain\Repository;
3
4
/*
5
 * This file is part of the Extension "sf_banners" for TYPO3 CMS.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.txt file that was distributed with this source code.
9
 */
10
11
use DERHANSEN\SfBanners\Domain\Model\BannerDemand;
12
use TYPO3\CMS\Core\Database\QueryGenerator;
13
use TYPO3\CMS\Core\Utility\GeneralUtility;
14
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
15
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
16
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
17
use TYPO3\CMS\Extbase\Persistence\Repository;
18
19
/**
20
 * Banner repository
21
 *
22
 * @author Torben Hansen <[email protected]>
23
 */
24
class BannerRepository extends Repository
25
{
26
    /**
27
     * Set default sorting
28
     *
29
     * @var array
30
     */
31
    protected $defaultOrderings = ['sorting' => QueryInterface::ORDER_ASCENDING];
32
33
    /**
34
     * Disable the use of storage records, because the StoragePage can be set
35
     * in the plugin
36
     *
37
     * @return void
38
     */
39
    public function initializeObject()
40
    {
41
        $this->defaultQuerySettings = $this->objectManager->get(Typo3QuerySettings::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->objectManager->ge...o3QuerySettings::class) of type object<TYPO3\CMS\Extbase\Object\object> is incompatible with the declared type object<TYPO3\CMS\Extbase...QuerySettingsInterface> of property $defaultQuerySettings.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
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...
42
        $this->defaultQuerySettings->setRespectStoragePage(false);
43
    }
44
45
    /**
46 8
     * Returns banners matching the given demand
47
     *
48 8
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
49 8
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
50 8
     */
51
    public function findDemanded(BannerDemand $demand)
52
    {
53
        /* Override the default sorting for random mode. Must be called before
54
            createQuery() */
55
        if ($demand->getDisplayMode() == 'allRandom') {
56
            $this->defaultOrderings = [];
57
        }
58 8
59
        $query = $this->createQuery();
60
61
        $constraints = [];
62 8
63 1
        if ($demand->getStartingPoint() != 0) {
64
            $pidList = GeneralUtility::intExplode(',', $demand->getStartingPoint(), true);
65
            $constraints[] = $query->in('pid', $pidList);
66 8
        }
67
68 8
        if ($demand->getCategories() != 0) {
69
            $categoryConstraints = [];
70 8
            $categories = GeneralUtility::intExplode(',', $demand->getCategories(), true);
71 8
            foreach ($categories as $category) {
72 8
                $categoryConstraints[] = $query->contains('category', $category);
73
            }
74
            if (count($categoryConstraints) > 0) {
75 8
                $constraints[] = $query->logicalOr($categoryConstraints);
76 1
            }
77 1
        }
78 1
        $query->matching($query->logicalAnd($constraints));
79 1
80
        /* Get banners without respect to limitations */
81 1
        $unfilteredResult = $query->execute();
82 1
        if (count($unfilteredResult) > 0) {
83
            $filteredResult = $this->applyBannerLimitations($unfilteredResult, $demand);
0 ignored issues
show
Bug introduced by
It seems like $unfilteredResult defined by $query->execute() on line 81 can also be of type array; however, DERHANSEN\SfBanners\Doma...pplyBannerLimitations() does only seem to accept object<TYPO3\CMS\Extbase...e\QueryResultInterface>, 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...
84
            $bannersByDisplayMode = $this->getBannersByDisplayMode($filteredResult, $demand);
85 8
            $result = $this->getBannersByMaxResults($bannersByDisplayMode, $demand);
86
        } else {
87
            $result = $unfilteredResult;
88 8
        }
89 8
        return $result;
90 8
    }
91 8
92
    /**
93 1
     * Returns the banners by the displayMode set in the demand
94
     *
95 8
     * @param array $filteredResult
96
     * @param BannerDemand $demand
97
     * @return array|mixed
98
     */
99
    protected function getBannersByDisplayMode(array $filteredResult, BannerDemand $demand)
100
    {
101
        $result = [];
102
103
        switch ($demand->getDisplayMode()) {
104
            case 'all':
105 8
                $result = $filteredResult;
106
                break;
107 8
            case 'allRandom':
108
                shuffle($filteredResult);
109
                $result = $filteredResult;
110 8
                break;
111
            case 'random':
112 8
                shuffle($filteredResult);
113 8
                $result = isset($filteredResult[0]) ? [$filteredResult[0]] : [];
114 8
                break;
115 8
            default:
116 1
                break;
117 1
        }
118
        return $result;
119 1
    }
120 1
121 1
    /**
122 1
     * Returns the banners by maxResults set in the demand
123 1
     *
124 1
     * @param array $banners
125
     * @param BannerDemand $bannerDemand
126
     * @return array
127
     */
128 8
    protected function getBannersByMaxResults(array $banners, BannerDemand $bannerDemand)
129
    {
130
        $result = $banners;
131
        if ($bannerDemand->getMaxResults() > 0 && count($banners) > $bannerDemand->getMaxResults()) {
132
            $result = array_slice($banners, 0, $bannerDemand->getMaxResults());
133
        }
134
        return $result;
135
    }
136
137
    /**
138 8
     * Applies banner limitations to the given queryResult and returns remaining banners as array
139
     *
140 8
     * @param QueryResultInterface $result
141 8
     * @param BannerDemand $demand
142 8
     * @return array
143
     */
144 8
    protected function applyBannerLimitations(QueryResultInterface $result, BannerDemand $demand)
145 3
    {
146 1
        $banners = $this->getExcludePageBanners($result, $demand);
147 1
        $resultingBanners = [];
148
        foreach ($banners as $banner) {
149 1
            /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
150
            if ($banner->getImpressionsMax() > 0 || $banner->getClicksMax() > 0) {
151 3
                if (($banner->getImpressionsMax() > 0 && $banner->getClicksMax() > 0)) {
152 3
                    if ($banner->getImpressions() < $banner->getImpressionsMax() && $banner->getClicks() <
153
                        $banner->getClicksMax()
154 1
                    ) {
155 3
                        $resultingBanners[] = $banner;
156 3
                    }
157
                } elseif ($banner->getImpressionsMax() > 0 && ($banner->getImpressions() <
158
                        $banner->getImpressionsMax())
159 8
                ) {
160
                    $resultingBanners[] = $banner;
161
                } elseif ($banner->getClicksMax() > 0 && ($banner->getClicks() < $banner->getClicksMax())) {
162
                    $resultingBanners[] = $banner;
163 8
                }
164 8
            } else {
165 8
                $resultingBanners[] = $banner;
166
            }
167
        }
168 1
        return $resultingBanners;
169
    }
170 8
171
    /**
172
     * Returns all banners in respect to excludepages (recursively if set in banner)
173
     *
174
     * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $result The result
175
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
176
     * @return array
177
     */
178
    protected function getExcludePageBanners(QueryResultInterface $result, BannerDemand $demand)
179
    {
180 8
        /** @var \TYPO3\CMS\Core\Database\QueryGenerator $queryGenerator */
181
        $queryGenerator = $this->objectManager->get(QueryGenerator::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...
182
183 8
        $banners = [];
184
        /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
185 8
        foreach ($result as $banner) {
186
            $excludePages = [];
187 8
            foreach ($banner->getExcludepages() as $excludePage) {
188 8
                if ($banner->getRecursive()) {
189 8
                    $pidList = $queryGenerator->getTreeList($excludePage->getUid(), 255, 0, 1);
190 2
                    $excludePages = array_merge($excludePages, explode(',', $pidList));
191 1
                } else {
192 1
                    $excludePages[] = $excludePage->getUid();
193
                }
194 2
            }
195
            if (!in_array($demand->getCurrentPageUid(), $excludePages)) {
196
                $banners[] = $banner;
197 8
            }
198 8
        }
199
        return $banners;
200
    }
201 8
202
    /**
203
     * Updates the impressions counter for each banner
204
     *
205
     * @param array $banners Banners
206
     * @return void
207
     */
208
    public function updateImpressions(array $banners)
209
    {
210
        foreach ($banners as $banner) {
211
            /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
212
            $banner->increaseImpressions();
213
            $this->update($banner);
214
        }
215
    }
216
}
217