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.
Passed
Pull Request — dev-extbase-fluid (#737)
by Alexander
02:59
created

SearchController   F

Complexity

Total Complexity 105

Size/Duplication

Total Lines 558
Duplicated Lines 0 %

Importance

Changes 23
Bugs 0 Features 0
Metric Value
eloc 282
dl 0
loc 558
rs 2
c 23
b 0
f 0
wmc 105

10 Methods

Rating   Name   Duplication   Size   Complexity  
C mainAction() 0 42 12
B getFacetsMenuEntry() 0 56 7
B addCurrentCollection() 0 22 7
A injectCollectionRepository() 0 3 1
F makeFacetsMenuArray() 0 100 17
A addExtendedSearch() 0 29 6
B addCurrentDocument() 0 28 9
A addEncryptedCoreName() 0 11 3
F searchAction() 0 149 38
A addFacetsMenu() 0 19 5

How to fix   Complexity   

Complex Class

Complex classes like SearchController 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 SearchController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
4
 *
5
 * This file is part of the Kitodo and TYPO3 projects.
6
 *
7
 * @license GNU General Public License version 3 or later.
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace Kitodo\Dlf\Controller;
13
14
use Kitodo\Dlf\Common\Document;
15
use Kitodo\Dlf\Common\DocumentList;
16
use Kitodo\Dlf\Common\Helper;
17
use Kitodo\Dlf\Common\Indexer;
18
use Kitodo\Dlf\Common\Solr;
19
use Kitodo\Dlf\Domain\Model\Collection;
20
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
21
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
22
use TYPO3\CMS\Core\Utility\GeneralUtility;
23
use Kitodo\Dlf\Domain\Repository\CollectionRepository;
24
25
class SearchController extends AbstractController
26
{
27
    public $prefixId = 'tx_dlf';
28
    public $extKey = 'dlf';
29
30
    protected $collectionRepository;
31
32
    /**
33
     * @param CollectionRepository $collectionRepository
34
     */
35
    public function injectCollectionRepository(CollectionRepository $collectionRepository)
36
    {
37
        $this->collectionRepository = $collectionRepository;
38
    }
39
40
    /**
41
     * Search action
42
     */
43
    public function searchAction()
44
    {
45
        $requestData = GeneralUtility::_GPmerged('tx_dlf');
46
        unset($requestData['__referrer'], $requestData['__trustedProperties']);
47
48
        $this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get($this->extKey);
49
50
        // Build label for result list.
51
        $label = htmlspecialchars(LocalizationUtility::translate('search.search', 'dlf'));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...'search.search', 'dlf') can also be of type null; however, parameter $string of htmlspecialchars() does only seem to accept string, 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

51
        $label = htmlspecialchars(/** @scrutinizer ignore-type */ LocalizationUtility::translate('search.search', 'dlf'));
Loading history...
52
        if (!empty($requestData['query'])) {
53
            $label .= ' ' . htmlspecialchars(sprintf(LocalizationUtility::translate('search.for', 'dlf'), trim($requestData['query'])));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...te('search.for', 'dlf') can also be of type null; however, parameter $format of sprintf() does only seem to accept string, 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

53
            $label .= ' ' . htmlspecialchars(sprintf(/** @scrutinizer ignore-type */ LocalizationUtility::translate('search.for', 'dlf'), trim($requestData['query'])));
Loading history...
54
        }
55
        // Prepare query parameters.
56
        $params = [];
57
        $matches = [];
58
        // Set search query.
59
        if (
60
            (!empty($this->settings['fulltext']) && !empty($requestData['fulltext']))
61
            || preg_match('/fulltext:\((.*)\)/', trim($requestData['query']), $matches)
62
        ) {
63
            // If the query already is a fulltext query e.g using the facets
64
            $requestData['query'] = empty($matches[1]) ? $requestData['query'] : $matches[1];
65
            // Search in fulltext field if applicable. Query must not be empty!
66
            if (!empty($requestData['query'])) {
67
                $query = 'fulltext:(' . Solr::escapeQuery(trim($requestData['query'])) . ')';
68
            }
69
        } else {
70
            // Retain given search field if valid.
71
            $query = Solr::escapeQueryKeepField(trim($requestData['query']), $this->settings['pages']);
72
        }
73
        // Add extended search query.
74
        if (
75
            !empty($requestData['extQuery'])
76
            && is_array($requestData['extQuery'])
77
        ) {
78
            $allowedOperators = ['AND', 'OR', 'NOT'];
79
            $allowedFields = GeneralUtility::trimExplode(',', $this->settings['extendedFields'], true);
80
            $numberOfExtQueries = count($requestData['extQuery']);
81
            for ($i = 0; $i < $numberOfExtQueries; $i++) {
82
                if (!empty($requestData['extQuery'][$i])) {
83
                    if (
84
                        in_array($requestData['extOperator'][$i], $allowedOperators)
85
                        && in_array($requestData['extField'][$i], $allowedFields)
86
                    ) {
87
                        if (!empty($query)) {
88
                            $query .= ' ' . $requestData['extOperator'][$i] . ' ';
89
                        }
90
                        $query .= Indexer::getIndexFieldName($requestData['extField'][$i], $this->settings['pages']) . ':(' . Solr::escapeQuery($requestData['extQuery'][$i]) . ')';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.
Loading history...
91
                    }
92
                }
93
            }
94
        }
95
        // Add filter query for faceting.
96
        if (!empty($requestData['fq'])) {
97
            foreach ($requestData['fq'] as $filterQuery) {
98
                $params['filterquery'][]['query'] = $filterQuery;
99
            }
100
        }
101
102
        // Add filter query for in-document searching.
103
        if (
104
            $this->settings['searchIn'] == 'document'
105
            || $this->settings['searchIn'] == 'all'
106
        ) {
107
            if (
108
                !empty($requestData['id'])
109
                && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($requestData['id'])
110
            ) {
111
                // Search in document and all subordinates (valid for up to three levels of hierarchy).
112
                $params['filterquery'][]['query'] = '_query_:"{!join from=uid to=partof}uid:{!join from=uid to=partof}uid:' . $requestData['id'] . '"' .
113
                    ' OR {!join from=uid to=partof}uid:' . $requestData['id'] .
114
                    ' OR uid:' . $requestData['id'];
115
                $label .= ' ' . htmlspecialchars(sprintf(LocalizationUtility::translate('search.in', 'dlf'), Document::getTitle($requestData['id'])));
116
            }
117
        }
118
        // Add filter query for in-collection searching.
119
        if (
120
            $this->settings['searchIn'] == 'collection'
121
            || $this->settings['searchIn'] == 'all'
122
        ) {
123
            if (
124
                !empty($requestData['collection'])
125
                && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($requestData['collection'])
126
            ) {
127
                $index_name = Helper::getIndexNameFromUid($requestData['collection'], 'tx_dlf_collections', $this->settings['pages']);
128
                $params['filterquery'][]['query'] = 'collection_faceting:("' . Solr::escapeQuery($index_name) . '")';
129
                $label .= ' ' . sprintf(LocalizationUtility::translate('search.in', 'dlf'), Helper::translate($index_name, 'tx_dlf_collections', $this->settings['pages']));
130
            }
131
        }
132
        // Add filter query for collection restrictions.
133
        if ($this->settings['collections']) {
134
            $collIds = explode(',', $this->settings['collections']);
135
            $collIndexNames = [];
136
            foreach ($collIds as $collId) {
137
                $collIndexNames[] = Solr::escapeQuery(Helper::getIndexNameFromUid(intval($collId), 'tx_dlf_collections', $this->settings['pages']));
138
            }
139
            // Last value is fake and used for distinction in $this->addCurrentCollection()
140
            $params['filterquery'][]['query'] = 'collection_faceting:("' . implode('" OR "', $collIndexNames) . '" OR "FakeValueForDistinction")';
141
        }
142
        // Set some query parameters.
143
        $params['query'] = !empty($query) ? $query : '*';
144
        $params['start'] = 0;
145
        $params['rows'] = 0;
146
        $params['sort'] = ['score' => 'desc'];
147
        // Instantiate search object.
148
        $solr = Solr::getInstance($this->settings['solrcore']);
149
        if (!$solr->ready) {
150
            $this->logger->error('Apache Solr not available');
1 ignored issue
show
Bug introduced by
The method error() 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

150
            $this->logger->/** @scrutinizer ignore-call */ 
151
                           error('Apache Solr not available');

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...
151
            $this->redirect('main', 'Search', null);
152
            //return $this->responseFactory->createHtmlResponse($this->view->render());
153
        }
154
        // Set search parameters.
155
        $solr->cPid = $this->settings['pages'];
156
        $solr->params = $params;
157
        // Perform search.
158
        $list = $solr->search();
159
        $list->metadata = [
160
            'label' => $label,
161
            'thumbnail' => '',
162
            'searchString' => $requestData['query'],
163
            'fulltextSearch' => (!empty($requestData['fulltext']) ? '1' : '0'),
164
            'options' => $list->metadata['options']
165
        ];
166
        $list->save();
167
        // Clean output buffer.
168
        ob_end_clean();
169
        $additionalParams = [];
170
        if (!empty($requestData['logicalPage'])) {
171
            $additionalParams['logicalPage'] = $requestData['logicalPage'];
172
        }
173
        // Jump directly to the page view, if there is only one result and it is configured
174
        if ($list->metadata['options']['numberOfHits'] == 1 && !empty($this->settings['showSingleResult'])) {
175
            $linkConf['parameter'] = $this->settings['targetPidPageView'];
176
            $additionalParams['id'] = $list->current()['uid'];
177
            $additionalParams['highlight_word'] = preg_replace('/\s\s+/', ';', $list->metadata['searchString']);
178
            $additionalParams['page'] = count($list[0]['subparts']) == 1 ? $list[0]['subparts'][0]['page'] : 1;
179
        } else {
180
            // Keep some plugin variables.
181
            $linkConf['parameter'] = $this->settings['targetPid'];
182
            if (!empty($requestData['order'])) {
183
                $additionalParams['order'] = $requestData['order'];
184
                $additionalParams['asc'] = !empty($requestData['asc']) ? '1' : '0';
185
            }
186
        }
187
        $linkConf['forceAbsoluteUrl'] = !empty($this->settings['forceAbsoluteUrl']) ? 1 : 0;
188
        $linkConf['forceAbsoluteUrl.']['scheme'] = !empty($this->settings['forceAbsoluteUrl']) && !empty($this->settings['forceAbsoluteUrlHttps']) ? 'https' : 'http';
189
        $linkConf['additionalParams'] = GeneralUtility::implodeArrayForUrl($this->prefixId, $additionalParams, '', true, false);
190
191
        $this->redirect('main', 'Search', null, null);
192
    }
193
194
    /**
195
     *
196
     * @return mixed
197
     * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
198
     */
199
    public function mainAction()
200
    {
201
        $requestData = GeneralUtility::_GPmerged('tx_dlf');
202
        unset($requestData['__referrer'], $requestData['__trustedProperties']);
203
204
        // Quit without doing anything if required variables are not set.
205
        if (empty($this->settings['solrcore'])) {
206
            $this->logger->warning('Incomplete plugin configuration');
207
            return '';
208
        }
209
        if (!isset($requestData['query'])
210
            && empty($requestData['extQuery'])
211
        ) {
212
            // Extract query and filter from last search.
213
            $list = GeneralUtility::makeInstance(DocumentList::class);
214
            if (!empty($list->metadata['searchString'])) {
215
                if ($list->metadata['options']['source'] == 'search') {
216
                    $search['query'] = $list->metadata['searchString'];
217
                }
218
                $search['params'] = $list->metadata['options']['params'];
219
            }
220
221
            $this->view->assign('QUERY', (!empty($search['query']) ? htmlspecialchars($search['query']) : ''));
222
            $this->view->assign('FULLTEXT_SEARCH', $list->metadata['fulltextSearch']);
223
        } else {
224
            $this->view->assign('QUERY', (!empty($requestData['query']) ? htmlspecialchars($requestData['query']) : ''));
225
            $this->view->assign('FULLTEXT_SEARCH', $requestData['fulltext']);
226
        }
227
228
        $this->view->assign('FACETS_MENU', $this->addFacetsMenu());
229
230
        $this->addEncryptedCoreName();
231
232
        if ($this->settings['searchIn'] == 'collection' || $this->settings['searchIn'] == 'all') {
233
            $this->addCurrentCollection();
234
        }
235
        if ($this->settings['searchIn'] == 'document' || $this->settings['searchIn'] == 'all') {
236
            $this->addCurrentDocument($requestData);
237
        }
238
239
        // Get additional fields for extended search.
240
        $this->addExtendedSearch();
241
    }
242
243
    /**
244
     * Adds the current document's UID or parent ID to the search form
245
     *
246
     * @access protected
247
     *
248
     * @return string HTML input fields with current document's UID
249
     */
250
    protected function addCurrentDocument($requestData)
251
    {
252
        // Load current list object.
253
        $list = GeneralUtility::makeInstance(DocumentList::class);
254
        // Load current document.
255
        if (
256
            !empty($requestData['id'])
257
            && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($requestData['id'])
258
        ) {
259
            $this->loadDocument($requestData);
260
            // Get document's UID
261
            if ($this->doc->ready) {
262
                $this->view->assign('DOCUMENT_ID', $this->doc->uid);
263
            }
264
        } elseif (!empty($list->metadata['options']['params']['filterquery'])) {
265
            // Get document's UID from search metadata.
266
            // The string may be e.g. "{!join from=uid to=partof}uid:{!join from=uid to=partof}uid:2" OR {!join from=uid to=partof}uid:2 OR uid:2"
267
            // or "collection_faceting:("Some Collection Title")"
268
            foreach ($list->metadata['options']['params']['filterquery'] as $facet) {
269
                if (($lastUidPos = strrpos($facet['query'], 'uid:')) !== false) {
270
                    $facetKeyVal = explode(':', substr($facet['query'], $lastUidPos));
271
                    if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($facetKeyVal[1])) {
272
                        $documentId = (int) $facetKeyVal[1];
273
                    }
274
                }
275
            }
276
            if (!empty($documentId)) {
277
                $this->view->assign('DOCUMENT_ID', $documentId);
278
            }
279
        }
280
    }
