Passed
Push — upcoming-feature/Introduce_Rou... ( e466c2...d478f4 )
by Rafael
67:01 queued 31:07
created

SearchUriBuilder::getRemoveFacetValueUri()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.1481

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 14
ccs 8
cts 12
cp 0.6667
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2.1481
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 ApacheSolrForTypo3\Solr\Event\Routing\BeforeProcessCachedVariablesEvent;
20
use ApacheSolrForTypo3\Solr\Event\Routing\BeforeReplaceVariableInCachedUrlEvent;
21
use ApacheSolrForTypo3\Solr\Event\Routing\PostProcessUriEvent;
22
use ApacheSolrForTypo3\Solr\Routing\RoutingService;
23
use ApacheSolrForTypo3\Solr\System\Url\UrlHelper;
24
use Psr\EventDispatcher\EventDispatcherInterface;
25
use TYPO3\CMS\Core\Http\Uri;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
28
29
/**
30
 * SearchUriBuilder
31
 *
32
 * Responsibility:
33
 *
34
 * The SearchUriBuilder is responsible to build uris, that are used in the
35
 * searchContext. It can use the previous request with it's persistent
36
 * arguments to build the url for a search sub request.
37
 *
38
 * @author Frans Saris <[email protected]>
39
 * @author Timo Hund <[email protected]>
40
 */
41
class SearchUriBuilder
42
{
43
44
    /**
45
     * @var UriBuilder
46
     */
47
    protected $uriBuilder;
48
49
    /**
50
     * @var array
51
     */
52
    protected static $preCompiledLinks = [];
53
54
    /**
55
     * @var integer
56
     */
57
    protected static $hitCount;
58
59
    /**
60
     * @var integer
61
     */
62
    protected static $missCount;
63
64
    /**
65
     * @var array
66
     */
67
    protected static $additionalArgumentsCache = [];
68
69
    /**
70
     * @var EventDispatcherInterface
71
     */
72
    protected $eventDispatcher;
73
74
    /**
75
     * @var RoutingService
76
     */
77
    protected $routingService;
78
79
    /**
80
     * @param UriBuilder $uriBuilder
81
     */
82 10
    public function injectUriBuilder(UriBuilder $uriBuilder)
83
    {
84 10
        $this->uriBuilder = $uriBuilder;
85 10
    }
86
87
    /**
88
     * @param RoutingService $routingService
89
     */
90 10
    public function injectRoutingService(RoutingService $routingService)
91
    {
92 10
        $this->routingService = $routingService;
93 10
    }
94
95
    /**
96
     * @param EventDispatcherInterface $eventDispatcher
97
     */
98 10
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher)
99
    {
100 10
        $this->eventDispatcher = $eventDispatcher;
101 10
    }
102
103
    /**
104
     * @param SearchRequest $previousSearchRequest
105
     * @param $facetName
106
     * @param $facetValue
107
     * @return string
108
     */
109 4
    public function getAddFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
110
    {
111
        $persistentAndFacetArguments = $previousSearchRequest
112 4
            ->getCopyForSubRequest()->removeAllGroupItemPages()->addFacetValue($facetName, $facetValue)
113 4
            ->getAsArray();
114
115 4
        $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
116 4
        $additionalArguments = is_array($additionalArguments) ? $additionalArguments : [];
0 ignored issues
show
introduced by
The condition is_array($additionalArguments) is always true.
Loading history...
117
118 4
        $arguments = $persistentAndFacetArguments + $additionalArguments;
119
120 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
121 4
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

121
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $arguments);
Loading history...
122
    }
123
124
    /**
125
     * Removes all other facet values for this name and only set's the passed value for the facet.
126
     *
127
     * @param SearchRequest $previousSearchRequest
128
     * @param $facetName
129
     * @param $facetValue
130
     * @return string
131
     */
132
    public function getSetFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
133
    {
134
        $previousSearchRequest = $previousSearchRequest
135
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName);
136
137
        return $this->getAddFacetValueUri($previousSearchRequest, $facetName, $facetValue);
138
    }
139
140
    /**
141
     * @param SearchRequest $previousSearchRequest
142
     * @param $facetName
143
     * @param $facetValue
144
     * @return string
145
     */
146 1
    public function getRemoveFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
147
    {
148
        $persistentAndFacetArguments = $previousSearchRequest
149 1
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeFacetValue($facetName, $facetValue)
150 1
            ->getAsArray();
151
152 1
        $additionalArguments = [];
153 1
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
154
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
155
        }
