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 — master (#329)
by Sebastian
03:28
created

Search::main()   F

Complexity

Conditions 47
Paths 15506

Size

Total Lines 178
Code Lines 118

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 47
eloc 118
nc 15506
nop 2
dl 0
loc 178
rs 0
c 0
b 0
f 0

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
namespace Kitodo\Dlf\Plugins;
3
4
/**
5
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
6
 *
7
 * This file is part of the Kitodo and TYPO3 projects.
8
 *
9
 * @license GNU General Public License version 3 or later.
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 */
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
20
/**
21
 * Plugin 'Search' for the 'dlf' extension
22
 *
23
 * @author Sebastian Meyer <[email protected]>
24
 * @author Henrik Lochmann <[email protected]>
25
 * @author Frank Ulrich Weber <[email protected]>
26
 * @package TYPO3
27
 * @subpackage dlf
28
 * @access public
29
 */
30
class Search extends \Kitodo\Dlf\Common\AbstractPlugin {
31
    public $scriptRelPath = 'Classes/Plugins/Search.php';
32
33
    /**
34
     * Adds the JS files necessary for search suggestions
35
     *
36
     * @access protected
37
     *
38
     * @return void
39
     */
40
    protected function addAutocompleteJS() {
41
        // Check if there are any metadata to suggest.
42
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
43
            'tx_dlf_metadata.*',
44
            'tx_dlf_metadata',
45
            'tx_dlf_metadata.index_autocomplete=1'
46
                .' AND tx_dlf_metadata.pid='.intval($this->conf['pages'])
47
                .Helper::whereClause('tx_dlf_metadata'),
48
            '',
49
            '',
50
            '1'
51
        );
52
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
53
            $GLOBALS['TSFE']->additionalHeaderData[$this->prefixId.'_search_suggest'] = '<script type="text/javascript" src="'.\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey).'Resources/Public/Javascript/Search/Suggester.js"></script>';
54
        } else {
55
            Helper::devLog('No metadata fields configured for search suggestions', DEVLOG_SEVERITY_WARNING);
56
        }
57
    }
58
59
    /**
60
     * Adds the current collection's UID to the search form
61
     *
62
     * @access protected
63
     *
64
     * @return string HTML input fields with current document's UID and parent ID
65
     */
66
    protected function addCurrentCollection() {
67
        // Load current collection.
68
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(DocumentList::class);
69
        if (!empty($list->metadata['options']['source'])
70
            && $list->metadata['options']['source'] == 'collection') {
71
            // Get collection's UID.
72
            return '<input type="hidden" name="'.$this->prefixId.'[collection]" value="'.$list->metadata['options']['select'].'" />';
73
        } elseif (!empty($list->metadata['options']['params']['filterquery'])) {
74
            // Get collection's UID from search metadata.
75
            foreach ($list->metadata['options']['params']['filterquery'] as $facet) {
76
                $facetKeyVal = explode(':', $facet['query'], 2);
77
                if ($facetKeyVal[0] == 'collection_faceting'
78
                    && !strpos($facetKeyVal[1], '" OR "')) {
79
                    $collectionId = Helper::getUidFromIndexName(trim($facetKeyVal[1], '(")'), 'tx_dlf_collections');
80
                }
81
            }
82
            return '<input type="hidden" name="'.$this->prefixId.'[collection]" value="'.$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...
83
        }
84
        return '';
85
    }
86
87
    /**
88
     * Adds the current document's UID or parent ID to the search form
89
     *
90
     * @access protected
91
     *
92
     * @return string HTML input fields with current document's UID and parent ID
93
     */