281
282
283
    /**
284
     * Adds the current collection's UID to the search form
285
     *
286
     * @access protected
287
     *
288
     * @return string HTML input fields with current document's UID and parent ID
289
     */
290
    protected function addCurrentCollection()
291
    {
292
        // Load current collection.
293
        $list = GeneralUtility::makeInstance(DocumentList::class);
294
        if (
295
            !empty($list->metadata['options']['source'])
296
            && $list->metadata['options']['source'] == 'collection'
297
        ) {
298
            $this->view->assign('COLLECTION_ID', $list->metadata['options']['select']);
299
            // Get collection's UID.
300
        } elseif (!empty($list->metadata['options']['params']['filterquery'])) {
301
            // Get collection's UID from search metadata.
302
            foreach ($list->metadata['options']['params']['filterquery'] as $facet) {
303
                $facetKeyVal = explode(':', $facet['query'], 2);
304
                if (
305
                    $facetKeyVal[0] == 'collection_faceting'
306
                    && !strpos($facetKeyVal[1], '" OR "')
307
                ) {
308
                    $collectionId = Helper::getUidFromIndexName(trim($facetKeyVal[1], '(")'), 'tx_dlf_collections');
309
                }
310
            }
311
            $this->view->assign('COLLECTION_ID', $collectionId);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $collectionId does not seem to be defined for all execution paths leading up to this point.
Loading history...
312
        }
313
    }