156 1
        $arguments = $persistentAndFacetArguments + $additionalArguments;
157
158 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
159 1
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

159
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $arguments);
Loading history...
160
    }
161
162
    /**
163
     * @param SearchRequest $previousSearchRequest
164
     * @param $facetName
165
     * @return string
166
     */
167 1
    public function getRemoveFacetUri(SearchRequest $previousSearchRequest, $facetName)
168
    {
169
        $persistentAndFacetArguments = $previousSearchRequest
170 1
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName)
171 1
            ->getAsArray();
172
173 1
        $additionalArguments = [];
174 1
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
175
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
176
        }
177
178 1
        $arguments = $persistentAndFacetArguments + $additionalArguments;
179
180 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
181 1
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

181
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $arguments);
Loading history...
182
    }
183
184
    /**
185
     * @param SearchRequest $previousSearchRequest
186
     * @return string
187
     */
188
    public function getRemoveAllFacetsUri(SearchRequest $previousSearchRequest)
189
    {
190
        $persistentAndFacetArguments = $previousSearchRequest
191
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacets()
192
            ->getAsArray();
193
194
        $additionalArguments = [];
195
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
196
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
197
        }
198
199
        $arguments = $persistentAndFacetArguments + $additionalArguments;
200
201
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
202
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

202
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $arguments);
Loading history...
203
    }
204
205
    /**
206
     * @param SearchRequest $previousSearchRequest
207
     * @param $page
208
     * @return string
209
     */
210 2
    public function getResultPageUri(SearchRequest $previousSearchRequest, $page)
211
    {
212
        $persistentAndFacetArguments = $previousSearchRequest
213 2
            ->getCopyForSubRequest()->setPage($page)
214 2
            ->getAsArray();
215
216 2
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
217 2
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

217
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $persistentAndFacetArguments);
Loading history...
218
    }
219
220
    /**
221
     * @param SearchRequest $previousSearchRequest
222
     * @param GroupItem $groupItem
223
     * @param int $page
224
     * @return string
225
     */
226 1
    public function getResultGroupItemPageUri(SearchRequest $previousSearchRequest, GroupItem $groupItem, int $page)
227
    {
228
        $persistentAndFacetArguments = $previousSearchRequest
229 1
            ->getCopyForSubRequest()->setGroupItemPage($groupItem->getGroup()->getGroupName(), $groupItem->getGroupValue(), $page)
230 1
            ->getAsArray();
231 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
232 1
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

232
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $persistentAndFacetArguments);
Loading history...
233
    }
234
    /**
235
     * @param SearchRequest $previousSearchRequest
236
     * @param $queryString
237
     * @return string
238
     */
239
    public function getNewSearchUri(SearchRequest $previousSearchRequest, $queryString)
240
    {
241
        /** @var $request SearchRequest */
242
        $contextConfiguration = $previousSearchRequest->getContextTypoScriptConfiguration();
243
        $contextSystemLanguage = $previousSearchRequest->getContextSystemLanguageUid();
244
        $contextPageUid = $previousSearchRequest->getContextPageUid();
245
246
        $request = GeneralUtility::makeInstance(
247
            SearchRequest::class, [],
248
            /** @scrutinizer ignore-type */ $contextPageUid,
249
            /** @scrutinizer ignore-type */ $contextSystemLanguage,
250
            /** @scrutinizer ignore-type */ $contextConfiguration);
251
        $arguments = $request->setRawQueryString($queryString)->getAsArray();
252
253
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
254
        return $this->buildLinkWithInMemoryCache($pageUid, $arguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

254
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $arguments);
Loading history...
255
    }
256
257
    /**
258
     * @param SearchRequest $previousSearchRequest
259
     * @param $sortingName
260
     * @param $sortingDirection
261
     * @return string
262
     */
263 1
    public function getSetSortingUri(SearchRequest $previousSearchRequest, $sortingName, $sortingDirection)
264
    {
265
        $persistentAndFacetArguments = $previousSearchRequest
266 1
            ->getCopyForSubRequest()->setSorting($sortingName, $sortingDirection)
267 1
            ->getAsArray();
268
269 1
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
270 1
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

270
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $persistentAndFacetArguments);
Loading history...
271
    }
272
273
    /**
274
     * @param SearchRequest $previousSearchRequest
275
     * @return string
276
     */
277
    public function getRemoveSortingUri(SearchRequest $previousSearchRequest)
