Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

SearchController::mainAction()   F
last analyzed

Complexity

Conditions 25
Paths 614

Size

Total Lines 120
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 25
eloc 64
c 3
b 0
f 0
nc 614
nop 0
dl 0
loc 120
rs 0.5361

How to fix   Long Method    Complexity   

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
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Controller;
14
15
use Kitodo\Dlf\Common\Helper;
16
use Kitodo\Dlf\Common\Indexer;
17
use Kitodo\Dlf\Common\SolrPaginator;
18
use Kitodo\Dlf\Common\Solr\Solr;
19
use Kitodo\Dlf\Domain\Model\Collection;
20
use Kitodo\Dlf\Domain\Repository\CollectionRepository;
21
use Kitodo\Dlf\Domain\Repository\MetadataRepository;
22
use Psr\Http\Message\ResponseInterface;
23
use Solarium\Component\Result\FacetSet;
24
use TYPO3\CMS\Core\Core\Environment;
25
use TYPO3\CMS\Core\Information\Typo3Version;
26
use TYPO3\CMS\Core\Pagination\SimplePagination;
27
use TYPO3\CMS\Core\Utility\ArrayUtility;
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30
/**
31
 * Controller class for the plugin 'Search'.
32
 *
33
 * @package TYPO3
34
 * @subpackage dlf
35
 *
36
 * @access public
37
 */
