Passed
Pull Request — master (#2755)
by Rafael
70:45 queued 67:01
created

SearchUriBuilder::buildLinkWithInMemoryCache()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 77
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 5.1349

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 77
ccs 47
cts 57
cp 0.8246
rs 8.7361
c 0
b 0
f 0
cc 5
nc 4
nop 2
crap 5.1349

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 35
    public function injectUriBuilder(UriBuilder $uriBuilder)
83
    {
84 35
        $this->uriBuilder = $uriBuilder;
85 35
    }
86
87
    /**
88
     * @param RoutingService $routingService
89
     */
90 35
    public function injectRoutingService(RoutingService $routingService)
91
    {
92 35
        $this->routingService = $routingService;
93 35
    }
94
95
    /**
96
     * @param EventDispatcherInterface $eventDispatcher
97
     */
98 35
    public function injectEventDispatcher(EventDispatcherInterface $eventDispatcher)
99
    {
100 35
        $this->eventDispatcher = $eventDispatcher;
101 35
    }
102
103
    /**
104
     * @param SearchRequest $previousSearchRequest
105
     * @param $facetName
106
     * @param $facetValue
107
     * @return string
108
     */
109 30
    public function getAddFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
110
    {
111
        $persistentAndFacetArguments = $previousSearchRequest
112 30
            ->getCopyForSubRequest()->removeAllGroupItemPages()->addFacetValue($facetName, $facetValue)
113 30
            ->getAsArray();
114
115 30
        $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
116 30
        $additionalArguments = is_array($additionalArguments) ? $additionalArguments : [];
0 ignored issues
show
introduced by
The condition is_array($additionalArguments) is always true.
Loading history...
117
118 30
        $arguments = $persistentAndFacetArguments + $additionalArguments;
119
120 30
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
121 30
        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 1
    public function getSetFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
133
    {
134
        $previousSearchRequest = $previousSearchRequest
135 1
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName);
136
137 1
        return $this->getAddFacetValueUri($previousSearchRequest, $facetName, $facetValue);
138
    }
139
140
    /**
141
     * @param SearchRequest $previousSearchRequest
142
     * @param $facetName
143
     * @param $facetValue
144
     * @return string
145
     */
146 4
    public function getRemoveFacetValueUri(SearchRequest $previousSearchRequest, $facetName, $facetValue)
147
    {
148
        $persistentAndFacetArguments = $previousSearchRequest
149 4
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeFacetValue($facetName, $facetValue)
150 4
            ->getAsArray();
151
152 4
        $additionalArguments = [];
153 4
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
154 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
155
        }
156 4
        $arguments = $persistentAndFacetArguments + $additionalArguments;
157
158 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
159 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

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
    public function getRemoveFacetUri(SearchRequest $previousSearchRequest, $facetName)
168
    {
169
        $persistentAndFacetArguments = $previousSearchRequest
170
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacetValuesByName($facetName)
171
            ->getAsArray();
172
173
        $additionalArguments = [];
174
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
175
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
176
        }
177
178
        $arguments = $persistentAndFacetArguments + $additionalArguments;
179
180
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
181
        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 4
    public function getRemoveAllFacetsUri(SearchRequest $previousSearchRequest)
189
    {
190
        $persistentAndFacetArguments = $previousSearchRequest
191 4
            ->getCopyForSubRequest()->removeAllGroupItemPages()->removeAllFacets()
192 4
            ->getAsArray();
193
194 4
        $additionalArguments = [];
195 4
        if ($previousSearchRequest->getContextTypoScriptConfiguration()->getSearchFacetingFacetLinkUrlParametersUseForFacetResetLinkUrl()) {
196 4
            $additionalArguments = $this->getAdditionalArgumentsFromRequestConfiguration($previousSearchRequest);
197
        }
198
199 4
        $arguments = $persistentAndFacetArguments + $additionalArguments;
200
201 4
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
202 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

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 12
    public function getResultPageUri(SearchRequest $previousSearchRequest, $page)
211
    {
212
        $persistentAndFacetArguments = $previousSearchRequest
213 12
            ->getCopyForSubRequest()->setPage($page)
214 12
            ->getAsArray();
215
216 12
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
217 12
        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
    public function getResultGroupItemPageUri(SearchRequest $previousSearchRequest, GroupItem $groupItem, int $page)
227
    {
228
        $persistentAndFacetArguments = $previousSearchRequest
229
            ->getCopyForSubRequest()->setGroupItemPage($groupItem->getGroup()->getGroupName(), $groupItem->getGroupValue(), $page)
230
            ->getAsArray();
231
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
232
        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 34
    public function getNewSearchUri(SearchRequest $previousSearchRequest, $queryString)
240
    {
241
        /** @var $request SearchRequest */
242 34
        $contextConfiguration = $previousSearchRequest->getContextTypoScriptConfiguration();
243 34
        $contextSystemLanguage = $previousSearchRequest->getContextSystemLanguageUid();
244 34
        $contextPageUid = $previousSearchRequest->getContextPageUid();
245
246 34
        $request = GeneralUtility::makeInstance(
247 34
            SearchRequest::class, [],
248 34
            /** @scrutinizer ignore-type */ $contextPageUid,
249 34
            /** @scrutinizer ignore-type */ $contextSystemLanguage,
250 34
            /** @scrutinizer ignore-type */ $contextConfiguration);
251 34
        $arguments = $request->setRawQueryString($queryString)->getAsArray();
252
253 34
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
254 34
        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 32
    public function getSetSortingUri(SearchRequest $previousSearchRequest, $sortingName, $sortingDirection)
264
    {
265
        $persistentAndFacetArguments = $previousSearchRequest
266 32
            ->getCopyForSubRequest()->setSorting($sortingName, $sortingDirection)
267 32
            ->getAsArray();
268
269 32
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
270 32
        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 32
    public function getRemoveSortingUri(SearchRequest $previousSearchRequest)
278
    {
279
        $persistentAndFacetArguments = $previousSearchRequest
280 32
            ->getCopyForSubRequest()->removeSorting()
281 32
            ->getAsArray();
282
283 32
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
284 32
        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 28
    public function getCurrentSearchUri(SearchRequest $previousSearchRequest)
292
    {
293
        $persistentAndFacetArguments = $previousSearchRequest
294 28
            ->getCopyForSubRequest()
295 28
            ->getAsArray();
296
297 28
        $pageUid = $this->getTargetPageUidFromRequestConfiguration($previousSearchRequest);
298 28
        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 31
    protected function getAdditionalArgumentsFromRequestConfiguration(SearchRequest $request)
306
    {
307 31
        if ($request->getContextTypoScriptConfiguration() == null) {
308
            return [];
309
        }
310
311 31
        $reQuestId = $request->getId();
312 31
        if (isset(self::$additionalArgumentsCache[$reQuestId])) {
313 31
            return self::$additionalArgumentsCache[$reQuestId];
314
        }
315
316 31
        self::$additionalArgumentsCache[$reQuestId] = $request->getContextTypoScriptConfiguration()
317 31
            ->getSearchFacetingFacetLinkUrlParametersAsArray();
318
319 31
        return self::$additionalArgumentsCache[$reQuestId];
320
    }
321
322
    /**
323
     * @param SearchRequest $request
324
     * @return integer|null
325
     */
326 35
    protected function getTargetPageUidFromRequestConfiguration(SearchRequest $request)
327
    {
328 35
        if ($request->getContextTypoScriptConfiguration() == null) {
329
            return null;
330
        }
331
332 35
        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 35
    protected function buildLinkWithInMemoryCache(int $pageUid, array $arguments): string
343
    {
344 35
        $values = [];
345 35
        $structure = $arguments;
346 35
        $this->getSubstitution($structure, $values);
347 35
        $hash = md5($pageUid . json_encode($structure));
348 35
        if (isset(self::$preCompiledLinks[$hash])) {
349 33
            self::$hitCount++;
350 33
            $uriCacheTemplate = self::$preCompiledLinks[$hash];
351
        } else {
352 35
            self::$missCount++;
353 35
            $this->uriBuilder->reset()->setTargetPageUid($pageUid);
354 35
            $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 35
            $urlHelper = GeneralUtility::makeInstance(UrlHelper::class, $uriCacheTemplate);
361 35
            $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 35
            self::$preCompiledLinks[$hash] = (string)$urlHelper;
364
        }
365
366
        $keys = array_map(function($value) {
367 35
            return urlencode($value);
368 35
        }, array_keys($values));
369
        $values = array_map(function($value) {
370 35
            return urlencode($value);
371 35
        }, $values);
372
373 35
        $routingConfigurations = $this->routingService
374 35
            ->fetchEnhancerByPageUid($pageUid);
375 35
        $enhancedRouting = count($routingConfigurations) > 0;
376 35
        $this->routingService->reset();
377 35
        if ($enhancedRouting && is_array($routingConfigurations[0])) {
378
            $this->routingService->fromRoutingConfiguration($routingConfigurations[0]);
379
        }
380
381
        /* @var Uri $uri */
382 35
        $uri = GeneralUtility::makeInstance(
383 35
            Uri::class,
384 35
            $uriCacheTemplate
385
        );
386
387 35
        $urlEvent = new BeforeReplaceVariableInCachedUrlEvent($uri, $enhancedRouting);
388
        /* @var BeforeReplaceVariableInCachedUrlEvent $urlEvent */
389 35
        $urlEvent = $this->eventDispatcher->dispatch($urlEvent);
390 35
        $uriCacheTemplate = (string)$urlEvent->getUri();
391
392 35
        $variableEvent = new BeforeProcessCachedVariablesEvent(
393 35
            $uri,
394 35
            $routingConfigurations,
395 35
            $keys,
396 35
            $values
397
        );
398 35
        $this->eventDispatcher->dispatch($variableEvent);
399
400 35
        $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 35
            if (strpos($value, '###') === false) {
405
                return $value;
406
            }
407 35
            return urlencode($value);
408 35
        }, array_keys($values));
409
410 35
        $uri = str_replace($keys, $values, $uriCacheTemplate);
411 35
        $uri = GeneralUtility::makeInstance(
412 35
            Uri::class,
413 35
            $uri
414
        );
415 35
        $uriEvent = new PostProcessUriEvent($uri, $routingConfigurations);
416 35
        $this->eventDispatcher->dispatch($uriEvent);
417 35
        $uri = $uriEvent->getUri();
418 35
        return (string)$uri;
419
    }
420
421
    /**
422
     * Flushes the internal in memory cache.
423
     *
424
     * @return void
425
     */
426
    public function flushInMemoryCache()
427
    {
428
        self::$preCompiledLinks = [];
429
    }
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 35
    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 35
        $filter = false;
470 35
        if (count($branch) > 0 && $branch[count($branch) - 1] === 'filter') {
471 31
            $filter = true;
472
        }
473 35
        foreach ($structure as $key => &$value) {
474 35
            $branch[] = $key;
475 35
            if (is_array($value)) {
476 35
                $this->getSubstitution($value, $values, $branch);
477
            } else {
478 35
                if ($filter) {
479 31
                    [$facetType, $facetValue] = explode(':', $value);
480 31
                    $branch[] = $facetType;
481
                }
482 35
                $path = '###' . implode(':', $branch) . '###';
483 35
                $values[$path] = $value;
484 35
                $structure[$key] = $path;
485 35
                if ($filter) {
486 31
                    array_pop($branch);
487
                }
488
            }
489 35
            array_pop($branch);
490
        }
491 35
    }
492
}
493