278
    {
279
        $persistentAndFacetArguments = $previousSearchRequest
280
            ->getCopyForSubRequest()->removeSorting()
281
            ->getAsArray();
282
283
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
284
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

284
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $persistentAndFacetArguments);
Loading history...
285
    }
286
287
    /**
288
     * @param SearchRequest $previousSearchRequest
289
     * @return string
290
     */
291
    public function getCurrentSearchUri(SearchRequest $previousSearchRequest)
292
    {
293
        $persistentAndFacetArguments = $previousSearchRequest
294
            ->getCopyForSubRequest()
295
            ->getAsArray();
296
297
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
298
        return $this->buildLinkWithInMemoryCache($pageUid, $persistentAndFacetArguments);
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $pageUid of ApacheSolrForTypo3\Solr\...LinkWithInMemoryCache() 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

298
        return $this->buildLinkWithInMemoryCache(/** @scrutinizer ignore-type */ $pageUid, $persistentAndFacetArguments);
Loading history...
299
    }
300
301
    /**
302
     * @param SearchRequest $request
303
     * @return array
304
     */
305 4
    protected function getAdditionalArgumentsFromRequestConfiguration(SearchRequest $request)
306
    {
307 4
        if ($request->getContextTypoScriptConfiguration() == null) {
308
            return [];
309
        }
310
311 4
        $reQuestId = $request->getId();
312 4
        if (isset(self::$additionalArgumentsCache[$reQuestId])) {
313 1
            return self::$additionalArgumentsCache[$reQuestId];
314
        }
315
316 4
        self::$additionalArgumentsCache[$reQuestId] = $request->getContextTypoScriptConfiguration()
317 4
            ->getSearchFacetingFacetLinkUrlParametersAsArray();
318
319 4
        return self::$additionalArgumentsCache[$reQuestId];
320
    }
321
322
    /**
323
     * @param SearchRequest $request
324
     * @return integer|null
325
     */
326 10
    protected function getTargetPageUidFromRequestConfiguration(SearchRequest $request)
327
    {
328 10
        if ($request->getContextTypoScriptConfiguration() == null) {
329
            return null;
330
        }
331
332 10
        return $request->getContextTypoScriptConfiguration()->getSearchTargetPage();
333
    }
334
335
    /**
336
     * Build the link with an i memory cache that reduces the amount of required typolink calls.
337
     *
338
     * @param integer $pageUid
339
     * @param array $arguments
340
     * @return string
341
     */
342 10
    protected function buildLinkWithInMemoryCache(int $pageUid, array $arguments): string