314
315
    /**
316
     * Adds the encrypted Solr core name to the search form
317
     *
318
     * @access protected
319
     *
320
     * @return string HTML input fields with encrypted core name and hash
321
     */
322
    protected function addEncryptedCoreName()
323
    {
324
        // Get core name.
325
        $name = Helper::getIndexNameFromUid($this->settings['solrcore'], 'tx_dlf_solrcores');
326
        // Encrypt core name.
327
        if (!empty($name)) {
328
            $name = Helper::encrypt($name);
329
        }
330
        // Add encrypted fields to search form.
331
        if ($name !== false) {
332
            $this->view->assign('ENCRYPTED_CORE_NAME', $name);
333
        }
334
    }
335
336
    /**
337
     * Adds the facets menu to the search form
338
     *
339
     * @access protected
340
     *
341
     * @return string HTML output of facets menu
342
     */
343
    protected function addFacetsMenu()
344
    {
345
        // Check for typoscript configuration to prevent fatal error.
346
        if (empty($this->settings['facetsConf'])) {
347
            $this->logger->warning('Incomplete plugin configuration');
348
            return '';
349
        }
350
        // Quit without doing anything if no facets are selected.
351
        if (empty($this->settings['facets']) && empty($this->settings['facetCollections'])) {
352
            return '';
353
        }
354
355
        // Get facets from plugin configuration.
356
        $facets = [];
357
        foreach (GeneralUtility::trimExplode(',', $this->settings['facets'], true) as $facet) {
358
            $facets[$facet . '_faceting'] = Helper::translate($facet, 'tx_dlf_metadata', $this->settings['pages']);
359
        }
360
361
        $this->view->assign('facetsMenu', $this->makeFacetsMenuArray($facets));
362
    }