94
    protected function addCurrentDocument() {
95
        // Load current list object.
96
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(DocumentList::class);
97
        // Load current document.
98
        if (!empty($this->piVars['id'])
99
            && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])) {
100
            $this->loadDocument();
101
            // Get document's UID or parent ID.
102
            if ($this->doc->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
103
                return '<input type="hidden" name="'.$this->prefixId.'[id]" value="'.($this->doc->parentId > 0 ? $this->doc->parentId : $this->doc->uid).'" />';
0 ignored issues
show
Bug Best Practice introduced by
The property $parentId is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
Bug Best Practice introduced by
The property $uid is declared protected in Kitodo\Dlf\Common\Document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
104
            }
105
        } elseif (!empty($list->metadata['options']['params']['filterquery'])) {
106
            // Get document's UID from search metadata.
107
            foreach ($list->metadata['options']['params']['filterquery'] as $facet) {
108
                $facetKeyVal = explode(':', $facet['query']);
109
                if ($facetKeyVal[0] == 'uid') {
110
                    $documentId = (int) substr($facetKeyVal[1], 1, strpos($facetKeyVal[1], ')'));
111
                }
112
            }
113
            return '<input type="hidden" name="'.$this->prefixId.'[id]" value="'.$documentId.'" />';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $documentId does not seem to be defined for all execution paths leading up to this point.
Loading history...
114
        }
115
        return '';
116
    }
117
118
    /**
119
     * Adds the encrypted Solr core name to the search form
120
     *
121
     * @access protected
122
     *
123
     * @return string HTML input fields with encrypted core name and hash
124
     */
125
    protected function addEncryptedCoreName() {
126
        // Get core name.
127
        $name = Helper::getIndexNameFromUid($this->conf['solrcore'], 'tx_dlf_solrcores');
128
        // Encrypt core name.
129
        if (!empty($name)) {
130
            $name = Helper::encrypt($name);
131
        }
132
        // Add encrypted fields to search form.
133
        if (is_array($name)) {
134
            return '<input type="hidden" name="'.$this->prefixId.'[encrypted]" value="'.$name['encrypted'].'" /><input type="hidden" name="'.$this->prefixId.'[hashed]" value="'.$name['hash'].'" />';
135
        } else {
136
            return '';
137
        }
138
    }
139
140
    /**
141
     * Returns the extended search form and adds the JS files necessary for extended search.
142
     *
143
     * @access protected
144
     *
145
     * @return string The extended search form or an empty string
146
     */
147
    protected function addExtendedSearch() {
148
        $extendedSearch = '';
149
        // Quit without doing anything if no fields for extended search are selected.
150
        if (empty($this->conf['extendedSlotCount'])
151
            || empty($this->conf['extendedFields'])) {
152
            return $extendedSearch;
153
        }
154
        // Get operator options.
155
        $operatorOptions = '';
156
        foreach (['AND', 'OR', 'NOT'] as $operator) {
157
            $operatorOptions .= '<option class="tx-dlf-search-operator-option tx-dlf-search-operator-'.$operator.'" value="'.$operator.'">'.$this->pi_getLL($operator, '', TRUE).'</option>';
158
        }
159
        // Get field selector options.
160
        $fieldSelectorOptions = '';
161
        $searchFields = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['extendedFields'], TRUE);
162
        foreach ($searchFields as $searchField) {
163
            $fieldSelectorOptions .= '<option class="tx-dlf-search-field-option tx-dlf-search-field-'.$searchField.'" value="'.$searchField.'">'.Helper::translate($searchField, 'tx_dlf_metadata', $this->conf['pages']).'</option>';
164
        }
