Passed
Pull Request — master (#2972)
by
unknown
30:52
created

SearchUriBuilder::getSubstitution()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.072

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 10
ccs 8
cts 10
cp 0.8
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 3.072
1
<?php
2
namespace ApacheSolrForTypo3\Solr\Domain\Search\Uri;
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 ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Grouping\GroupItem;
18
use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
21
22
/**
23
 * SearchUriBuilder
24
 *
25
 * Responsibility:
26
 *
27
 * The SearchUriBuilder is responsible to build uris, that are used in the
28
 * searchContext. It can use the previous request with it's persistent
29
 * arguments to build the url for a search sub request.
30
 *
31
 * @author Frans Saris <[email protected]>
32
 * @author Timo Hund <[email protected]>
33
 */
34
class SearchUriBuilder
35
{
36
    /**
37
     * @var UriBuilder
38
     */
39
    protected $uriBuilder;
40
41
    /**
42
     * @var array
43
     */
44
    protected static $preCompiledLinks = [];
45
46
    /**
47
     * @var integer
48
     */
49
    protected static $hitCount;
50
51
    /**
52
     * @var integer
53
     */
54
    protected static $missCount;
55
56
    /**
57
     * @var array
58
     */
59
    protected static $additionalArgumentsCache = [];
60
61
    /**
62
     * @param UriBuilder $uriBuilder
63
     */
64
    public function injectUriBuilder(UriBuilder $uriBuilder)
65
    {
66 35
        $this->uriBuilder = $uriBuilder;
67
    }
68 35
69 35
    /**
70
     * @param SearchRequest $previousSearchRequest
71
     * @param $facetName
72
     * @param $facetValue
73
     * @return string
74
     */
75
    public function getAddFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
76
    {
77 30
        $persistentAndFacetArguments = $previousSearchRequest
78
            ->getCopyForSubRequest()->removeAllGroupItemPages()->addFacetValue($facetName, $facetValue)
79
            ->getAsArray();
80 30
81 30
        $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
82
        $additionalArguments = is_array($additionalArguments) ? $additionalArguments : [];
0 ignored issues
show
introduced by
The condition is_array($additionalArguments) is always true.
Loading history...
83 30
84 30
        $arguments = $persistentAndFacetArguments + $additionalArguments;
85
86 30
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
87
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
88 30
    }
89 30
90
    /**
91
     * Removes all other facet values for this name and only set's the passed value for the facet.
92
     *
93
     * @param SearchRequest $previousSearchRequest
94
     * @param $facetName
95
     * @param $facetValue
96
     * @return string
97
     */
98
    public function getSetFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
99
    {
100 1
        $previousSearchRequest = $previousSearchRequest
101
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName);
102
103 1
        return $this->getAddFacetValueUri($previousSearchRequest, $facetName, $facetValue);
104
    }
105 1
106
    /**
107
     * @param SearchRequest $previousSearchRequest
108
     * @param $facetName
109
     * @param $facetValue
110
     * @return string
111
     */
112
    public function getRemoveFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
113
    {
114 4
        $persistentAndFacetArguments = $previousSearchRequest
115
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeFacetValue($facetName, $facetValue)
116
            ->getAsArray();
117 4
118 4
        $additionalArguments = [];
119
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
120 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
121 4
        }
122 4
        $arguments = $persistentAndFacetArguments + $additionalArguments;
123
124 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
125
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
126 4
    }
127 4
128
    /**
129
     * @param SearchRequest $previousSearchRequest
130
     * @param $facetName
131
     * @return string
132
     */
133
    public function getRemoveFacetUri(SearchRequest $previousSearchRequest, $facetName)
134
    {
135
        $persistentAndFacetArguments = $previousSearchRequest
136
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName)
137
            ->getAsArray();
138
139
        $additionalArguments = [];
140
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
141
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
142
        }
143
144
        $arguments = $persistentAndFacetArguments + $additionalArguments;
145
146
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
147
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
148
    }
149
150
    /**
151
     * @param SearchRequest $previousSearchRequest
152
     * @return string
153
     */
154
    public function getRemoveAllFacetsUri(SearchRequest $previousSearchRequest)
155
    {
156 4
        $persistentAndFacetArguments = $previousSearchRequest
157
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacets()
158
            ->getAsArray();
159 4
160 4
        $additionalArguments = [];
161
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
162 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
163 4
        }
164 4
165
        $arguments = $persistentAndFacetArguments + $additionalArguments;
166
167 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
168
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
169 4
    }
170 4
171
    /**
172
     * @param SearchRequest $previousSearchRequest
173
     * @param $page
174
     * @return string
175
     */
176
    public function getResultPageUri(SearchRequest $previousSearchRequest, $page)
177
    {
178 12
        $persistentAndFacetArguments = $previousSearchRequest
179
            ->getCopyForSubRequest()->setPage($page)
180
            ->getAsArray();
181 12
182 12
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
183
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
184 12
    }
185 12
186
    /**
187
     * @param SearchRequest $previousSearchRequest
188
     * @param GroupItem $groupItem
189
     * @param int $page
190
     * @return string
191
     */
192
    public function getResultGroupItemPageUri(SearchRequest $previousSearchRequest, GroupItem $groupItem, int $page)
