Passed
Push — release-11.5.x ( a0b867...3026d3 )
by Markus
30:33
created

SearchUriBuilder   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 494
Duplicated Lines 0 %

Test Coverage

Coverage 90.95%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 42
eloc 186
c 2
b 0
f 0
dl 0
loc 494
ccs 181
cts 199
cp 0.9095
rs 9.0399

20 Methods

Rating   Name   Duplication   Size   Complexity  
A getTargetPageUidFromRequestConfiguration() 0 7 2
A injectEventDispatcher() 0 3 1
A getAdditionalArgumentsFromRequestConfiguration() 0 15 3
A getResultPageUri() 0 8 1
A getResultGroupItemPageUri() 0 7 1
A injectUriBuilder() 0 3 1
B buildLinkWithInMemoryCache() 0 87 7
A sortFilterParametersIfNecessary() 0 11 4
A getSetSortingUri() 0 8 1
A getCurrentSearchUri() 0 8 1
A injectRoutingService() 0 3 1
A getNewSearchUri() 0 23 1
A getSetFacetValueUri() 0 6 1
A flushInMemoryCache() 0 3 1
A getRemoveAllFacetsUri() 0 17 2
A getRemoveFacetValueUri() 0 16 2
A getAddFacetValueUri() 0 14 1
B getSubstitution() 0 31 8
A getRemoveFacetUri() 0 17 2
A getRemoveSortingUri() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like SearchUriBuilder 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 SearchUriBuilder, 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 TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace ApacheSolrForTypo3\Solr\Domain\Search\Uri;
19
20
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Grouping\GroupItem;
21
use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest;
22
use ApacheSolrForTypo3\Solr\Event\Routing\BeforeProcessCachedVariablesEvent;
23
use ApacheSolrForTypo3\Solr\Event\Routing\BeforeReplaceVariableInCachedUrlEvent;
24
use ApacheSolrForTypo3\Solr\Event\Routing\PostProcessUriEvent;
25
use ApacheSolrForTypo3\Solr\Routing\RoutingService;
26
use ApacheSolrForTypo3\Solr\System\Url\UrlHelper;
27
use ApacheSolrForTypo3\Solr\Utility\ParameterSortingUtility;
28
use Psr\EventDispatcher\EventDispatcherInterface;
29
use Symfony\Component\Routing\Exception\InvalidParameterException;
30
use TYPO3\CMS\Core\Http\Uri;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
33
34
/**
35
 * SearchUriBuilder
36
 *
37
 * Responsibility:
38
 *
39
 * The SearchUriBuilder is responsible to build uris, that are used in the
40
 * searchContext. It can use the previous request with its persistent
41
 * arguments to build the url for a search sub request.
42
 *
43
 * @author Frans Saris <[email protected]>
44
 * @author Timo Hund <[email protected]>
45
 */
46
class SearchUriBuilder
47
{
48
    /**
49
     * @var UriBuilder|null
50
     */
51
    protected ?UriBuilder $uriBuilder = null;
52
53
    /**
54
     * @var array
55
     */
56
    protected static array $preCompiledLinks = [];
57
58
    /**
59
     * @var int
60
     */
61
    protected static int $hitCount = 0;
62
63
    /**
64
     * @var int
65
     */
66
    protected static int $missCount = 0;
67
68
    /**
69
     * @var array
70
     */
71
    protected static array $additionalArgumentsCache = [];
72
73
    /**
74
     * @var EventDispatcherInterface
75
     */
76
    protected EventDispatcherInterface $eventDispatcher;
77
78
    /**
79
     * @var ?RoutingService
80
     */
81
    protected ?RoutingService $routingService = null;
82
83
    /**
84
     * @param UriBuilder $uriBuilder
85
     */
86 37
    public function injectUriBuilder(UriBuilder $uriBuilder)
87
    {
88 37
        $this->uriBuilder = $uriBuilder;
89
    }
90
91
    /**
92
     * @param RoutingService $routingService
93
     */
94 37
    public function injectRoutingService(RoutingService $routingService)
95
    {
96 37
        $this->routingService = $routingService;
97
    }
98
99
    /**
100
     * @param EventDispatcherInterface $eventDispatcher
101
     */
102 37
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher)
103
    {
104 37
        $this->eventDispatcher = $eventDispatcher;
105
    }