165
        for ($i = 0; $i < $this->conf['extendedSlotCount']; $i++) {
166
            $markerArray = [
167
                '###EXT_SEARCH_OPERATOR###' => '<select class="tx-dlf-search-operator tx-dlf-search-operator-'.$i.'" name="'.$this->prefixId.'[extOperator]['.$i.']">'.$operatorOptions.'</select>',
168
                '###EXT_SEARCH_FIELDSELECTOR###' => '<select class="tx-dlf-search-field tx-dlf-search-field-'.$i.'" name="'.$this->prefixId.'[extField]['.$i.']">'.$fieldSelectorOptions.'</select>',
169
                '###EXT_SEARCH_FIELDQUERY###' => '<input class="tx-dlf-search-query tx-dlf-search-query-'.$i.'" type="text" name="'.$this->prefixId.'[extQuery]['.$i.']" />'
170
            ];
171
            $extendedSearch .= $this->cObj->substituteMarkerArray($this->cObj->getSubpart($this->template, '###EXT_SEARCH_ENTRY###'), $markerArray);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Frontend\Conte...substituteMarkerArray() has been deprecated: since TYPO3 v8, will be removed in TYPO3 v9, please use the MarkerBasedTemplateService instead. ( Ignorable by Annotation )

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

171
            $extendedSearch .= /** @scrutinizer ignore-deprecated */ $this->cObj->substituteMarkerArray($this->cObj->getSubpart($this->template, '###EXT_SEARCH_ENTRY###'), $markerArray);

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...
Deprecated Code introduced by
The function TYPO3\CMS\Frontend\Conte...tRenderer::getSubpart() has been deprecated: since TYPO3 v8, will be removed in TYPO3 v9, please use the MarkerBasedTemplateService instead. ( Ignorable by Annotation )

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

171
            $extendedSearch .= $this->cObj->substituteMarkerArray(/** @scrutinizer ignore-deprecated */ $this->cObj->getSubpart($this->template, '###EXT_SEARCH_ENTRY###'), $markerArray);

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...
172
        }
173
        return $extendedSearch;
174
    }
175
176
    /**
177
     * Adds the facets menu to the search form
178
     *
179
     * @access protected
180
     *
181
     * @return string HTML output of facets menu
182
     */
183
    protected function addFacetsMenu() {
184
        // Check for typoscript configuration to prevent fatal error.
185
        if (empty($this->conf['facetsConf.'])) {
186
            Helper::devLog('Incomplete plugin configuration', DEVLOG_SEVERITY_WARNING);
187
            return '';
188
        }
189
        // Quit without doing anything if no facets are selected.
190
        if (empty($this->conf['facets'])) {
191
            return '';
192
        }
193
        // Get facets from plugin configuration.
194
        $facets = [];
195
        foreach (\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['facets'], TRUE) as $facet) {
196
            $facets[$facet.'_faceting'] = Helper::translate($facet, 'tx_dlf_metadata', $this->conf['pages']);
197
        }
198
        // Render facets menu.
199
        $TSconfig = [];
200
        $TSconfig['special'] = 'userfunction';
201
        $TSconfig['special.']['userFunc'] = 'Kitodo\\Dlf\\Plugins\\Search->makeFacetsMenuArray';
202
        $TSconfig['special.']['facets'] = $facets;
203
        $TSconfig['special.']['limit'] = max(intval($this->conf['limitFacets']), 1);
204
        $TSconfig = \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($this->conf['facetsConf.'], $TSconfig);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $TSconfig is correct as TYPO3\CMS\Core\Utility\A...cetsConf.'], $TSconfig) targeting TYPO3\CMS\Core\Utility\A...RecursiveWithOverrule() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
205
        return $this->cObj->HMENU($TSconfig);
0 ignored issues
show
Bug introduced by
The method HMENU() does not exist on TYPO3\CMS\Frontend\Conte...t\ContentObjectRenderer. ( Ignorable by Annotation )

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

205
        return $this->cObj->/** @scrutinizer ignore-call */ HMENU($TSconfig);

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...
206
    }
207
208
    /**
209
     * Adds the fulltext switch to the search form
210
     *
211
     * @access protected
212
     *
213
     * @param integer $isFulltextSearch: Is fulltext search activated?
214
     *
215
     * @return string HTML output of fulltext switch
216
     */
217
    protected function addFulltextSwitch($isFulltextSearch = 0) {
218
        $output = '';
219
        // Check for plugin configuration.
220
        if (!empty($this->conf['fulltext'])) {
221
            $output .= ' <input class="tx-dlf-search-fulltext" id="tx-dlf-search-fulltext-no" type="radio" name="'.$this->prefixId.'[fulltext]" value="0" '.($isFulltextSearch == 0 ? 'checked="checked"' : '').' />';
222
            $output .= ' <label for="tx-dlf-search-fulltext-no">'.$this->pi_getLL('label.inMetadata', '').'</label>';
223
            $output .= ' <input class="tx-dlf-search-fulltext" id="tx-dlf-search-fulltext-yes" type="radio" name="'.$this->prefixId.'[fulltext]" value="1" '.($isFulltextSearch == 1 ? 'checked="checked"' : '').'/>';
224
            $output .= ' <label for="tx-dlf-search-fulltext-yes">'.$this->pi_getLL('label.inFulltext', '').'</label>';
225
        }
226
        return $output;
227
    }