363
364
    /**
365
     * This builds a menu array for HMENU
366
     *
367
     * @access public
368
     *
369
     * @param string $content: The PlugIn content
370
     * @param array $conf: The PlugIn configuration
371
     *
372
     * @return array HMENU array
373
     */
374
    public function makeFacetsMenuArray($facets)
375
    {
376
        $menuArray = [];
377
        // Set default value for facet search.
378
        $search = [
379
            'query' => '*',
380
            'params' => [
381
                'component' => [
382
                    'facetset' => [
383
                        'facet' => []
384
                    ]
385
                ]
386
            ]
387
        ];
388
        // Extract query and filter from last search.
389
        $list = GeneralUtility::makeInstance(DocumentList::class);
390
        if (!empty($list->metadata['options']['source'])) {
391
            if ($list->metadata['options']['source'] == 'search') {
392
                $search['query'] = $list->metadata['options']['select'];
393
            }
394
            $search['params'] = $list->metadata['options']['params'];
395
        }
396
        // Get applicable facets.
397
        $solr = Solr::getInstance($this->settings['solrcore']);
398
        if (!$solr->ready) {
399
            $this->logger->error('Apache Solr not available');
400
            return [];
401
        }
402
        // Set needed parameters for facet search.
403
        if (empty($search['params']['filterquery'])) {
404
            $search['params']['filterquery'] = [];
405
        }
406
407
        foreach (array_keys($facets) as $field) {
408
            $search['params']['component']['facetset']['facet'][] = [
409
                'type' => 'field',
410
                'key' => $field,
411
                'field' => $field,
412
                'limit' => $this->settings['limitFacets'],
413
                'sort' => isset($this->settings['sortingFacets']) ? $this->settings['sortingFacets'] : 'count'
414
            ];
415
        }
416
417
        // Set additional query parameters.
418
        $search['params']['start'] = 0;
419
        $search['params']['rows'] = 0;
420
        // Set query.
421
        $search['params']['query'] = $search['query'];
422
        // Perform search.
423
        $selectQuery = $solr->service->createSelect($search['params']);
424
        $results = $solr->service->select($selectQuery);
425
        $facet = $results->getFacetSet();
426
427
        $facetCollectionArray = [];
428
429
        // replace everything expect numbers and comma
430
        $facetCollections = preg_replace('/[^0-9,]/', '', $this->settings['facetCollections']);
431
432
        if (!empty($facetCollections)) {
433
            $collections = $this->collectionRepository->getFacetCollections($facetCollections);
434
435
            /** @var Collection $collection */
436
            foreach ($collections as $collection) {
437
                $facetCollectionArray[] = $collection->getIndexName();
438
            }
439
        }
440
441
        // Process results.
442
        foreach ($facet as $field => $values) {
443
            $entryArray = [];
444
            $entryArray['title'] = htmlspecialchars($facets[$field]);
445
            $entryArray['count'] = 0;
446
            $entryArray['_OVERRIDE_HREF'] = '';
447
            $entryArray['doNotLinkIt'] = 1;
448
            $entryArray['ITEM_STATE'] = 'NO';
449
            // Count number of facet values.
450
            $i = 0;
451
            foreach ($values as $value => $count) {
452
                if ($count > 0) {
453
                    // check if facet collection configuration exists
454
                    if (!empty($this->settings['facetCollections'])) {
455
                        if ($field == "collection_faceting" && !in_array($value, $facetCollectionArray)) {
456
                            continue;
457
                        }
458
                    }
459
                    $entryArray['count']++;
460
                    if ($entryArray['ITEM_STATE'] == 'NO') {
461
                        $entryArray['ITEM_STATE'] = 'IFSUB';
462
                    }
463
                    $entryArray['_SUB_MENU'][] = $this->getFacetsMenuEntry($field, $value, $count, $search, $entryArray['ITEM_STATE']);
464
                    if (++$i == $this->settings['limit']) {
465
                        break;
466
                    }
467
                } else {
468
                    break;
469
                }
470
            }
471
            $menuArray[] = $entryArray;
472
        }
473
        return $menuArray;
474
    }