106
107
    /**
108
     * @param SearchRequest $previousSearchRequest
109
     * @param string $facetName
110
     * @param mixed $facetValue
111
     * @return string
112
     */
113 19
    public function getAddFacetValueUri(SearchRequest $previousSearchRequest, string $facetName, $facetValue): string
114
    {
115 19
        $persistentAndFacetArguments = $previousSearchRequest
116 19
            ->getCopyForSubRequest()->removeAllGroupItemPages()->addFacetValue($facetName, $facetValue)
117 19
            ->getAsArray();
118
119 19
        $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
120
121 19
        $arguments = $persistentAndFacetArguments + $additionalArguments;
122
123 19
        $this->sortFilterParametersIfNecessary($previousSearchRequest, $arguments);
124
125 19
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
126 19
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
127
    }
128
129
    /**
130
     * Removes all other facet values for this name and only set's the passed value for the facet.
131
     *
132
     * @param SearchRequest $previousSearchRequest
133
     * @param $facetName
134
     * @param $facetValue
135
     * @return string
136
     */
137 1
    public function getSetFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue): string
138
    {
139 1
        $previousSearchRequest = $previousSearchRequest
140 1
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName);
141
142 1
        return $this->getAddFacetValueUri($previousSearchRequest, $facetName, $facetValue);
143
    }
144
145
    /**
146
     * @param SearchRequest $previousSearchRequest
147
     * @param $facetName
148
     * @param $facetValue
149
     * @return string
150
     */
151 5
    public function getRemoveFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue): string
152
    {
153 5
        $persistentAndFacetArguments = $previousSearchRequest
154 5
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeFacetValue($facetName, $facetValue)
155 5
            ->getAsArray();
156
157 5
        $additionalArguments = [];
158 5
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
159 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
160
        }
161 5
        $arguments = $persistentAndFacetArguments + $additionalArguments;
162
163 5
        $this->sortFilterParametersIfNecessary($previousSearchRequest, $arguments);
164
165 5
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
166 5
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
167
    }
168
169
    /**
170
     * @param SearchRequest $previousSearchRequest
171
     * @param $facetName
172
     * @return string
173
     */
174 1
    public function getRemoveFacetUri(SearchRequest $previousSearchRequest, $facetName): string
175
    {
176 1
        $persistentAndFacetArguments = $previousSearchRequest
177 1
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName)
178 1
            ->getAsArray();
179
180 1
        $additionalArguments = [];
181 1
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
182
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
183
        }
184
185 1
        $arguments = $persistentAndFacetArguments + $additionalArguments;
186
187 1
        $this->sortFilterParametersIfNecessary($previousSearchRequest, $arguments);
188
189 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
190 1
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
191
    }
192
193
    /**
194
     * @param SearchRequest $previousSearchRequest
195
     * @return string
196
     */
197 4
    public function getRemoveAllFacetsUri(SearchRequest $previousSearchRequest): string
198
    {
199 4
        $persistentAndFacetArguments = $previousSearchRequest
200 4
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacets()
201 4
            ->getAsArray();
202
203 4
        $additionalArguments = [];
204 4
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
205 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
206
        }
207
208 4
        $arguments = $persistentAndFacetArguments + $additionalArguments;
209
210 4
        $this->sortFilterParametersIfNecessary($previousSearchRequest, $arguments);
211
212 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
213 4
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
214
    }
215
216
    /**
217
     * @param SearchRequest $previousSearchRequest
218
     * @param $page
219
     * @return string
220
     */
221 5
    public function getResultPageUri(SearchRequest $previousSearchRequest, $page): string
222
    {
223 5
        $persistentAndFacetArguments = $previousSearchRequest
224 5
            ->getCopyForSubRequest()->setPage($page)
225 5
            ->getAsArray();
226
227 5
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
228 5
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
229
    }
230
231
    /**
232
     * @param SearchRequest $previousSearchRequest
233
     * @param GroupItem $groupItem
234
     * @param int $page
235
     * @return string
236
     */
237 1
    public function getResultGroupItemPageUri(SearchRequest $previousSearchRequest, GroupItem $groupItem, int $page): string
238
    {
239 1
        $persistentAndFacetArguments = $previousSearchRequest
240 1
            ->getCopyForSubRequest()->setGroupItemPage($groupItem->getGroup()->getGroupName(), $groupItem->getGroupValue(), $page)
241 1
            ->getAsArray();
242 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
243 1
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
244
    }