228
229
    /**
230
     * Adds the logical page field to the search form
231
     *
232
     * @access protected
233
     *
234
     * @return string HTML output of logical page field
235
     */
236
    protected function addLogicalPage() {
237
        $output = '';
238
        // Check for plugin configuration.
239
        if (!empty($this->conf['showLogicalPageField'])) {
240
            $output .= ' <label for="tx-dlf-search-logical-page">'.$this->pi_getLL('label.logicalPage', '').': </label>';
241
            $output .= ' <input class="tx-dlf-search-logical-page" id="tx-dlf-search-logical-page" type="text" name="'.$this->prefixId.'[logicalPage]" />';
242
        }
243
        return $output;
244
    }
245
246
    /**
247
     * Creates an array for a HMENU entry of a facet value.
248
     *
249
     * @access protected
250
     *
251
     * @param string $field: The facet's index_name
252
     * @param string $value: The facet's value
253
     * @param integer $count: Number of hits for this facet
254
     * @param array $search: The parameters of the current search query
255
     * @param string &$state: The state of the parent item
256
     *
257
     * @return array The array for the facet's menu entry
258
     */
259
    protected function getFacetsMenuEntry($field, $value, $count, $search, &$state) {
260
        $entryArray = [];
261
        // Translate value.
262
        if ($field == 'owner_faceting') {
263
            // Translate name of holding library.
264
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_libraries', $this->conf['pages']));
265
        } elseif ($field == 'type_faceting') {
266
            // Translate document type.
267
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_structures', $this->conf['pages']));
268
        } elseif ($field == 'collection_faceting') {
269
            // Translate name of collection.
270
            $entryArray['title'] = htmlspecialchars(Helper::translate($value, 'tx_dlf_collections', $this->conf['pages']));
271
        } elseif ($field == 'language_faceting') {
272
            // Translate ISO 639 language code.
273
            $entryArray['title'] = htmlspecialchars(Helper::getLanguageName($value));
274
        } else {
275
            $entryArray['title'] = htmlspecialchars($value);
276
        }
277
        $entryArray['count'] = $count;
278
        $entryArray['doNotLinkIt'] = 0;
279
        // Check if facet is already selected.
280
        $queryColumn = array_column($search['params']['filterquery'], 'query');
281
        $index = array_search($field.':("'.Solr::escapeQuery($value).'")', $queryColumn);
282
        if ($index !== FALSE) {
283
            // Facet is selected, thus remove it from filter.
284
            unset($queryColumn[$index]);
285
            $queryColumn = array_values($queryColumn);
286
            $entryArray['ITEM_STATE'] = 'CUR';
287
            $state = 'ACTIFSUB';
288
            //Reset facets
289
            if ($this->conf['resetFacets']) {
290
                //remove ($count) for selected facet in template
291
                $entryArray['count'] = FALSE;
292
                //build link to delete selected facet
293
                $entryArray['_OVERRIDE_HREF'] = $this->pi_linkTP_keepPIvars_url(['query' => $search['query'], 'fq' => $queryColumn]);
294
                $entryArray['title'] = sprintf($this->pi_getLL('resetFacet', ''), $entryArray['title']);
295
            }
296
        } else {
297
            // Facet is not selected, thus add it to filter.
298
            $queryColumn[] = $field.':("'.Solr::escapeQuery($value).'")';
299
            $entryArray['ITEM_STATE'] = 'NO';
300
        }
301
        $entryArray['_OVERRIDE_HREF'] = $this->pi_linkTP_keepPIvars_url(['query' => $search['query'], 'fq' => $queryColumn]);
302
        return $entryArray;
303
    }