193
    {
194
        $persistentAndFacetArguments = $previousSearchRequest
195
            ->getCopyForSubRequest()->setGroupItemPage($groupItem->getGroup()->getGroupName(), $groupItem->getGroupValue(), $page)
196
            ->getAsArray();
197
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
198
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
199
    }
200
    /**
201
     * @param SearchRequest $previousSearchRequest
202
     * @param $queryString
203
     * @return string
204
     */
205
    public function getNewSearchUri(SearchRequest $previousSearchRequest, $queryString)
206
    {
207 34
        /** @var $request SearchRequest */
208
        $contextConfiguration = $previousSearchRequest->getContextTypoScriptConfiguration();
209
        $contextSystemLanguage = $previousSearchRequest->getContextSystemLanguageUid();
210 34
        $contextPageUid = $previousSearchRequest->getContextPageUid();
211 34
212 34
        $request = GeneralUtility::makeInstance(
213
            SearchRequest::class, [],
214 34
            /** @scrutinizer ignore-type */ $contextPageUid,
215 34
            /** @scrutinizer ignore-type */ $contextSystemLanguage,
216 34
            /** @scrutinizer ignore-type */ $contextConfiguration);
217 34
        $arguments = $request->setRawQueryString($queryString)->getAsArray();
218 34
219 34
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
220
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
221 34
    }
222 34
223
    /**
224
     * @param SearchRequest $previousSearchRequest
225
     * @param $sortingName
226
     * @param $sortingDirection
227
     * @return string
228
     */
229
    public function getSetSortingUri(SearchRequest $previousSearchRequest, $sortingName, $sortingDirection)
230
    {
231 32
        $persistentAndFacetArguments = $previousSearchRequest
232
            ->getCopyForSubRequest()->setSorting($sortingName, $sortingDirection)
233
            ->getAsArray();
234 32
235 32
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
236
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
237 32
    }
238 32
239
    /**
240
     * @param SearchRequest $previousSearchRequest
241
     * @return string
242
     */
243
    public function getRemoveSortingUri(SearchRequest $previousSearchRequest)
244
    {
245 32
        $persistentAndFacetArguments = $previousSearchRequest
246
            ->getCopyForSubRequest()->removeSorting()
247
            ->getAsArray();
248 32
249 32
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
250
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
251 32
    }
252 32
253
    /**
254
     * @param SearchRequest $previousSearchRequest
255
     * @return string
256
     */
257
    public function getCurrentSearchUri(SearchRequest $previousSearchRequest)
258
    {
259 28
        $persistentAndFacetArguments = $previousSearchRequest
260
            ->getCopyForSubRequest()
261
            ->getAsArray();
262 28
263 28
264
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
265
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
266 28
    }
267 28
268
    /**
269
     * @param SearchRequest $request
270
     * @return array
271
     */
272
    protected function getAdditionalArgumentsFromRequestConfiguration(SearchRequest $request)
273
    {
274 31
        if ($request->getContextTypoScriptConfiguration() == null) {
275
            return [];
276 31
        }
277
278
        $reQuestId = $request->getId();
279
        if (isset(self::$additionalArgumentsCache[$reQuestId])) {
280 31
            return self::$additionalArgumentsCache[$reQuestId];
281 31
        }
282 31
283
        self::$additionalArgumentsCache[$reQuestId] = $request->getContextTypoScriptConfiguration()
284
            ->getSearchFacetingFacetLinkUrlParametersAsArray();
285 31
286 31
        return self::$additionalArgumentsCache[$reQuestId];
287
    }
288 31
289
    /**
290
     * @param SearchRequest $request
291
     * @return integer|null
292
     */
293
    protected function getTargetPageUidFromRequestConfiguration(SearchRequest $request)
294
    {
295 35
        if ($request->getContextTypoScriptConfiguration() == null) {
296
            return null;
297 35
        }
298
299
        return $request->getContextTypoScriptConfiguration()->getSearchTargetPage();
300
    }
301 35
302
    /**
303
     * Build the link with an in memory cache that reduces the amount of required typolink calls.
304
     *
305
     * @param integer $pageUid
306
     * @param array $arguments
307
     * @return string
308
     */
309
    protected function buildLinkWithInMemoryCache($pageUid, array $arguments)
310
    {
311 35
        $hash = md5($pageUid . json_encode($arguments));
312
        if (isset(self::$preCompiledLinks[$hash])) {
313 35
            self::$hitCount++;
314 35
            $uriCacheTemplate = self::$preCompiledLinks[$hash];
315 35
        } else {
316 35
            self::$missCount++;
317 35
            $uriCacheTemplate = $this->uriBuilder
318 33
                ->reset()
319 33
                ->setTargetPageUid($pageUid)
320
                ->setArguments($arguments)
321 35
                ->build();
322 35
323 35
            self::$preCompiledLinks[$hash] = (string)$uriCacheTemplate;
324
        }
325
326
        return $uriCacheTemplate;
327
    }
328
329 35
    /**
330 35
     * Flushes the internal in memory cache.
331
     *
332 35
     * @return void
333
     */
334
    public function flushInMemoryCache()
335
    {
336 35
        self::$preCompiledLinks = [];
337 35
    }
338
}
339