245
    /**
246
     * @param SearchRequest $previousSearchRequest
247
     * @param $queryString
248
     * @return string
249
     */
250 1
    public function getNewSearchUri(SearchRequest $previousSearchRequest, $queryString): string
251
    {
252
        /** @var $request SearchRequest */
253 1
        $contextConfiguration = $previousSearchRequest->getContextTypoScriptConfiguration();
254 1
        $contextSystemLanguage = $previousSearchRequest->getContextSystemLanguageUid();
255 1
        $contextPageUid = $previousSearchRequest->getContextPageUid();
256
257 1
        $request = GeneralUtility::makeInstance(
258 1
            SearchRequest::class,
259 1
            [],
260
            /** @scrutinizer ignore-type */
261 1
            $contextPageUid,
262
            /** @scrutinizer ignore-type */
263 1
            $contextSystemLanguage,
264
            /** @scrutinizer ignore-type */
265 1
            $contextConfiguration
266 1
        );
267 1
        $arguments = $request->setRawQueryString($queryString)->getAsArray();
268
269 1
        $this->sortFilterParametersIfNecessary($previousSearchRequest, $arguments);
270
271 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
272 1
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
273
    }
274
275
    /**
276
     * @param SearchRequest $previousSearchRequest
277
     * @param $sortingName
278
     * @param $sortingDirection
279
     * @return string
280
     */
281 1
    public function getSetSortingUri(SearchRequest $previousSearchRequest, $sortingName, $sortingDirection): string
282
    {
283 1
        $persistentAndFacetArguments = $previousSearchRequest
284 1
            ->getCopyForSubRequest()->setSorting($sortingName, $sortingDirection)
285 1
            ->getAsArray();
286
287 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
288 1
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
289
    }
290
291
    /**
292
     * @param SearchRequest $previousSearchRequest
293
     * @return string
294
     */
295
    public function getRemoveSortingUri(SearchRequest $previousSearchRequest): string
296
    {
297
        $persistentAndFacetArguments = $previousSearchRequest
298
            ->getCopyForSubRequest()->removeSorting()
299
            ->getAsArray();
300
301
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
302
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
303
    }
304
305
    /**
306
     * @param SearchRequest $previousSearchRequest
307
     * @return string
308
     */
309 22
    public function getCurrentSearchUri(SearchRequest $previousSearchRequest): string
310
    {
311 22
        $persistentAndFacetArguments = $previousSearchRequest
312 22
            ->getCopyForSubRequest()
313 22
            ->getAsArray();
314
315 22
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
316 22
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
317
    }
318
319
    /**
320
     * @param SearchRequest $request
321
     * @return array
322
     */
323 20
    protected function getAdditionalArgumentsFromRequestConfiguration(SearchRequest $request): array
324
    {
325 20
        if ($request->getContextTypoScriptConfiguration() == null) {
326
            return [];
327
        }
328
329 20
        $reQuestId = $request->getId();
330 20
        if (isset(self::$additionalArgumentsCache[$reQuestId])) {
331 13
            return self::$additionalArgumentsCache[$reQuestId];
332
        }
333
334 20
        self::$additionalArgumentsCache[$reQuestId] = $request->getContextTypoScriptConfiguration()
335 20
            ->getSearchFacetingFacetLinkUrlParametersAsArray();
336
337 20
        return self::$additionalArgumentsCache[$reQuestId];
338
    }
339
340
    /**
341
     * @param SearchRequest $request
342
     * @return int|null
343
     */
344 35
    protected function getTargetPageUidFromRequestConfiguration(SearchRequest $request): ?int
345
    {
346 35
        if ($request->getContextTypoScriptConfiguration() == null) {
347
            return null;
348
        }
349
350 35
        return $request->getContextTypoScriptConfiguration()->getSearchTargetPage();
351
    }
352
353
    /**
354
     * Build the link with an i memory cache that reduces the amount of required typolink calls.
355
     *
356
     * @param int|null $pageUid
357
     * @param array $arguments
358
     * @return string
359
     */
360 35
    protected function buildLinkWithInMemoryCache(?int $pageUid, array $arguments): string