475
476
    /**
477
     * Creates an array for a HMENU entry of a facet value.
478
     *
479
     * @access protected
480
     *
481
     * @param string $field: The facet's index_name
482
     * @param string $value: The facet's value
483
     * @param int $count: Number of hits for this facet
484
     * @param array $search: The parameters of the current search query
485
     * @param string &$state: The state of the parent item
486
     *
487
     * @return array The array for the facet's menu entry
488
     */
489
    protected function getFacetsMenuEntry($field, $value, $count, $search, &$state)
490
    {
491
        $entryArray = [];
492
        // Translate value.
493
        if ($field == 'owner_faceting') {
494
            // Translate name of holding library.
495
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->settings['pages']));
496
        } elseif ($field == 'type_faceting') {
497
            // Translate document type.
498
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->settings['pages']));
499
        } elseif ($field == 'collection_faceting') {
500
            // Translate name of collection.
501
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_collections', $this->settings['pages']));
502
        } elseif ($field == 'language_faceting') {
503
            // Translate ISO 639 language code.
504
            $entryArray['title'] = htmlspecialchars(Helper::getLanguageName($value));
505
        } else {
506
            $entryArray['title'] = htmlspecialchars($value);
507
        }
508
        $entryArray['count'] = $count;
509
        $entryArray['doNotLinkIt'] = 0;