304
305
    /**
306
     * The main method of the PlugIn
307
     *
308
     * @access public
309
     *
310
     * @param string $content: The PlugIn content
311
     * @param array $conf: The PlugIn configuration
312
     *
313
     * @return string The content that is displayed on the website
314
     */
315
    public function main($content, $conf) {
316
        $this->init($conf);
317
        // Disable caching for this plugin.
318
        $this->setCache(FALSE);
319
        // Quit without doing anything if required variables are not set.
320
        if (empty($this->conf['solrcore'])) {
321
            Helper::devLog('Incomplete plugin configuration', DEVLOG_SEVERITY_WARNING);
322
            return $content;
323
        }
324
        if (!isset($this->piVars['query'])
325
            && empty($this->piVars['extQuery'])) {
326
            // Extract query and filter from last search.
327
            $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(DocumentList::class);
328
            if (!empty($list->metadata['searchString'])) {
329
                if ($list->metadata['options']['source'] == 'search') {
330
                    $search['query'] = $list->metadata['searchString'];
1 ignored issue
show
Comprehensibility Best Practice introduced by
$search was never initialized. Although not strictly required by PHP, it is generally a good practice to add $search = array(); before regardless.
Loading history...
331
                }
332
                $search['params'] = $list->metadata['options']['params'];
333
            }
334
            // Add javascript for search suggestions if enabled and jQuery autocompletion is available.
335
            if (!empty($this->conf['suggest'])) {
336
                $this->addAutocompleteJS();
337
            }
338
            // Load template file.
339
            $this->getTemplate();
340
            // Configure @action URL for form.
341
            $linkConf = [
342
                'parameter' => $GLOBALS['TSFE']->id
343
            ];
344
            // Fill markers.
345
            $markerArray = [
346
                '###ACTION_URL###' => $this->cObj->typoLink_URL($linkConf),
347
                '###LABEL_QUERY###' => (!empty($search['query']) ? htmlspecialchars($search['query']) : $this->pi_getLL('label.query')),
348
                '###LABEL_SUBMIT###' => $this->pi_getLL('label.submit'),
349
                '###FIELD_QUERY###' => $this->prefixId.'[query]',
350
                '###QUERY###' => (!empty($search['query']) ? $search['query'] : ''),
351
                '###FULLTEXTSWITCH###' => $this->addFulltextSwitch($list->metadata['fulltextSearch']),
352
                '###FIELD_DOC###' => ($this->conf['searchIn'] == 'document' || $this->conf['searchIn'] == 'all' ? $this->addCurrentDocument() : ''),
353
                '###FIELD_COLL###' => ($this->conf['searchIn'] == 'collection' || $this->conf['searchIn'] == 'all' ? $this->addCurrentCollection() : ''),
354
                '###ADDITIONAL_INPUTS###' => $this->addEncryptedCoreName(),
355
                '###FACETS_MENU###' => $this->addFacetsMenu(),
356
                '###LOGICAL_PAGE###' => $this->addLogicalPage()
357
            ];
358
            // Get additional fields for extended search.
359
            $extendedSearch = $this->addExtendedSearch();
360
            // Display search form.
361
            $content .= $this->cObj->substituteSubpart($this->cObj->substituteMarkerArray($this->template, $markerArray), '###EXT_SEARCH_ENTRY###', $extendedSearch);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Frontend\Conte...substituteMarkerArray() has been deprecated: since TYPO3 v8, will be removed in TYPO3 v9, please use the MarkerBasedTemplateService 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
            $content .= $this->cObj->substituteSubpart(/** @scrutinizer ignore-deprecated */ $this->cObj->substituteMarkerArray($this->template, $markerArray), '###EXT_SEARCH_ENTRY###', $extendedSearch);

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...
Deprecated Code introduced by
The function TYPO3\CMS\Frontend\Conte...er::substituteSubpart() has been deprecated: since TYPO3 v8, will be removed in TYPO3 v9, please use the MarkerBasedTemplateService 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
            $content .= /** @scrutinizer ignore-deprecated */ $this->cObj->substituteSubpart($this->cObj->substituteMarkerArray($this->template, $markerArray), '###EXT_SEARCH_ENTRY###', $extendedSearch);

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
            return $this->pi_wrapInBaseClass($content);
363
        } else {
364
            // Instantiate search object.
365
            $solr = Solr::getInstance($this->conf['solrcore']);
366
            if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
367
                Helper::devLog('Apache Solr not available', DEVLOG_SEVERITY_ERROR);
368
                return $content;
369
            }
370
            // Build label for result list.
371
            $label = $this->pi_getLL('search', '', TRUE);
372
            if (!empty($this->piVars['query'])) {
373
                $label .= htmlspecialchars(sprintf($this->pi_getLL('for', ''), $this->piVars['query']));
374
            }
375
            // Prepare query parameters.
376
            $params = [];
377
            $matches = [];
378
            // Set search query.
379
            if ((!empty($this->conf['fulltext']) && !empty($this->piVars['fulltext']))
380
                || preg_match('/fulltext:\((.*)\)/', $this->piVars['query'], $matches)) {
381
                // If the query already is a fulltext query e.g using the facets
382
                $this->piVars['query'] = empty($matches[1]) ? $this->piVars['query'] : $matches[1];
383
                // Search in fulltext field if applicable. query must not be empty!
384
                if (!empty($this->piVars['query'])) {
385
                    $query = 'fulltext:('.Solr::escapeQuery($this->piVars['query']).')';
386
                }
387
            } else {
388
                // Retain given search field if valid.
389
                $query = Solr::escapeQueryKeepField($this->piVars['query'], $this->conf['pages']);
390
            }
391
            // Add extended search query.
392
            if (!empty($this->piVars['extQuery'])
393
                && is_array($this->piVars['extQuery'])) {
394
                $allowedOperators = ['AND', 'OR', 'NOT'];
395
                $allowedFields = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['extendedFields'], TRUE);
396
                for ($i = 0; $i < count($this->piVars['extQuery']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
397
                    if (!empty($this->piVars['extQuery'][$i])) {
398
                        if (in_array($this->piVars['extOperator'][$i], $allowedOperators)
399
                            && in_array($this->piVars['extField'][$i], $allowedFields)) {
400
                            if (!empty($query)) {
401
                                $query .= ' '.$this->piVars['extOperator'][$i].' ';
402
                            }
403
                            $query .= Indexer::getIndexFieldName($this->piVars['extField'][$i], $this->conf['pages']).':('.Solr::escapeQuery($this->piVars['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...
404
                        }
405
                    }
406
                }
407
            }
408
            // Add filter query for faceting.
409
            if (!empty($this->piVars['fq'])) {
410
                foreach ($this->piVars['fq'] as $filterQuery) {
411
                    $params['filterquery'][]['query'] = $filterQuery;
412
                }
413
            }
414
            // Add filter query for in-document searching.
415
            if ($this->conf['searchIn'] == 'document'
416
                || $this->conf['searchIn'] == 'all') {
417
                if (!empty($this->piVars['id'])
418
                    && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])) {
419
                    $params['filterquery'][]['query'] = 'uid:('.$this->piVars['id'].') OR partof:('.$this->piVars['id'].')';
420
                    $label .= htmlspecialchars(sprintf($this->pi_getLL('in', ''), Document::getTitle($this->piVars['id'])));
421
                }
422
            }
423
            // Add filter query for in-collection searching.
424
            if ($this->conf['searchIn'] == 'collection'
425
                || $this->conf['searchIn'] == 'all') {
426
                if (!empty($this->piVars['collection'])
427
                    && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['collection'])) {
428
                    $index_name = Helper::getIndexNameFromUid($this->piVars['collection'], 'tx_dlf_collections', $this->conf['pages']);
429
                    $params['filterquery'][]['query'] = 'collection_faceting:("'.Solr::escapeQuery($index_name).'")';
430
                    $label .= sprintf($this->pi_getLL('in', '', TRUE), Helper::translate($index_name, 'tx_dlf_collections', $this->conf['pages']));
431
                }
432
            }
