Completed
Pull Request — master (#157)
by
unknown
25:59
created

BannerRepository::getIncludePageBanners()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 28
rs 8.439
ccs 0
cts 4
cp 0
cc 6
eloc 18
nc 8
nop 2
crap 42
1
<?php
2
namespace DERHANSEN\SfBanners\Domain\Repository;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\Extbase\Persistence\Repository;
19
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
20
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
21
use DERHANSEN\SfBanners\Domain\Model\BannerDemand;
22
23
/**
24
 * Banner repository
25
 *
26
 * @author Torben Hansen <[email protected]>
27
 */
28
class BannerRepository extends Repository
29
{
30
    /**
31
     * Set default sorting
32
     *
33
     * @var array
34
     */
35
    protected $defaultOrderings = array('sorting' => QueryInterface::ORDER_ASCENDING);
36
37
    /**
38
     * Disable the use of storage records, because the StoragePage can be set
39
     * in the plugin
40
     *
41
     * @return void
42
     */
43 8
    public function initializeObject()
44
    {
45 8
        $this->defaultQuerySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
46 8
        $this->defaultQuerySettings->setRespectStoragePage(false);
47 8
    }
48
49
    /**
50
     * Returns banners matching the given demand
51
     *
52
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
53
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
54
     */
55 8
    public function findDemanded(BannerDemand $demand)
56
    {
57
        /* Override the default sorting for random mode. Must be called before
58
            createQuery() */
59 8
        if ($demand->getDisplayMode() == 'allRandom') {
60 1
            $this->defaultOrderings = array();
61 1
        }
62
63 8
        $query = $this->createQuery();
64
65 8
        $constraints = array();
66
67 8
        if ($demand->getStartingPoint() != 0) {
68 8
            $pidList = GeneralUtility::intExplode(',', $demand->getStartingPoint(), true);
69 8
            $constraints[] = $query->in('pid', $pidList);
70 8
        }
71
72 8
        if ($demand->getCategories() != 0) {
73 1
            $categoryConstraints = array();
74 1
            $categories = GeneralUtility::intExplode(',', $demand->getCategories(), true);
75 1
            foreach ($categories as $category) {
76 1
                $categoryConstraints[] = $query->contains('category', $category);
77 1
            }
78 1
            if (count($categoryConstraints) > 0) {
79 1
                $constraints[] = $query->logicalOr($categoryConstraints);
80 1
            }
81 1
        }
82 8
        $query->matching($query->logicalAnd($constraints));
83
84
        /* Get banners without respect to limitations */
85 8
        $unfilteredResult = $query->execute();
86 8
        if ($unfilteredResult->count() > 0) {
87 8
            $finalQuery = $this->getQueryWithLimitation($unfilteredResult, $demand);
88 8
            $result = $this->getResult($finalQuery, $demand);
89 8
        } else {
90 1
            $result = $unfilteredResult;
91
        }
92 8
        return $result;
93
    }
94
95
96
    /**
97
     * Returns the result of the query based on the given displaymode set in demand
98
     *
99
     * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query The query
100
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
101
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
102
     */
103 8
    protected function getResult(QueryInterface $query, BannerDemand $demand)
104
    {
105 8
        $result = array();
106
107
        // Do not respect syslanguage since we search for uids - @see forge #47192
108 8
        $query->getQuerySettings()->setRespectSysLanguage(false);
109
110 8
        switch ($demand->getDisplayMode()) {
111 8
            case 'all':
112 8
                $result = $query->execute();
113 8
                break;
114 1
            case 'allRandom':
115 1
                $result = $this->objectManager->get('DERHANSEN\\SfBanners\\Persistence\\RandomQueryResult', $query);
116
117 1
                break;
118 1
            case 'random':
119 1
                $rows = $query->execute()->count();
120 1
                $rowNumber = mt_rand(0, max(0, ($rows - 1)));
121 1
                $result = $query->setOffset($rowNumber)->setLimit(1)->execute();
122 1
                break;
123
            default:
124
                break;
125 8
        }
126 8
        return $result;
127
    }
128
129
    /**
130
     * Returns a query of banner-uids with respect to max_impressions and max_clicks
131
     *
132
     * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $result The result
133
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
134
     * @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
135
     */
136 8
    protected function getQueryWithLimitation(QueryResultInterface $result, BannerDemand $demand)
137
    {
138 8
        $banners = $this->getExcludePageBanners($result, $demand);
139 8
        $banners = $this->getIncludePageBanners($banners, $demand);
140 8
141
        $bannerUids = array();
142 8
        foreach ($banners as $banner) {
143 3
            /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
144 1
            if ($banner->getImpressionsMax() > 0 || $banner->getClicksMax() > 0) {
145
                if (($banner->getImpressionsMax() > 0 && $banner->getClicksMax() > 0)) {
146 1
                    if ($banner->getImpressions() < $banner->getImpressionsMax() && $banner->getClicks() <
147
                        $banner->getClicksMax()
148
                    ) {
149 3
                        $bannerUids[] = $banner->getUid();
150 1
                    }
151 3
                } elseif ($banner->getImpressionsMax() > 0 && ($banner->getImpressions() <
152 1
                        $banner->getImpressionsMax())
153 3
                ) {
154 2
                    $bannerUids[] = $banner->getUid();
155 2
                } elseif ($banner->getClicksMax() > 0 && ($banner->getClicks() < $banner->getClicksMax())) {
156 3
                    $bannerUids[] = $banner->getUid();
157 7
                }
158
            } else {
159 8
                $bannerUids[] = $banner->getUid();
160
            }
161 8
        }
162 8
163 8
        $query = $this->createQuery();
164 8
        if (count($bannerUids) > 0) {
165
            $query->matching($query->logicalOr($query->in('uid', $bannerUids)));
166 1
        } else {
167
            /* Query should not match any record */
168 8
            $query->matching($query->equals('uid', 0));
169
        }
170
        return $query;
171
    }
172
173
    /**
174
     * Returns all banners in respect to excludepages (recursively if set in banner)
175
     *
176
     * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $result The result
177
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
178 8
     * @return array
179
     */
180
    protected function getExcludePageBanners(QueryResultInterface $result, BannerDemand $demand)
181 8
    {
182
        /** @var \TYPO3\CMS\Core\Database\QueryGenerator $queryGenerator */
183 8
        $queryGenerator = $this->objectManager->get('TYPO3\\CMS\\Core\\Database\\QueryGenerator');
184
185 8
        $banners = array();
186 8
        /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
187 8
        foreach ($result as $banner) {
188 2
            $excludePages = array();
189 1
            foreach ($banner->getExcludepages() as $excludePage) {
190 1
                if ($banner->getRecursive()) {
191 1
                    $pidList = $queryGenerator->getTreeList($excludePage->getUid(), 255, 0, 1);
192 1
                    $excludePages = array_merge($excludePages, explode(',', $pidList));
193
                } else {
194 8
                    $excludePages[] = $excludePage->getUid();
195 8
                }
196 8
            }
197 8
            if (!in_array($demand->getCurrentPageUid(), $excludePages)) {
198 8
                $banners[] = $banner;
199 8
            }
200
        }
201
        return $banners;
202
    }
203
204
    /**
205
     * Returns all banners in respect to includepages
206
     *
207
     * @param Array<\DERHANSEN\SfBanners\Domain\Model\Banner> $result Array of banners
208
     * @param \DERHANSEN\SfBanners\Domain\Model\BannerDemand $demand The demand
209
     * @return array
210
     */
211
    protected function getIncludePageBanners($result, BannerDemand $demand)
212
    {
213
        /** @var \TYPO3\CMS\Core\Database\QueryGenerator $queryGenerator */
214
        $queryGenerator = $this->objectManager->get('TYPO3\\CMS\\Core\\Database\\QueryGenerator');
215
216
        $banners = array();
217
        /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
218
        foreach ($result as $banner) {
219
            $includePages = array();
220
            $bannerIncludePages = $banner->getIncludepages();
221
            if (count($bannerIncludePages) == 0) {
222
                $banners[] = $banner;
223
                continue;
224
            }
225
            foreach ($bannerIncludePages as $includePage) {
226
                if ($banner->getIncludeRecursive()) {
227
                    $pidList = $queryGenerator->getTreeList($includePage->getUid(), 255, 0, 1);
228
                    $includePages = array_merge($includePages, explode(',', $pidList));
229
                } else {
230
                    $includePages[] = $includePage->getUid();
231
                }
232
            }
233
            if (in_array($demand->getCurrentPageUid(), $includePages)) {
234
                $banners[] = $banner;
235
            }
236
        }
237
        return $banners;
238
    }
239
240
    /**
241
     * Updates the impressions counter for each banner
242
     *
243
     * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array $banners Banners
244
     * @return void
245
     */
246
    public function updateImpressions(QueryResultInterface $banners)
247
    {
248
        foreach ($banners as $banner) {
249
            /** @var \DERHANSEN\SfBanners\Domain\Model\Banner $banner */
250
            $banner->increaseImpressions();
251
            $this->update($banner);
252
        }
253
    }
254
}
255
256