510
        // Check if facet is already selected.
511
        $queryColumn = array_column($search['params']['filterquery'], 'query');
512
        $index = array_search($field . ':("' . Solr::escapeQuery($value) . '")', $queryColumn);
513
        if ($index !== false) {
514
            // Facet is selected, thus remove it from filter.
515
            unset($queryColumn[$index]);
516
            $queryColumn = array_values($queryColumn);
517
            $entryArray['ITEM_STATE'] = 'CUR';
518
            $state = 'ACTIFSUB';
519
            //Reset facets
520
            if ($this->settings['resetFacets']) {
521
                //remove ($count) for selected facet in template
522
                $entryArray['count'] = false;
523
                //build link to delete selected facet
524
                $uri = $this->uriBuilder->reset()
525
                    ->setTargetPageUid($GLOBALS['TSFE']->id)
526
                    ->setArguments(['tx_dlf' => ['query' => $search['query'], 'fq' => $queryColumn], 'tx_dlf_search' => ['action' => 'search']])
527
                    ->setAddQueryString(true)
528
                    ->build();
529
                $entryArray['_OVERRIDE_HREF'] = $uri;
530
                $entryArray['title'] = sprintf(LocalizationUtility::translate('search.resetFacet', 'dlf'), $entryArray['title']);
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...rch.resetFacet', 'dlf') can also be of type null; however, parameter $format of sprintf() does only seem to accept string, 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

530
                $entryArray['title'] = sprintf(/** @scrutinizer ignore-type */ LocalizationUtility::translate('search.resetFacet', 'dlf'), $entryArray['title']);
Loading history...
531
            }
532
        } else {
533
            // Facet is not selected, thus add it to filter.
534
            $queryColumn[] = $field . ':("' . Solr::escapeQuery($value) . '")';
535
            $entryArray['ITEM_STATE'] = 'NO';
536
        }