38
class SearchController extends AbstractController
39
{
40
    /**
41
     * @access protected
42
     * @var CollectionRepository
43
     */
44
    protected CollectionRepository $collectionRepository;
45
46
    /**
47
     * @access public
48
     *
49
     * @param CollectionRepository $collectionRepository
50
     *
51
     * @return void
52
     */
53
    public function injectCollectionRepository(CollectionRepository $collectionRepository): void
54
    {
55
        $this->collectionRepository = $collectionRepository;
56
    }
57
58
    /**
59
     * @access protected
60
     * @var MetadataRepository
61
     */
62
    protected MetadataRepository $metadataRepository;
63
64
    /**
65
     * @access public
66
     *
67
     * @param MetadataRepository $metadataRepository
68
     *
69
     * @return void
70
     */
71
    public function injectMetadataRepository(MetadataRepository $metadataRepository): void
72
    {
73
        $this->metadataRepository = $metadataRepository;
74
    }
75
76
    /**
77
     * @access protected
78
     * @var array The current search parameter
79
     */
80
    protected ?array $searchParams;
81
82
    /**
83
     * Search Action
84
     *
85
     * @access public
86
     *
87
     * @return ResponseInterface the response
88
     */
89
    public function searchAction(): ResponseInterface
90
    {
91
        // if search was triggered, get search parameters from POST variables
92
        $this->searchParams = $this->getParametersSafely('searchParameter');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getParametersSafely('searchParameter') can also be of type string. However, the property $searchParams is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
93
94
        // output is done by main action
95
        return $this->redirect('main', null, null, ['searchParameter' => $this->searchParams]);
96
    }
97
98
    /**
99
     * Main action
100
     *
101
     * This shows the search form and optional the facets and extended search form.
102
     *
103
     * @access public
104
     *
105
     * @return ResponseInterface the response
106
     */
107
    public function mainAction(): ResponseInterface
108
    {
109
        $listViewSearch = false;
110
        // Quit without doing anything if required variables are not set.
111
        if (empty($this->settings['solrcore'])) {
112
            $this->logger->warning('Incomplete plugin configuration');
113
            return $this->htmlResponse();
114
        }
115
116
        // if search was triggered, get search parameters from POST variables
117
        $this->searchParams = $this->getParametersSafely('searchParameter');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getParametersSafely('searchParameter') can also be of type string. However, the property $searchParams is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
118
        // if search was triggered by the ListView plugin, get the parameters from GET variables
119
        // replace with $this->request->getQueryParams() when dropping support for Typo3 v11, see Deprecation-100596
120
        $listRequestData = GeneralUtility::_GPmerged('tx_dlf_listview');
121
        // Quit without doing anything if no search parameters.
122
        if (empty($this->searchParams) && empty($listRequestData)) {
123
            $this->logger->warning('Missing search parameters');
124
            return $this->htmlResponse();
125
        }
126
127
        if (isset($listRequestData['searchParameter']) && is_array($listRequestData['searchParameter'])) {
128
            $this->searchParams = array_merge($this->searchParams ?: [], $listRequestData['searchParameter']);
129
            $listViewSearch = true;
130
            $GLOBALS['TSFE']->fe_user->setKey('ses', 'search', $this->searchParams);
131
        }
132
133
        // sanitize date search input
134
        if (!empty($this->searchParams['dateFrom']) || !empty($this->searchParams['dateTo'])) {
135
            if (empty($this->searchParams['dateFrom']) && !empty($this->searchParams['dateTo'])) {
136
                $this->searchParams['dateFrom'] = '*';
137
            }
138
139
            if (empty($this->searchParams['dateTo']) && !empty($this->searchParams['dateFrom'])) {
140
                $this->searchParams['dateTo'] = 'NOW';
141
            }
142
143
            if ($this->searchParams['dateFrom'] > $this->searchParams['dateTo']) {
144
                $tmpDate = $this->searchParams['dateFrom'];
145
                $this->searchParams['dateFrom'] = $this->searchParams['dateTo'];
146
                $this->searchParams['dateTo'] = $tmpDate;
147
            }
148
        }
149
150
        // Pagination of Results: Pass the currentPage to the fluid template to calculate current index of search result.
151
        $currentPage = $this->getParametersSafely('page');
152
        if (empty($currentPage)) {
153
            $currentPage = 1;
154
        }
155
156
        // If a targetPid is given, the results will be shown by ListView on the target page.
157
        if (!empty($this->settings['targetPid']) && !empty($this->searchParams) && !$listViewSearch) {
158
            return $this->redirect(
159
                'main',
160
                'ListView',
161
                null,
162
                [
163
                    'searchParameter' => $this->searchParams,
164
                    'page' => $currentPage
165
                ], $this->settings['targetPid']
166
            );
167
        }
168
169
        // If no search has been executed, no variables have to be prepared.
170
        // An empty form will be shown.
171
        if (is_array($this->searchParams) && !empty($this->searchParams)) {
172
            // get all sortable metadata records
173
            $sortableMetadata = $this->metadataRepository->findByIsSortable(true);
0 ignored issues
show
Bug introduced by
The method findByIsSortable() does not exist on Kitodo\Dlf\Domain\Repository\MetadataRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

173
            /** @scrutinizer ignore-call */ 
174
            $sortableMetadata = $this->metadataRepository->findByIsSortable(true);
Loading history...
174
175
            // get all metadata records to be shown in results
176
            $listedMetadata = $this->metadataRepository->findByIsListed(true);
0 ignored issues
show
Bug introduced by
The method findByIsListed() does not exist on Kitodo\Dlf\Domain\Repository\MetadataRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

176
            /** @scrutinizer ignore-call */ 
177
            $listedMetadata = $this->metadataRepository->findByIsListed(true);
Loading history...
177
178
            // get all indexed metadata fields
179
            $indexedMetadata = $this->metadataRepository->findByIndexIndexed(true);
0 ignored issues
show
Bug introduced by
The method findByIndexIndexed() does not exist on Kitodo\Dlf\Domain\Repository\MetadataRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

179
            /** @scrutinizer ignore-call */ 
180
            $indexedMetadata = $this->metadataRepository->findByIndexIndexed(true);
Loading history...
180
181
            $solrResults = null;
182
            $numResults = 0;
183
            // Do not execute the Solr search if used together with ListView plugin.
184
            if (!$listViewSearch) {
185
                $solrResults = $this->documentRepository->findSolrWithoutCollection($this->settings, $this->searchParams, $listedMetadata, $indexedMetadata);
186
                $numResults = $solrResults->getNumFound();
187
188
                $itemsPerPage = $this->settings['list']['paginate']['itemsPerPage'];
189
                if (empty($itemsPerPage)) {
190
                    $itemsPerPage = 25;
191
                }
192
                $solrPaginator = new SolrPaginator($solrResults, $currentPage, $itemsPerPage);
193
                $simplePagination = new SimplePagination($solrPaginator);
194
195
                $pagination = $this->buildSimplePagination($simplePagination, $solrPaginator);
196
                $this->view->assignMultiple([ 'pagination' => $pagination, 'paginator' => $solrPaginator ]);
197
            }
198
199
            $this->view->assign('documents', !empty($solrResults) ? $solrResults : []);
200
            $this->view->assign('numResults', $numResults);
201
            $this->view->assign('page', $currentPage);
202
            $this->view->assign('lastSearch', $this->searchParams);
203
            $this->view->assign('listedMetadata', $listedMetadata);
204
            $this->view->assign('sortableMetadata', $sortableMetadata);
205
206
            // Add the facets menu
207
            $this->addFacetsMenu();
208
        }
209
210
        // Get additional fields for extended search.
211
        $this->addExtendedSearch();
212
213
        // Add the current document if present to fluid. This way, we can limit further searches to this document.
214
        if (isset($this->requestData['id'])) {
215
            $currentDocument = $this->documentRepository->findByUid($this->requestData['id']);
216
            $this->view->assign('currentDocument', $currentDocument);
217
        }
218
219
        // Add uHash parameter to suggest parameter to make a basic protection of this form.
220
        if ($this->settings['suggest']) {
221
            $this->view->assign('uHash', GeneralUtility::hmac((string) (new Typo3Version()) . Environment::getExtensionsPath(), 'SearchSuggest'));
222
        }
223
224
        $this->view->assign('viewData', $this->viewData);
225
226
        return $this->htmlResponse();
227
    }
228
229
    /**
230
     * Adds the facets menu to the search form
231
     *
232
     * @access protected
233
     */
234
    protected function addFacetsMenu(): void
235
    {
236
        // Quit without doing anything if no facets are configured.
237
        if (empty($this->settings['facets']) && empty($this->settings['facetCollections'])) {
238
            return;
239
        }
240
241
        // Get facets from plugin configuration.
242
        $facets = [];
243
        foreach (GeneralUtility::trimExplode(',', $this->settings['facets'], true) as $facet) {
244
            $facets[$facet . '_faceting'] = Helper::translate($facet, 'tx_dlf_metadata', $this->settings['storagePid']);
245
        }
246
247
        $this->view->assign('facetsMenu', $this->makeFacetsMenuArray($facets));
248
    }
249
250
    /**
251
     * This builds a menu array for HMENU
252
     *
253
     * @access public
254
     *
255
     * @param array $facets
256
     *
257
     * @return array HMENU array
258
     */
259
    public function makeFacetsMenuArray(array $facets): array
260
    {
261
        // Set default value for facet search.
262
        $search = [
263
            'query' => '*:*',
264
            'params' => [
265
                'component' => [
266
                    'facetset' => [
267
                        'facet' => []
268
                    ]
269
                ],
270
                'filterquery' => []
271
            ]
272
        ];
273
274
        $fields = Solr::getFields();
275
276
        // Set search query.
277
        $searchParams = $this->searchParams;
278
        if (
279
            (!empty($searchParams['fulltext']))
280
            || preg_match('/' . $fields['fulltext'] . ':\((.*)\)/', trim($searchParams['query']), $matches)
281
        ) {
282
            // If the query already is a fulltext query e.g using the facets
283
            $searchParams['query'] = empty($matches[1]) ? $searchParams['query'] : $matches[1];
284
            // Search in fulltext field if applicable. Query must not be empty!
285
            if (!empty($searchParams['query'])) {
286
                $search['query'] = $fields['fulltext'] . ':(' . Solr::escapeQuery(trim($searchParams['query'])) . ')';
287
            }
288
        } else {
289
            // Retain given search field if valid.
290
            if (!empty($searchParams['query'])) {
291
                $search['query'] = Solr::escapeQueryKeepField(trim($searchParams['query']), $this->settings['storagePid']);
292
            }
293
        }
294
295
        $collectionsQuery = $this->addCollectionsQuery($search['query']);
296
        if (!empty($collectionsQuery)) {
297
            $search['params']['filterquery'][]['query'] = $collectionsQuery;
298
        }
299
300
        // add filter query for date search
301
        if (!empty($this->searchParams['dateFrom']) && !empty($this->searchParams['dateTo'])) {
302
            // combine dateFrom and dateTo into filterquery as range search
303
            $search['params']['filterquery'][]['query'] = '{!join from=' . $fields['uid'] . ' to=' . $fields['uid'] . '}' . $fields['date'] . ':[' . $this->searchParams['dateFrom'] . ' TO ' . $this->searchParams['dateTo'] . ']';
304
        }
305
306
        // Add extended search query.
307
        if (
308
            !empty($searchParams['extQuery'])
309
            && is_array($searchParams['extQuery'])
310
        ) {
311
            // If the search query is already set by the simple search field, we have to reset it.
312
            $search['query'] = '';
313
            $allowedOperators = ['AND', 'OR', 'NOT'];
314
            $numberOfExtQueries = count($searchParams['extQuery']);
315
            for ($i = 0; $i < $numberOfExtQueries; $i++) {
316
                if (!empty($searchParams['extQuery'][$i])) {
317
                    if (
318
                        in_array($searchParams['extOperator'][$i], $allowedOperators)
319
                    ) {
320
                        if (!empty($search['query'])) {
321
                            $search['query'] .= ' ' . $searchParams['extOperator'][$i] . ' ';
322
                        }
323
                        $search['query'] .= Indexer::getIndexFieldName($searchParams['extField'][$i], $this->settings['storagePid']) . ':(' . Solr::escapeQuery($searchParams['extQuery'][$i]) . ')';
324
                    }
325
                }
326
            }
327
        }
328
329
        if (isset($this->searchParams['fq']) && is_array($this->searchParams['fq'])) {
330
            foreach ($this->searchParams['fq'] as $fq) {
331
                $search['params']['filterquery'][]['query'] = $fq;
332
            }
333
        }
334
335
        // Get applicable facets.
336
        $solr = Solr::getInstance($this->settings['solrcore']);
337
        if (!$solr->ready) {
338
            $this->logger->error('Apache Solr not available');
339
            return [];
340
        }
341
342
        foreach (array_keys($facets) as $field) {
343
            $search['params']['component']['facetset']['facet'][$field] = [
344
                'type' => 'field',
345
                'mincount' => '1',
346
                'key' => $field,
347
                'field' => $field,
348
                'limit' => $this->settings['limitFacets'],
349
                'sort' => isset($this->settings['sortingFacets']) ? $this->settings['sortingFacets'] : 'count'
350
            ];
351
        }
352
353
        // Set additional query parameters.
354
        $search['params']['start'] = 0;
355
        $search['params']['rows'] = 0;
356
        // Set query.
357
        $search['params']['query'] = $search['query'];
358
        // Perform search.
359
        $selectQuery = $solr->service->createSelect($search['params']);
360
        // check for solr response
361
        $solrRequest = $solr->service->createRequest($selectQuery);
362
        $response = $solr->service->executeRequest($solrRequest);
363
        // return empty facet on solr error
364
        if ($response->getStatusCode() == 400) {
365
            return [];
366
        }
367
        $results = $solr->service->select($selectQuery);
368
        $facet = $results->getFacetSet();
369
370
        $facetCollectionArray = [];
371
372
        // replace everything expect numbers and comma
373
        $facetCollections = preg_replace('/[^\d,]/', '', $this->settings['facetCollections']);
374
375
        if (!empty($facetCollections)) {
376
            $collections = $this->collectionRepository->findCollectionsBySettings(['collections' => $facetCollections]);
377
378
            /** @var Collection $collection */
379
            foreach ($collections as $collection) {
380
                $facetCollectionArray[] = $collection->getIndexName();
381
            }
382
        }
383
384
        return $this->processResults($facet, $facetCollectionArray, $search);
385
    }
386
387
    /**
388
     * Add the collection query string, if the collections are given.
389
     *
390
     * @access private
391
     *
392
     * @param string $query The current query
393
     *
394
     * @return string The collection query string
395
     */
396
    private function addCollectionsQuery(string $query): string
397
    {
398
        // if collections are given, we prepare the collections query string
399
        // extract collections from collection parameter
400
        $collections = null;
401
        if (array_key_exists('collection', $this->searchParams)) {
402
            foreach (explode(',', $this->searchParams['collection']) as $collectionEntry) {
403
                if (!empty($collectionEntry)) {
404
                    $collections[] = $this->collectionRepository->findByUid((int) $collectionEntry);
405
                }
406
            }
407
        }
408
        if ($collections) {
0 ignored issues
show
introduced by
$collections is of type null, thus it always evaluated to false.
Loading history...
409
            $collectionsQueryString = '';
410
            $virtualCollectionsQueryString = '';
411
            foreach ($collections as $collectionEntry) {
412
                // check for virtual collections query string
413
                if ($collectionEntry->getIndexSearch()) {
414
                    $virtualCollectionsQueryString .= empty($virtualCollectionsQueryString) ? '(' . $collectionEntry->getIndexSearch() . ')' : ' OR (' . $collectionEntry->getIndexSearch() . ')';
415
                } else {
416
                    $collectionsQueryString .= empty($collectionsQueryString) ? '"' . $collectionEntry->getIndexName() . '"' : ' OR "' . $collectionEntry->getIndexName() . '"';
417
                }
418
            }
419
420
            // distinguish between simple collection browsing and actual searching within the collection(s)
421
            if (!empty($collectionsQueryString)) {
422
                if (empty($query)) {
423
                    $collectionsQueryString = '(collection_faceting:(' . $collectionsQueryString . ') AND toplevel:true AND partof:0)';
424
                } else {
425
                    $collectionsQueryString = '(collection_faceting:(' . $collectionsQueryString . '))';
426
                }
427
            }
428
429
            // virtual collections might query documents that are neither toplevel:true nor partof:0 and need to be searched separately
430
            if (!empty($virtualCollectionsQueryString)) {
431
                $virtualCollectionsQueryString = '(' . $virtualCollectionsQueryString . ')';
432
            }
433
434
            // combine both querystrings into a single filterquery via OR if both are given, otherwise pass either of those
435
            return implode(" OR ", array_filter([$collectionsQueryString, $virtualCollectionsQueryString]));
436
        }
437
        return "";
438
    }
439
440
    /**
441
     * Creates an array for a HMENU entry of a facet value.
442
     *
443
     * @access private
444
     *
445
     * @param string $field The facet's index_name
446
     * @param string $value The facet's value
447
     * @param int $count Number of hits for this facet
448
     * @param array $search The parameters of the current search query
449
     * @param string &$state The state of the parent item
450
     *
451
     * @return array The array for the facet's menu entry
452
     */
453
    private function getFacetsMenuEntry(string $field, string $value, int $count, array $search, string &$state): array
454
    {
455
        $entryArray = [];
456
        $entryArray['title'] = $this->translateValue($field, $value);
457
        $entryArray['count'] = $count;
458
        $entryArray['doNotLinkIt'] = 0;
459
        // Check if facet is already selected.
460
        $queryColumn = array_column($search['params']['filterquery'], 'query');
461
        $index = array_search($field . ':("' . Solr::escapeQuery($value) . '")', $queryColumn);
462
        if ($index !== false) {
463
            // Facet is selected, thus remove it from filter.
464
            unset($queryColumn[$index]);
465
            $queryColumn = array_values($queryColumn);
466
            $entryArray['ITEM_STATE'] = 'CUR';
467
            $state = 'ACTIFSUB';
468
            // Reset facets
469
            if ($this->settings['resetFacets']) {
470
                $entryArray['resetFacet'] = true;
471
                $entryArray['queryColumn'] = $queryColumn;
472
            }
473
        } else {
474
            // Facet is not selected, thus add it to filter.
475
            $queryColumn[] = $field . ':("' . Solr::escapeQuery($value) . '")';
476
            $entryArray['ITEM_STATE'] = 'NO';
477
        }
478
        $entryArray['queryColumn'] = $queryColumn;
479
480
        return $entryArray;
481
    }
482
483
    /**
484
     * Process results.
485
     *
486
     * @access private
487
     *
488
     * @param FacetSet|null $facet
489
     * @param array $facetCollectionArray
490
     * @param array $search
491
     *
492
     * @return array menu array
493
     */
494
    private function processResults($facet, array $facetCollectionArray, array $search): array
495
    {
496
        $menuArray = [];
497
498
        if ($facet) {
499
            foreach ($facet as $field => $values) {
500
                $entryArray = [];
501
                $entryArray['field'] = substr($field, 0, strpos($field, '_faceting'));
502
                $entryArray['count'] = 0;
503
                $entryArray['_OVERRIDE_HREF'] = '';
504
                $entryArray['ITEM_STATE'] = 'NO';
505
                // Count number of facet values.
506
                $i = 0;
507
                foreach ($values as $value => $count) {
508
                    if ($count > 0) {
509
                        // check if facet collection configuration exists
510
                        if (!empty($this->settings['facetCollections'])) {
511
                            if ($field == "collection_faceting" && !in_array($value, $facetCollectionArray)) {
512
                                continue;
513
                            }
514
                        }
515
                        $entryArray['count']++;
516
                        if ($entryArray['ITEM_STATE'] == 'NO') {
517
                            $entryArray['ITEM_STATE'] = 'IFSUB';
518
                        }
519
                        $entryArray['_SUB_MENU'][] = $this->getFacetsMenuEntry($field, $value, $count, $search, $entryArray['ITEM_STATE']);
520
                        if (++$i == $this->settings['limit']) {
521
                            break;
522
                        }
523
                    } else {
524
                        break;
525
                    }
526
                }
527
                $menuArray[] = $entryArray;
528
            }
529
        }
530
        return $menuArray;
531
    }
532
533
    /**
534
     * Translates value depending on the index name.
535
     *
536
     * @access private
537
     *
538
     * @param string $field The facet's index_name
539
     * @param string $value The facet's value
540
     *
541
     * @return string
542
     */
543
    private function translateValue(string $field, string $value): string
544
    {
545
        switch ($field) {
546
            case 'owner_faceting':
547
                // Translate name of holding library.
548
                return htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['storagePid']));
549
            case 'type_faceting':
550
                // Translate document type.
551
                return htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['storagePid']));