433
            // Add filter query for collection restrictions.
434
            if ($this->conf['collections']) {
435
                $collIds = explode(',', $this->conf['collections']);
436
                $collIndexNames = [];
437
                foreach ($collIds as $collId) {
438
                    $collIndexNames[] = Solr::escapeQuery(Helper::getIndexNameFromUid(intval($collId), 'tx_dlf_collections', $this->conf['pages']));
439
                }
440
                // Last value is fake and used for distinction in $this->addCurrentCollection()
441
                $params['filterquery'][]['query'] = 'collection_faceting:("'.implode('" OR "', $collIndexNames).'" OR "FakeValueForDistinction")';
442
            }
443
            // Set some query parameters.
444
            $params['query'] = $query;
445
            $params['start'] = 0;
446
            $params['rows'] = 0;
447
            $params['sort'] = ['score' => 'desc'];
448
            // Instantiate search object.
449
            $solr = Solr::getInstance($this->conf['solrcore']);
450
            if (!$solr->ready) {
451
                Helper::devLog('Apache Solr not available', DEVLOG_SEVERITY_ERROR);
452
                return $content;
453
            }
454
            // Set search parameters.
455
            $solr->cPid = $this->conf['pages'];
0 ignored issues
show
Bug Best Practice introduced by
The property $cPid is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __set, consider adding a @property or @property-write.
Loading history...
456
            $solr->params = $params;