361
    {
362 35
        $values = [];
363 35
        $structure = $arguments;
364 35
        $this->getSubstitution($structure, $values);
365 35
        $hash = md5($pageUid . json_encode($structure));
366 35
        if (isset(self::$preCompiledLinks[$hash])) {
367 13
            self::$hitCount++;
368 13
            $uriCacheTemplate = self::$preCompiledLinks[$hash];
369
        } else {
370 35
            self::$missCount++;
371 35
            $this->uriBuilder->reset()->setTargetPageUid($pageUid);
0 ignored issues
show
Bug introduced by
The method reset() does not exist on null. ( Ignorable by Annotation )

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

371
            $this->uriBuilder->/** @scrutinizer ignore-call */ 
372
                               reset()->setTargetPageUid($pageUid);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $targetPageUid of TYPO3\CMS\Extbase\Mvc\We...der::setTargetPageUid() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

371
            $this->uriBuilder->reset()->setTargetPageUid(/** @scrutinizer ignore-type */ $pageUid);
Loading history...
372
            try {
373 35
                $uriCacheTemplate = $this->uriBuilder->setArguments($structure)->build();
374
375
                /** @var UrlHelper $urlHelper */
376 34
                $urlHelper = GeneralUtility::makeInstance(UrlHelper::class, $uriCacheTemplate);
377 34
                self::$preCompiledLinks[$hash] = (string)$urlHelper;
378 1
            } catch (InvalidParameterException $exception) {
379
                // the placeholders may result in an exception when route enhancers with requirements are active
380
                // In this case, try to build the URL with original arguments
381 1
                $hash = md5($pageUid . json_encode($arguments));
382 1
                if (isset(self::$preCompiledLinks[$hash])) {
383
                    self::$hitCount++;
384
                    $uriCacheTemplate = self::$preCompiledLinks[$hash];
385
                } else {
386 1
                    $uriCacheTemplate = $this->uriBuilder->setArguments($arguments)->build();
387
                    /** @var UrlHelper $urlHelper */
388 1
                    $urlHelper = GeneralUtility::makeInstance(UrlHelper::class, $uriCacheTemplate);
389 1
                    self::$preCompiledLinks[$hash] = (string)$urlHelper;
390
                }
391
            }
392
        }
393
394 35
        $keys = array_map(function ($value) {
395 33
            return urlencode((string)$value);
396 35
        }, array_keys($values));
397 35
        $values = array_map(function ($value) {
398 33
            return urlencode((string)$value);
399 35
        }, $values);
400
401 35
        $routingConfigurations = $this->routingService
402 35
            ->fetchEnhancerByPageUid($pageUid);
0 ignored issues
show
Bug introduced by
The method fetchEnhancerByPageUid() does not exist on null. ( Ignorable by Annotation )

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

402
        /** @scrutinizer ignore-call */ 
403
        $routingConfigurations = $this->routingService

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...etchEnhancerByPageUid() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

402
            ->fetchEnhancerByPageUid(/** @scrutinizer ignore-type */ $pageUid);
Loading history...
403 35
        $enhancedRouting = count($routingConfigurations) > 0;
404 35
        $this->routingService->reset();
405 35
        if ($enhancedRouting && is_array($routingConfigurations[0] ?? null)) {
406
            $this->routingService->fromRoutingConfiguration($routingConfigurations[0]);
407
        }
408
409
        /* @var Uri $uri */
410 35
        $uri = GeneralUtility::makeInstance(
411 35
            Uri::class,
412 35
            $uriCacheTemplate
413 35
        );
414
415 35
        $urlEvent = new BeforeReplaceVariableInCachedUrlEvent($uri, $enhancedRouting);
416
        /* @var BeforeReplaceVariableInCachedUrlEvent $urlEvent */
417 35
        $urlEvent = $this->eventDispatcher->dispatch($urlEvent);
418 35
        $uriCacheTemplate = (string)$urlEvent->getUri();
419
420 35
        $variableEvent = new BeforeProcessCachedVariablesEvent(
421 35
            $uri,
422 35
            $routingConfigurations,
423 35
            $keys,
424 35
            $values
425 35
        );
426 35
        $this->eventDispatcher->dispatch($variableEvent);
427
428 35
        $values = $variableEvent->getVariableValues();
429
        // Take care that everything is urlencoded!
430 35
        $keys = array_map(function ($value) {
431
            // @TODO: With only PHP 8 support, replace this with str_contains()
432 33
            if (strpos($value, '###') === false) {
433
                return $value;
434
            }
435 33
            return urlencode($value);
436 35
        }, array_keys($values));
437
438 35
        $uri = str_replace($keys, $values, $uriCacheTemplate);
439 35
        $uri = GeneralUtility::makeInstance(
440 35
            Uri::class,
441 35
            $uri
442 35
        );
443 35
        $uriEvent = new PostProcessUriEvent($uri, $routingConfigurations);
444 35
        $this->eventDispatcher->dispatch($uriEvent);
445 35
        $uri = $uriEvent->getUri();
446 35
        return (string)$uri;
447
    }