552
            case 'collection_faceting':
553
                // Translate name of collection.
554
                return htmlspecialchars(Helper::translate($value, 'tx_dlf_collections', $this->settings['storagePid']));
555
            case 'language_faceting':
556
                // Translate ISO 639 language code.
557
                return htmlspecialchars(Helper::getLanguageName($value));
558
            default:
559
                return htmlspecialchars($value);
560
        }
561
    }
562
563
    /**
564
     * Returns the extended search form and adds the JS files necessary for extended search.
565
     *
566
     * @access private
567
     *
568
     * @return void
569
     */
570
    private function addExtendedSearch(): void
571
    {
572
        // Quit without doing anything if no fields for extended search are selected.
573
        if (
574
            empty($this->settings['extendedSlotCount'])
575
            || empty($this->settings['extendedFields'])
576
        ) {
577
            return;
578
        }
579
580
        // Get field selector options.
581
        $searchFields = GeneralUtility::trimExplode(',', $this->settings['extendedFields'], true);
582
583
        $slotCountArray = [];
584
        for ($i = 0; $i < $this->settings['extendedSlotCount']; $i++) {
585
            $slotCountArray[] = $i;
586
        }
587
588
        $this->view->assign('extendedSlotCount', $slotCountArray);
589
        $this->view->assign('extendedFields', $this->settings['extendedFields']);
590
        $this->view->assign('operators', ['AND', 'OR', 'NOT']);
591
        $this->view->assign('searchFields', $searchFields);
592
    }
593
}
594