0 ignored issues
show
Bug Best Practice introduced by
The property $params is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __set, consider adding a @property or @property-write.
Loading history...
457
            // Perform search.
458
            $list = $solr->search();
459
            $list->metadata = [
0 ignored issues
show
Bug Best Practice introduced by
The property $metadata is declared protected in Kitodo\Dlf\Common\DocumentList. Since you implement __set, consider adding a @property or @property-write.
Loading history...
460
                'label' => $label,
461
                'thumbnail' => '',
462
                'searchString' => $this->piVars['query'],
463
                'fulltextSearch' => (!empty($this->piVars['fulltext']) ? '1' : '0'),
464
                'options' => $list->metadata['options']
465
            ];
466
            $list->save();
467
            // Clean output buffer.
468
            \TYPO3\CMS\Core\Utility\GeneralUtility::cleanOutputBuffers();
0 ignored issues
show
Bug introduced by
The method cleanOutputBuffers() does not exist on TYPO3\CMS\Core\Utility\GeneralUtility. ( Ignorable by Annotation )

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

468
            \TYPO3\CMS\Core\Utility\GeneralUtility::/** @scrutinizer ignore-call */ 
469
                                                    cleanOutputBuffers();

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...
469
            $additionalParams = [];
470
            if (!empty($this->piVars['logicalPage'])) {
471
                $additionalParams['logicalPage'] = $this->piVars['logicalPage'];
472
            }
473
            // Jump directly to the page view, if there is only one result and it is configured
474
            if ($list->metadata['options']['numberOfHits'] == 1 && !empty($this->conf['showSingleResult'])) {
475
                $linkConf['parameter'] = $this->conf['targetPidPageView'];
1 ignored issue
show
Comprehensibility Best Practice introduced by
$linkConf was never initialized. Although not strictly required by PHP, it is generally a good practice to add $linkConf = array(); before regardless.
Loading history...
476
                $additionalParams['id'] = $list->current()['uid'];
477
                $additionalParams['highlight_word'] = preg_replace('/\s\s+/', ';', $list->metadata['searchString']);
478
                $additionalParams['page'] = count($list[0]['subparts']) == 1 ? $list[0]['subparts'][0]['page'] : 1;
479
            } else {
480
                // Keep some plugin variables.
481
                $linkConf['parameter'] = $this->conf['targetPid'];
482
                if (!empty($this->piVars['order'])) {
483
                    $additionalParams['order'] = $this->piVars['order'];
484
                    $additionalParams['asc'] = !empty($this->piVars['asc']) ? '1' : '0';
485
                }
486
            }