537
        $uri = $this->uriBuilder->reset()
538
            ->setTargetPageUid($GLOBALS['TSFE']->id)
539
            ->setArguments(['tx_dlf' => ['query' => $search['query'], 'fq' => $queryColumn], 'tx_dlf_search' => ['action' => 'search']])
540
            ->setArgumentPrefix('tx_dlf')
541
            ->build();
542
        $entryArray['_OVERRIDE_HREF'] = $uri;
543
544
        return $entryArray;
545
    }
546
547
    /**
548
     * Returns the extended search form and adds the JS files necessary for extended search.
549
     *
550
     * @access protected
551
     *
552
     * @return string The extended search form or an empty string
553
     */
554
    protected function addExtendedSearch()
555
    {
556
        // Quit without doing anything if no fields for extended search are selected.
557
        if (
558
            empty($this->settings['extendedSlotCount'])
559
            || empty($this->settings['extendedFields'])
560
        ) {
561
            return '';
562
        }
563
        // Get operator options.
564
        $operatorOptions = [];
565
        foreach (['AND', 'OR', 'NOT'] as $operator) {
566
            $operatorOptions[$operator] = htmlspecialchars(LocalizationUtility::translate('search.' . $operator, 'dlf'));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...h.' . $operator, 'dlf') can also be of type null; however, parameter $string of htmlspecialchars() does only seem to accept string, 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

566
            $operatorOptions[$operator] = htmlspecialchars(/** @scrutinizer ignore-type */ LocalizationUtility::translate('search.' . $operator, 'dlf'));
Loading history...
567
        }
568
        // Get field selector options.
569
        $fieldSelectorOptions = [];
570
        $searchFields = GeneralUtility::trimExplode(',', $this->settings['extendedFields'], true);
571
        foreach ($searchFields as $searchField) {
572
            $fieldSelectorOptions[$searchField] = Helper::translate($searchField, 'tx_dlf_metadata', $this->settings['pages']);
573
        }
574
        $slotCountArray = [];
575
        for ($i = 0; $i < $this->settings['extendedSlotCount']; $i++) {
576
            $slotCountArray[] = $i;
577
        }
578
579
        $this->view->assign('extendedSlotCount', $slotCountArray);
580
        $this->view->assign('extendedFields', $this->settings['extendedFields']);
581
        $this->view->assign('operators', $operatorOptions);
582
        $this->view->assign('searchFields', $fieldSelectorOptions);
583
    }
584
}
585