343
    {
344 10
        $values = [];
345 10
        $structure = $arguments;
346 10
        $this->getSubstitution($structure, $values);
347 10
        $hash = md5($pageUid . json_encode($structure));
348 10
        if (isset(self::$preCompiledLinks[$hash])) {
349 1
            self::$hitCount++;
350 1
            $uriCacheTemplate = self::$preCompiledLinks[$hash];
351
        } else {
352 10
            self::$missCount++;
353 10
            $this->uriBuilder->reset()->setTargetPageUid($pageUid);
354 10
            $uriCacheTemplate = $this->uriBuilder->setArguments($structure)->setUseCacheHash(false)->build();
0 ignored issues
show
Unused Code introduced by
The call to TYPO3\CMS\Extbase\Mvc\We...lder::setUseCacheHash() has too many arguments starting with false. ( Ignorable by Annotation )

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

354
            $uriCacheTemplate = $this->uriBuilder->setArguments($structure)->/** @scrutinizer ignore-call */ setUseCacheHash(false)->build();

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
355
356
            // even if we call build with disabled cHash in TYPO3 9 a cHash will be generated when site management is active
357
            // to prevent wrong cHashes we remove the cHash here from the cached uri template.
358
            // @todo: This can be removed when https://forge.typo3.org/issues/87120 is resolved and we can ship a proper configuration
359
            /* @var UrlHelper $urlHelper */
360 10
            $urlHelper = GeneralUtility::makeInstance(UrlHelper::class, $uriCacheTemplate);
361 10
            $urlHelper->removeQueryParameter('cHash');
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...:removeQueryParameter() has been deprecated: Will be removed with v12. Use withoutQueryParameter instead. ( Ignorable by Annotation )

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

361
            /** @scrutinizer ignore-deprecated */ $urlHelper->removeQueryParameter('cHash');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
362
363 10
            self::$preCompiledLinks[$hash] = (string)$urlHelper;
364
        }
365
366
        $keys = array_map(function($value) {
367 8
            return urlencode($value);
368 10
        }, array_keys($values));
369
        $values = array_map(function($value) {
370 8
            return urlencode($value);
371 10
        }, $values);
372
373 10
        $routingConfigurations = $this->routingService
374 10
            ->fetchEnhancerByPageUid($pageUid);
375 10
        $enhancedRouting = count($routingConfigurations) > 0;
376 10
        $this->routingService->reset();
377 10
        if ($enhancedRouting && is_array($routingConfigurations[0])) {
378
            $this->routingService->fromRoutingConfiguration($routingConfigurations[0]);
379
        }
380
381
        /* @var Uri $uri */
382 10
        $uri = GeneralUtility::makeInstance(
383 10
            Uri::class,
384 10
            $uriCacheTemplate
385
        );
386
387 10
        $urlEvent = new BeforeReplaceVariableInCachedUrlEvent($uri, $enhancedRouting);
388
        /* @var BeforeReplaceVariableInCachedUrlEvent $urlEvent */
389 10
        $urlEvent = $this->eventDispatcher->dispatch($urlEvent);
390 10
        $uriCacheTemplate = (string)$urlEvent->getUri();
391
392 10
        $variableEvent = new BeforeProcessCachedVariablesEvent(
393 10
            $uri,
394 10
            $routingConfigurations,
395 10
            $keys,
396 10
            $values
397
        );
398 10
        $this->eventDispatcher->dispatch($variableEvent);
399
400 10
        $values = $variableEvent->getVariableValues();
401
        // Take care that everything is urlencoded!
402
        $keys = array_map(function($value) {
403
            // @TODO: With only PHP 8 support, replace this with str_contains()
404 8
            if (strpos($value, '###') === false) {
405
                return $value;
406
            }
407 8
            return urlencode($value);
408 10
        }, array_keys($values));
409
410 10
        $uri = str_replace($keys, $values, $uriCacheTemplate);
411 10
        $uri = GeneralUtility::makeInstance(
412 10
            Uri::class,
413 10
            $uri
414
        );
415 10
        $uriEvent = new PostProcessUriEvent($uri, $routingConfigurations);
416 10
        $this->eventDispatcher->dispatch($uriEvent);
417 10
        $uri = $uriEvent->getUri();
418 10
        return (string)$uri;
419
    }
420
421
    /**
422
     * Flushes the internal in memory cache.
423
     *
424
     * @return void
425
     */
426 10
    public function flushInMemoryCache()
427
    {
428 10
        self::$preCompiledLinks = [];
429 10
    }
430
431
    /**
432
     * This method is used to build two arrays from a nested array. The first one represents the structure.
433
     * In this structure the values are replaced with the pass to the value. At the same time the values get collected
434
     * in the $values array, with the path as key. This can be used to build a comparable hash from the arguments
435
     * in order to reduce the amount of typolink calls
436
     *
437
     *
438
     * Example input
439
     *
440
     * $data = [
441
     *  'foo' => [
442
     *      'bar' => 111
443
     *   ]
444
     * ]
445
     *
446
     * will return:
447
     *
448
     * $structure = [
449
     *  'foo' => [
450
     *      'bar' => '###foo:bar###'
451
     *   ]
452
     * ]
453
     *
454
     * $values = [
455
     *  '###foo:bar###' => 111
456
     * ]
457
     *
458
     * @param $structure
459
     * @param $values
460
     * @param array $branch
461
     */
462 10
    protected function getSubstitution(array &$structure, array  &$values, array $branch = []): void
463
    {
464
        /*
465
         * Adds information about the filter facet to the placeholder.
466
         *
467
         * This feature allows to handle even placeholder in RouteEnhancer
468
         */
469 10
        $filter = false;
470 10
        if (count($branch) > 0 && $branch[count($branch) - 1] === 'filter') {
471 8
            $filter = true;
472
        }
473 10
        foreach ($structure as $key => &$value) {
474 10
            $branch[] = $key;
475 10
            if (is_array($value)) {
476 10
                $this->getSubstitution($value, $values, $branch);
477
            } else {
478 8
                if ($filter) {
479 6
                    [$facetType, $facetValue] = explode(':', $value);
480 6
                    $branch[] = $facetType;
481
                }
482 8
                $path = '###' . implode(':', $branch) . '###';
483 8
                $values[$path] = $value;
484 8
                $structure[$key] = $path;
485 8
                if ($filter) {
486 6
                    array_pop($branch);
487
                }
488
            }
489 10
            array_pop($branch);
490
        }
491 10
    }
492
}
493