487
            $linkConf['additionalParams'] = \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($this->prefixId, $additionalParams, '', TRUE, FALSE);
488
            // Send headers.
489
            header('Location: '.\TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl($this->cObj->typoLink_URL($linkConf)));
490
            // Flush output buffer and end script processing.
491
            ob_end_flush();
492
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
493
        }
494
    }
495
496
    /**
497
     * This builds a menu array for HMENU
498
     *
499
     * @access public
500
     *
501
     * @param string $content: The PlugIn content
502
     * @param array $conf: The PlugIn configuration
503
     *
504
     * @return array HMENU array
505
     */
506
    public function makeFacetsMenuArray($content, $conf) {
1 ignored issue
show
Unused Code introduced by
The parameter $content is not used and could be removed. ( Ignorable by Annotation )

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

506
    public function makeFacetsMenuArray(/** @scrutinizer ignore-unused */ $content, $conf) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
507
        $this->init($conf);
508
        $menuArray = [];
509
        // Set default value for facet search.
510
        $search = [
511
            'query' => '*',
512
            'params' => [
513
                'component' => [
514
                    'facetset' => [
515
                        'facet' => []
516
                    ]
517
                ]
518
            ]
519
        ];
520
        // Extract query and filter from last search.
521
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(DocumentList::class);
522
        if (!empty($list->metadata['options']['source'])) {
523
            if ($list->metadata['options']['source'] == 'search') {
524
                $search['query'] = $list->metadata['options']['select'];
525
            }
526
            $search['params'] = $list->metadata['options']['params'];
527
        }
528
        // Get applicable facets.
529
        $solr = Solr::getInstance($this->conf['solrcore']);
530
        if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
531
            Helper::devLog('Apache Solr not available', DEVLOG_SEVERITY_ERROR);
532
            return [];
533
        }
534
        // Set needed parameters for facet search.
535
        if (empty($search['params']['filterquery'])) {
536
            $search['params']['filterquery'] = [];
537
        }
538
        foreach (array_keys($this->conf['facets']) as $field) {
539
            $search['params']['component']['facetset']['facet'][] = [
540
                'type' => 'field',
541
                'key' => $field,
542
                'field' => $field,
543
                'limit' => $this->conf['limitFacets'],
544
                'sort' => isset($this->conf['sortingFacets']) ? $this->conf['sortingFacets'] : 'count'
545
            ];
546
        }
547
        // Set additional query parameters.
548
        $search['params']['start'] = 0;
549
        $search['params']['rows'] = 0;
550
        // Set query.
551
        $search['params']['query'] = $search['query'];
552
        // Perform search.
553
        $selectQuery = $solr->service->createSelect($search['params']);
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in Kitodo\Dlf\Common\Solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
554
        $results = $solr->service->select($selectQuery);
555
        $facet = $results->getFacetSet();
556
        // Process results.
557
        foreach ($facet as $field => $values) {
558
            $entryArray = [];
559
            $entryArray['title'] = htmlspecialchars($this->conf['facets'][$field]);
560
            $entryArray['count'] = 0;
561
            $entryArray['_OVERRIDE_HREF'] = '';
562
            $entryArray['doNotLinkIt'] = 1;
563
            $entryArray['ITEM_STATE'] = 'NO';
564
            // Count number of facet values.
565
            $i = 0;
566
            foreach ($values as $value => $count) {
567
                if ($count > 0) {
568
                    $entryArray['count']++;
569
                    if ($entryArray['ITEM_STATE'] == 'NO') {
570
                        $entryArray['ITEM_STATE'] = 'IFSUB';
571
                    }
572
                    $entryArray['_SUB_MENU'][] = $this->getFacetsMenuEntry($field, $value, $count, $search, $entryArray['ITEM_STATE']);
573
                    if (++$i == $this->conf['limit']) {
574
                        break;
575
                    }
576
                } else {
577
                    break;
578
                }
579
            }
580
            $menuArray[] = $entryArray;
581
        }
582
        return $menuArray;
583
    }
584
}
585