448
449
    /**
450
     * Flushes the internal in memory cache.
451
     */
452 11
    public function flushInMemoryCache()
453
    {
454 11
        self::$preCompiledLinks = [];
455
    }
456
457
    /**
458
     * This method is used to build two arrays from a nested array. The first one represents the structure.
459
     * In this structure the values are replaced with the pass to the value. At the same time the values get collected
460
     * in the $values array, with the path as key. This can be used to build a comparable hash from the arguments
461
     * in order to reduce the amount of typolink calls
462
     *
463
     *
464
     * Example input
465
     *
466
     * $data = [
467
     *  'foo' => [
468
     *      'bar' => 111
469
     *   ]
470
     * ]
471
     *
472
     * will return:
473
     *
474
     * $structure = [
475
     *  'foo' => [
476
     *      'bar' => '###foo:bar###'
477
     *   ]
478
     * ]
479
     *
480
     * $values = [
481
     *  '###foo:bar###' => 111
482
     * ]
483
     *
484
     * @param array $structure
485
     * @param array $values
486
     * @param array $branch
487
     */
488 35
    protected function getSubstitution(array &$structure, array &$values, array $branch = []): void
489
    {
490
        /*
491
         * Adds information about the filter facet to the placeholder.
492
         *
493
         * This feature allows the handle even placeholder in RouteEnhancer
494
         */
495 35
        $filter = false;
496 35
        if (count($branch) > 0 && $branch[count($branch) - 1] === 'filter') {
497 25
            $filter = true;
498
        }
499 35
        foreach ($structure as $key => &$value) {
500 35
            $branch[] = $key;
501 35
            if (is_array($value)) {
502 35
                $this->getSubstitution($value, $values, $branch);
503
            } else {
504
                // @todo: Refactor to multi-dimensional array.
505
                // https://solr-ddev-site.ddev.site/content-examples/form-elements/search?tx_solr[filter][type:tx_news_domain_model_news]=1&tx_solr[q]=*
506
                // https://solr-ddev-site.ddev.site/content-examples/form-elements/search?tx_solr[filter][0]=type:pages&tx_solr[q]=*
507 33
                if ($filter && $value !== 1) {
508 22
                    [$facetType] = explode(':', $value);
509 22
                    $branch[] = $facetType;
510
                }
511 33
                $path = '###' . implode(':', $branch) . '###';
512 33
                $values[$path] = $value;
513 33
                $structure[$key] = $path;
514 33
                if ($filter) {
515 22
                    array_pop($branch);
516
                }
517
            }
518 35
            array_pop($branch);
519
        }
520
    }
521
522
    /**
523
     * Sorts filter arguments if enabled.
524
     *
525
     *
526
     * @param SearchRequest $searchRequest
527
     * @param array $arguments
528
     */
529 23
    protected function sortFilterParametersIfNecessary(SearchRequest $searchRequest, array &$arguments)
530
    {
531 23
        if (!$searchRequest->isActiveFacetsSorted()) {
532 23
            return;
533
        }
534
535
        $pluginNameSpace = $searchRequest->getContextTypoScriptConfiguration()->getSearchPluginNamespace();
536
        if (!empty($arguments[$pluginNameSpace]['filter']) && is_array($arguments[$pluginNameSpace]['filter'])) {
537
            $arguments[$pluginNameSpace]['filter'] = ParameterSortingUtility::sortByType(
538
                $arguments[$pluginNameSpace]['filter'],
539
                $searchRequest->getActiveFacetsUrlParameterStyle()
540
            );
541
        }
542
    }
543
}
544