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
Push — master ( 118576...18bf9c )
by Sebastian
14:55
created

tx_dlf_search   F

Complexity

Total Complexity 104

Size/Duplication

Total Lines 822
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 822
rs 1.263
c 1
b 0
f 0
wmc 104

11 Methods

Rating   Name   Duplication   Size   Complexity  
C getFacetsMenuEntry() 0 70 7
A addLogicalPage() 0 14 2
A addEncryptedCoreName() 0 20 3
B addFacetsMenu() 0 45 5
B addExtendedSearch() 0 44 6
A addFulltextSwitch() 0 18 4
C addCurrentCollection() 0 30 7
C addCurrentDocument() 0 37 8
C makeFacetsMenuArray() 0 112 11
F main() 0 280 48
A addAutocompleteJS() 0 21 3

How to fix   Complexity   

Complex Class

Complex classes like tx_dlf_search 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 tx_dlf_search, 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
/**
13
 * Plugin 'DLF: Search' for the 'dlf' extension.
14
 *
15
 * @author	Sebastian Meyer <[email protected]>
16
 * @author	Henrik Lochmann <[email protected]>
17
 * @package	TYPO3
18
 * @subpackage	tx_dlf
19
 * @access	public
20
 */
21
class tx_dlf_search extends tx_dlf_plugin {
22
23
    public $scriptRelPath = 'plugins/search/class.tx_dlf_search.php';
24
25
    /**
26
     * Adds the JS files necessary for search suggestions
27
     *
28
     * @access	protected
29
     *
30
     * @return	void
31
     */
32
    protected function addAutocompleteJS() {
33
34
        // Check if there are any metadata to suggest.
35
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
36
            'tx_dlf_metadata.*',
37
            'tx_dlf_metadata',
38
            'tx_dlf_metadata.index_autocomplete=1 AND tx_dlf_metadata.pid='.intval($this->conf['pages']).tx_dlf_helper::whereClause('tx_dlf_metadata'),
39
            '',
40
            '',
41
            '1'
42
        );
43
44
        if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
45
46
            $GLOBALS['TSFE']->additionalHeaderData[$this->prefixId.'_search_suggest'] = '<script type="text/javascript" src="'.\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey).'plugins/search/tx_dlf_search_suggest.js"></script>';
47
48
        } else {
49
50
            if (TYPO3_DLOG) {
51
52
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_search->addAutocompleteJS()] No metadata fields configured for search suggestions', $this->extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
53
54
            }
55
56
        }
57
58
    }
59
60
    /**
61
     * Adds the current collection's UID to the search form
62
     *
63
     * @access	protected
64
     *
65
     * @return	string		HTML input fields with current document's UID and parent ID
66
     */
67
    protected function addCurrentCollection() {
68
69
        // Load current collection.
70
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_dlf_list');
71
72
        if (!empty($list->metadata['options']['source']) && $list->metadata['options']['source'] == 'collection') {
73
74
            // Get collection's UID.
75
            return '<input type="hidden" name="'.$this->prefixId.'[collection]" value="'.$list->metadata['options']['select'].'" />';
76
77
        } elseif (!empty($list->metadata['options']['params']['fq'])) {
78
79
            // Get collection's UID from search metadata.
80
            foreach ($list->metadata['options']['params']['fq'] as $id => $facet) {
81
82
                $facetKeyVal = explode(':', $facet, 2);
83
84
                if ($facetKeyVal[0] == 'collection_faceting' && !strpos($facetKeyVal[1], '" OR "')) {
85
86
                    $collectionId = tx_dlf_helper::getIdFromIndexName(trim($facetKeyVal[1], '(")'), 'tx_dlf_collections');
87
88
                }
89
90
            }
91
92
            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...
93
94
        }
95
96
        return '';
97
98
    }
99
100
    /**
101
     * Adds the current document's UID or parent ID to the search form
102
     *
103
     * @access	protected
104
     *
105
     * @return	string		HTML input fields with current document's UID and parent ID
106
     */
107
    protected function addCurrentDocument() {
108
109
        // Load current list object.
110
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_dlf_list');
111
112
        // Load current document.
113
        if (!empty($this->piVars['id']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])) {
114
115
            $this->loadDocument();
116
117
            // Get document's UID or parent ID.
118
            if ($this->doc->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in tx_dlf_document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
119
120
                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 $uid is declared protected in tx_dlf_document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
Bug Best Practice introduced by
The property $parentId is declared protected in tx_dlf_document. Since you implement __get, consider adding a @property or @property-read.
Loading history...
121
122
            }
123
124
        } elseif (!empty($list->metadata['options']['params']['fq'])) {
125
126
            // Get document's UID from search metadata.
127
            foreach ($list->metadata['options']['params']['fq'] as $id => $facet) {
128
129
                $facetKeyVal = explode(':', $facet);
130
131
                if ($facetKeyVal[0] == 'uid') {
132
133
                    $documentId = (int) substr($facetKeyVal[1], 1, strpos($facetKeyVal[1], ')'));
134
135
                }
136
137
            }
138
139
            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...
140
141
        }
142
143
        return '';
144
145
    }
146
147
    /**
148
     * Adds the encrypted Solr core name to the search form
149
     *
150
     * @access	protected
151
     *
152
     * @return	string		HTML input fields with encrypted core name and hash
153
     */
154
    protected function addEncryptedCoreName() {
155
156
        // Get core name.
157
        $name = tx_dlf_helper::getIndexName($this->conf['solrcore'], 'tx_dlf_solrcores');
158
159
        // Encrypt core name.
160
        if (!empty($name)) {
161
162
            $name = tx_dlf_helper::encrypt($name);
163
164
        }
165
166
        // Add encrypted fields to search form.
167
        if (is_array($name)) {
168
169
            return '<input type="hidden" name="'.$this->prefixId.'[encrypted]" value="'.$name['encrypted'].'" /><input type="hidden" name="'.$this->prefixId.'[hashed]" value="'.$name['hash'].'" />';
170
171
        } else {
172
173
            return '';
174
175
        }
176
177
    }
178
179
    /**
180
     * Returns the extended search form and adds the JS files necessary for extended search.
181
     *
182
     * @access	protected
183
     *
184
     * @return	string		The extended search form or an empty string
185
     */
186
    protected function addExtendedSearch() {
187
188
        $extendedSearch = '';
189
190
        // Quit without doing anything if no fields for extended search are selected.
191
        if (empty($this->conf['extendedSlotCount']) || empty($this->conf['extendedFields'])) {
192
193
            return $extendedSearch;
194
195
        }
196
197
        // Get operator options.
198
        $operatorOptions = '';
199
200
        foreach (array ('AND', 'OR', 'NOT') as $operator) {
201
202
            $operatorOptions .= '<option class="tx-dlf-search-operator-option tx-dlf-search-operator-'.$operator.'" value="'.$operator.'">'.$this->pi_getLL($operator, '', TRUE).'</option>';
203
204
        }
205
206
        // Get field selector options.
207
        $fieldSelectorOptions = '';
208
209
        $searchFields = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['extendedFields'], TRUE);
210
211
        foreach ($searchFields as $searchField) {
212
213
            $fieldSelectorOptions .= '<option class="tx-dlf-search-field-option tx-dlf-search-field-'.$searchField.'" value="'.$searchField.'">'.tx_dlf_helper::translate($searchField, 'tx_dlf_metadata', $this->conf['pages']).'</option>';
214
215
        }
216
217
        for ($i = 0; $i < $this->conf['extendedSlotCount']; $i++) {
218
219
            $markerArray = array (
220
                '###EXT_SEARCH_OPERATOR###' => '<select class="tx-dlf-search-operator tx-dlf-search-operator-'.$i.'" name="'.$this->prefixId.'[extOperator]['.$i.']">'.$operatorOptions.'</select>',
221
                '###EXT_SEARCH_FIELDSELECTOR###' => '<select class="tx-dlf-search-field tx-dlf-search-field-'.$i.'" name="'.$this->prefixId.'[extField]['.$i.']">'.$fieldSelectorOptions.'</select>',
222
                '###EXT_SEARCH_FIELDQUERY###' => '<input class="tx-dlf-search-query tx-dlf-search-query-'.$i.'" type="text" name="'.$this->prefixId.'[extQuery]['.$i.']" />'
223
            );
224
225
            $extendedSearch .= $this->cObj->substituteMarkerArray($this->cObj->getSubpart($this->template, '###EXT_SEARCH_ENTRY###'), $markerArray);
226
227
        }
228
229
        return $extendedSearch;
230
231
    }
232
233
    /**
234
     * Adds the facets menu to the search form
235
     *
236
     * @access	protected
237
     *
238
     * @return	string		HTML output of facets menu
239
     */
240
    protected function addFacetsMenu() {
241
242
        // Check for typoscript configuration to prevent fatal error.
243
        if (empty($this->conf['facetsConf.'])) {
244
245
            if (TYPO3_DLOG) {
246
247
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_search->addFacetsMenu()] Incomplete plugin configuration', $this->extKey, SYSLOG_SEVERITY_WARNING);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
248
249
            }
250
251
            return '';
252
253
        }
254
255
        // Quit without doing anything if no facets are selected.
256
        if (empty($this->conf['facets'])) {
257
258
            return '';
259
260
        }
261
262
        // Get facets from plugin configuration.
263
        $facets = array ();
264
265
        foreach (\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['facets'], TRUE) as $facet) {
266
267
            $facets[$facet.'_faceting'] = tx_dlf_helper::translate($facet, 'tx_dlf_metadata', $this->conf['pages']);
268
269
        }
270
271
        // Render facets menu.
272
        $TSconfig = array ();
273
274
        $TSconfig['special'] = 'userfunction';
275
276
        $TSconfig['special.']['userFunc'] = 'tx_dlf_search->makeFacetsMenuArray';
277
278
        $TSconfig['special.']['facets'] = $facets;
279
280
        $TSconfig['special.']['limit'] = max(intval($this->conf['limitFacets']), 1);
281
282
        $TSconfig = tx_dlf_helper::array_merge_recursive_overrule($this->conf['facetsConf.'], $TSconfig);
283
284
        return $this->cObj->HMENU($TSconfig);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Frontend\Conte...ObjectRenderer::HMENU() has been deprecated: since TYPO3 CMS 7, will be removed with TYPO3 CMS 8, use $cObj->cObjGetSingle('HMENU', $conf) instead ( Ignorable by Annotation )

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

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

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...
285
286
    }
287
288
    /**
289
     * Adds the fulltext switch to the search form
290
     *
291
     * @access	protected
292
     *
293
     * @param int $isFulltextSearch
294
     *
295
     * @return	string		HTML output of fulltext switch
296
     */
297
    protected function addFulltextSwitch($isFulltextSearch = 0) {
298
299
        $output = '';
300
301
        // Check for plugin configuration.
302
        if (!empty($this->conf['fulltext'])) {
303
304
            $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"' : '').' />';
305
306
            $output .= ' <label for="tx-dlf-search-fulltext-no">'.$this->pi_getLL('label.inMetadata', '').'</label>';
307
308
            $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"' : '').'/>';
309
310
            $output .= ' <label for="tx-dlf-search-fulltext-yes">'.$this->pi_getLL('label.inFulltext', '').'</label>';
311
312
        }
313
314
        return $output;
315
316
    }
317
318
    /**
319
     * Adds the logical page field to the search form
320
     *
321
     * @access	protected
322
     *
323
     * @return	string		HTML output of logical page field
324
     */
325
    protected function addLogicalPage() {
326
327
        $output = '';
328
329
        // Check for plugin configuration.
330
        if (!empty($this->conf['showLogicalPageField'])) {
331
332
            $output .= ' <label for="tx-dlf-search-logical-page">'.$this->pi_getLL('label.logicalPage', '').': </label>';
333
334
            $output .= ' <input class="tx-dlf-search-logical-page" id="tx-dlf-search-logical-page" type="text" name="'.$this->prefixId.'[logicalPage]" />';
335
336
        }
337
338
        return $output;
339
340
    }
341
342
    /**
343
     * Creates an array for a HMENU entry of a facet value.
344
     *
345
     * @param	string		$field: The facet's index_name
346
     * @param	string		$value: The facet's value
347
     * @param	integer		$count: Number of hits for this facet
348
     * @param	array		$search: The parameters of the current search query
349
     * @param	string		&$state: The state of the parent item
350
     *
351
     * @return	array		The array for the facet's menu entry
352
     */
353
    protected function getFacetsMenuEntry($field, $value, $count, $search, &$state) {
354
355
        $entryArray = array ();
356
357
        // Translate value.
358
        if ($field == 'owner_faceting') {
359
360
            // Translate name of holding library.
361
            $entryArray['title'] = htmlspecialchars(tx_dlf_helper::translate($value, 'tx_dlf_libraries', $this->conf['pages']));
362
363
        } elseif ($field == 'type_faceting') {
364
365
            // Translate document type.
366
            $entryArray['title'] = htmlspecialchars(tx_dlf_helper::translate($value, 'tx_dlf_structures', $this->conf['pages']));
367
368
        } elseif ($field == 'collection_faceting') {
369
370
            // Translate name of collection.
371
            $entryArray['title'] = htmlspecialchars(tx_dlf_helper::translate($value, 'tx_dlf_collections', $this->conf['pages']));
372
373
        } elseif ($field == 'language_faceting') {
374
375
            // Translate ISO 639 language code.
376
            $entryArray['title'] = htmlspecialchars(tx_dlf_helper::getLanguageName($value));
377
378
        } else {
379
380
            $entryArray['title'] = htmlspecialchars($value);
381
382
        }
383
384
        $entryArray['count'] = $count;
385
386
        $entryArray['doNotLinkIt'] = 0;
387
388
        // Check if facet is already selected.
389
        $index = array_search($field.':("'.tx_dlf_solr::escapeQuery($value).'")', $search['params']['fq']);
390
391
        if ($index !== FALSE) {
392
393
            // Facet is selected, thus remove it from filter.
394
            unset($search['params']['fq'][$index]);
395
396
            $search['params']['fq'] = array_values($search['params']['fq']);
397
398
            $entryArray['ITEM_STATE'] = 'CUR';
399
400
            $state = 'ACTIFSUB';
401
402
            //Reset facets
403
            if ($this->conf['resetFacets']) {
404
                //remove ($count) for selected facet in template
405
                $entryArray['count'] = FALSE;
406
                //build link to delete selected facet
407
                $entryArray['_OVERRIDE_HREF'] = $this->pi_linkTP_keepPIvars_url(array ('query' => $search['query'], 'fq' => $search['params']['fq']));
408
                $entryArray['title'] = sprintf($this->pi_getLL('resetFacet', ''), $entryArray['title']);
409
            }
410
411
        } else {
412
413
            // Facet is not selected, thus add it to filter.
414
            $search['params']['fq'][] = $field.':("'.tx_dlf_solr::escapeQuery($value).'")';
415
416
            $entryArray['ITEM_STATE'] = 'NO';
417
418
        }
419
420
        $entryArray['_OVERRIDE_HREF'] = $this->pi_linkTP_keepPIvars_url(array ('query' => $search['query'], 'fq' => $search['params']['fq']));
421
422
        return $entryArray;
423
424
    }
425
426
    /**
427
     * The main method of the PlugIn
428
     *
429
     * @access	public
430
     *
431
     * @param	string		$content: The PlugIn content
432
     * @param	array		$conf: The PlugIn configuration
433
     *
434
     * @return	string		The content that is displayed on the website
435
     */
436
    public function main($content, $conf) {
437
438
        $this->init($conf);
439
440
        // Disable caching for this plugin.
441
        $this->setCache(FALSE);
442
443
        // Quit without doing anything if required variables are not set.
444
        if (empty($this->conf['solrcore'])) {
445
446
            if (TYPO3_DLOG) {
447
448
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_search->main('.$content.', [data])] Incomplete plugin configuration', $this->extKey, SYSLOG_SEVERITY_WARNING, $conf);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
449
450
            }
451
452
            return $content;
453
454
        }
455
456
        if (!isset($this->piVars['query']) && empty($this->piVars['extQuery'])) {
457
458
            // Extract query and filter from last search.
459
            $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_dlf_list');
460
461
            if (!empty($list->metadata['searchString'])) {
462
463
                if ($list->metadata['options']['source'] == 'search') {
464
465
                    $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...
466
467
                }
468
469
                $search['params'] = $list->metadata['options']['params'];
470
471
            }
472
473
            // Add javascript for search suggestions if enabled and jQuery autocompletion is available.
474
            if (!empty($this->conf['suggest'])) {
475
476
                $this->addAutocompleteJS();
477
478
            }
479
480
            // Load template file.
481
            if (!empty($this->conf['templateFile'])) {
482
483
                $this->template = $this->cObj->getSubpart($this->cObj->fileResource($this->conf['templateFile']), '###TEMPLATE###');
484
485
            } else {
486
487
                $this->template = $this->cObj->getSubpart($this->cObj->fileResource('EXT:dlf/plugins/search/template.tmpl'), '###TEMPLATE###');
488
489
            }
490
491
            // Configure @action URL for form.
492
            $linkConf = array (
493
                'parameter' => $GLOBALS['TSFE']->id,
494
                'forceAbsoluteUrl' => 1
495
            );
496
497
            // Fill markers.
498
            $markerArray = array (
499
                '###ACTION_URL###' => $this->cObj->typoLink_URL($linkConf),
500
                '###LABEL_QUERY###' => (!empty($search['query']) ? $search['query'] : $this->pi_getLL('label.query')),
501
                '###LABEL_SUBMIT###' => $this->pi_getLL('label.submit'),
502
                '###FIELD_QUERY###' => $this->prefixId.'[query]',
503
                '###QUERY###' => (!empty($search['query']) ? $search['query'] : ''),
504
                '###FULLTEXTSWITCH###' => $this->addFulltextSwitch($list->metadata['fulltextSearch']),
505
                '###FIELD_DOC###' => ($this->conf['searchIn'] == 'document' || $this->conf['searchIn'] == 'all' ? $this->addCurrentDocument() : ''),
506
                '###FIELD_COLL###' => ($this->conf['searchIn'] == 'collection' || $this->conf['searchIn'] == 'all' ? $this->addCurrentCollection() : ''),
507
                '###ADDITIONAL_INPUTS###' => $this->addEncryptedCoreName(),
508
                '###FACETS_MENU###' => $this->addFacetsMenu(),
509
                '###LOGICAL_PAGE###' => $this->addLogicalPage()
510
            );
511
512
            // Get additional fields for extended search.
513
            $extendedSearch = $this->addExtendedSearch();
514
515
            // Display search form.
516
            $content .= $this->cObj->substituteSubpart($this->cObj->substituteMarkerArray($this->template, $markerArray), '###EXT_SEARCH_ENTRY###', $extendedSearch);
517
518
            return $this->pi_wrapInBaseClass($content);
519
520
        } else {
521
522
            // Instantiate search object.
523
            $solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
524
525
            if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in tx_dlf_solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
526
527
                if (TYPO3_DLOG) {
528
529
                    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_search->main('.$content.', [data])] Apache Solr not available', $this->extKey, SYSLOG_SEVERITY_ERROR, $conf);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
530
531
                }
532
533
                return $content;
534
535
            }
536
537
            // Build label for result list.
538
            $label = $this->pi_getLL('search', '', TRUE);
539
540
            if (!empty($this->piVars['query'])) {
541
542
                $label .= htmlspecialchars(sprintf($this->pi_getLL('for', ''), $this->piVars['query']));
543
544
            }
545
546
            // Prepare query parameters.
547
            $params = array ();
548
549
            $matches = array ();
550
551
            // Set search query.
552
            if ((!empty($this->conf['fulltext']) && !empty($this->piVars['fulltext'])) || preg_match('/fulltext:\((.*)\)/', $this->piVars['query'], $matches)) {
553
554
                // If the query already is a fulltext query e.g using the facets
555
                $this->piVars['query'] = empty($matches[1]) ? $this->piVars['query'] : $matches[1];
556
557
                // Search in fulltext field if applicable. query must not be empty!
558
                if (!empty($this->piVars['query'])) {
559
560
                    $query = 'fulltext:('.tx_dlf_solr::escapeQuery($this->piVars['query']).')';
561
562
                }
563
564
            } else {
565
                // Retain given search field if valid.
566
                $query = tx_dlf_solr::escapeQueryKeepField($this->piVars['query'], $this->conf['pages']);
567
568
            }
569
570
            // Add extended search query.
571
            if (!empty($this->piVars['extQuery']) && is_array($this->piVars['extQuery'])) {
572
573
                $allowedOperators = array ('AND', 'OR', 'NOT');
574
575
                $allowedFields = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['extendedFields'], TRUE);
576
577
                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...
578
579
                    if (!empty($this->piVars['extQuery'][$i])) {
580
581
                        if (in_array($this->piVars['extOperator'][$i], $allowedOperators) && in_array($this->piVars['extField'][$i], $allowedFields)) {
582
583
                            if (!empty($query)) {
584
585
                                $query .= ' '.$this->piVars['extOperator'][$i].' ';
586
587
                            }
588
589
                            $query .= tx_dlf_indexing::getIndexFieldName($this->piVars['extField'][$i], $this->conf['pages']).':('.tx_dlf_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...
590
591
                        }
592
593
                    }
594
595
                }
596
597
            }
598
599
            // Add filter query for faceting.
600
            if (!empty($this->piVars['fq'])) {
601
602
                $params['fq'] = $this->piVars['fq'];
603
604
            }
605
606
            // Add filter query for in-document searching.
607
            if ($this->conf['searchIn'] == 'document' || $this->conf['searchIn'] == 'all') {
608
609
                if (!empty($this->piVars['id']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['id'])) {
610
611
                    $params['fq'][] = 'uid:('.$this->piVars['id'].') OR partof:('.$this->piVars['id'].')';
612
613
                    $label .= htmlspecialchars(sprintf($this->pi_getLL('in', ''), tx_dlf_document::getTitle($this->piVars['id'])));
614
615
                }
616
617
            }
618
619
            // Add filter query for in-collection searching.
620
            if ($this->conf['searchIn'] == 'collection' || $this->conf['searchIn'] == 'all') {
621
622
                if (!empty($this->piVars['collection']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->piVars['collection'])) {
623
624
                    $index_name = tx_dlf_helper::getIndexName($this->piVars['collection'], 'tx_dlf_collections', $this->conf['pages']);
625
626
                    $params['fq'][] = 'collection_faceting:("'.tx_dlf_solr::escapeQuery($index_name).'")';
627
628
                    $label .= sprintf($this->pi_getLL('in', '', TRUE), tx_dlf_helper::translate($index_name, 'tx_dlf_collections', $this->conf['pages']));
629
630
                }
631
632
            }
633
634
            // Add filter query for collection restrictions.
635
            if ($this->conf['collections']) {
636
637
                $collIds = explode(',', $this->conf['collections']);
638
639
                $collIndexNames = array ();
640
641
                foreach ($collIds as $collId) {
642
643
                    $collIndexNames[] = tx_dlf_solr::escapeQuery(tx_dlf_helper::getIndexName(intval($collId), 'tx_dlf_collections', $this->conf['pages']));
644
645
                }
646
647
                // Last value is fake and used for distinction in $this->addCurrentCollection()
648
                $params['fq'][] = 'collection_faceting:("'.implode('" OR "', $collIndexNames).'" OR "FakeValueForDistinction")';
649
650
            }
651
652
            // Set search parameters.
653
            $solr->limit = max(intval($this->conf['limit']), 1);
0 ignored issues
show
Bug Best Practice introduced by
The property $limit is declared protected in tx_dlf_solr. Since you implement __set, consider adding a @property or @property-write.
Loading history...
654
655
            $solr->cPid = $this->conf['pages'];
0 ignored issues
show
Bug Best Practice introduced by
The property $cPid is declared protected in tx_dlf_solr. Since you implement __set, consider adding a @property or @property-write.
Loading history...
656
657
            $solr->params = $params;
0 ignored issues
show
Bug Best Practice introduced by
The property $params is declared protected in tx_dlf_solr. Since you implement __set, consider adding a @property or @property-write.
Loading history...
658
659
            // Perform search.
660
            $results = $solr->search($query);
661
662
            $results->metadata = array (
0 ignored issues
show
Bug Best Practice introduced by
The property $metadata is declared protected in tx_dlf_list. Since you implement __set, consider adding a @property or @property-write.
Loading history...
663
                'label' => $label,
664
                'description' => '<p class="tx-dlf-search-numHits">'.htmlspecialchars(sprintf($this->pi_getLL('hits', ''), $solr->numberOfHits, count($results))).'</p>',
0 ignored issues
show
Bug Best Practice introduced by
The property $numberOfHits is declared protected in tx_dlf_solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
665
                'thumbnail' => '',
666
                'searchString' => $this->piVars['query'],
667
                'fulltextSearch' => (!empty($this->piVars['fulltext']) ? '1' : '0'),
668
                'options' => $results->metadata['options']
669
            );
670
671
            $results->save();
672
673
            // Clean output buffer.
674
            \TYPO3\CMS\Core\Utility\GeneralUtility::cleanOutputBuffers();
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Core\Utility\G...y::cleanOutputBuffers() has been deprecated: since TYPO3 CMS 7, will be removed in CMS 8, use ob_* functions directly or self::flushOutputBuffers ( Ignorable by Annotation )

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

674
            /** @scrutinizer ignore-deprecated */ \TYPO3\CMS\Core\Utility\GeneralUtility::cleanOutputBuffers();

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...
675
676
            $additionalParams = array ();
677
678
            if (!empty($this->piVars['logicalPage'])) {
679
680
                $additionalParams['logicalPage'] = $this->piVars['logicalPage'];
681
682
            }
683
684
            // Jump directly to the page view, if there is only one result and it is configured
685
            if ($results->count() == 1 && !empty($this->conf['showSingleResult'])) {
686
687
                $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...
688
689
                $additionalParams['id'] = $results->current()['uid'];
690
                $additionalParams['highlight_word'] = preg_replace('/\s\s+/', ';', $results->metadata['searchString']);
691
                $additionalParams['page'] = count($results[0]['subparts']) == 1 ? $results[0]['subparts'][0]['page'] : 1;
692
693
            } else {
694
695
                // Keep some plugin variables.
696
                $linkConf['parameter'] = $this->conf['targetPid'];
697
698
                if (!empty($this->piVars['order'])) {
699
700
                    $additionalParams['order'] = $this->piVars['order'];
701
                    $additionalParams['asc'] = !empty($this->piVars['asc']) ? '1' : '0';
702
703
                }
704
705
            }
706
707
            $linkConf['additionalParams'] = \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($this->prefixId, $additionalParams, '', TRUE, FALSE);
708
709
            // Send headers.
710
            header('Location: '.\TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl($this->cObj->typoLink_URL($linkConf)));
711
712
            // Flush output buffer and end script processing.
713
            ob_end_flush();
714
715
            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...
716
717
        }
718
719
    }
720
721
    /**
722
     * This builds a menu array for HMENU
723
     *
724
     * @access	public
725
     *
726
     * @param	string		$content: The PlugIn content
727
     * @param	array		$conf: The PlugIn configuration
728
     *
729
     * @return	array		HMENU array
730
     */
731
    public function makeFacetsMenuArray($content, $conf) {
732
733
        $this->init($conf);
734
735
        $menuArray = array ();
736
737
        // Set default value for facet search.
738
        $search = array (
739
            'query' => '*',
740
            'params' => array ()
741
        );
742
743
        // Extract query and filter from last search.
744
        $list = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_dlf_list');
745
746
        if (!empty($list->metadata['options']['source'])) {
747
748
            if ($list->metadata['options']['source'] == 'search') {
749
750
                $search['query'] = $list->metadata['options']['select'];
751
752
            }
753
754
            $search['params'] = $list->metadata['options']['params'];
755
756
        }
757
758
        // Get applicable facets.
759
        $solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
760
761
        if (!$solr->ready) {
0 ignored issues
show
Bug Best Practice introduced by
The property $ready is declared protected in tx_dlf_solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
762
763
            if (TYPO3_DLOG) {
764
765
                \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[tx_dlf_search->makeFacetsMenuArray('.$content.', [data])] Apache Solr not available', $this->extKey, SYSLOG_SEVERITY_ERROR, $conf);
0 ignored issues
show
Bug introduced by
The constant SYSLOG_SEVERITY_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
766
767
            }
768
769
            return array ();
770
771
        }
772
773
        // Set needed parameters for facet search.
774
        if (empty($search['params']['fq'])) {
775
776
            $search['params']['fq'] = array ();
777
778
        }
779
780
        $search['params']['facet'] = 'true';
781
782
        $search['params']['facet.field'] = array_keys($this->conf['facets']);
783
784
        //override SOLR default value for facet.limit of 100
785
        $search['params']['facet.limit'] = $this->conf['limitFacets'];
786
787
        // Perform search.
788
        $results = $solr->service->search($search['query'], 0, 0, $search['params']);
0 ignored issues
show
Bug Best Practice introduced by
The property $service is declared protected in tx_dlf_solr. Since you implement __get, consider adding a @property or @property-read.
Loading history...
789
790
        // Process results.
791
        foreach ($results->facet_counts->facet_fields as $field => $values) {
792
793
            $entryArray = array ();
794
795
            $entryArray['title'] = htmlspecialchars($this->conf['facets'][$field]);
796
797
            $entryArray['count'] = 0;
798
799
            $entryArray['_OVERRIDE_HREF'] = '';
800
801
            $entryArray['doNotLinkIt'] = 1;
802
803
            $entryArray['ITEM_STATE'] = 'NO';
804
805
            // Count number of facet values.
806
            $i = 0;
807
808
            foreach ($values as $value => $count) {
809
810
                if ($count > 0) {
811
812
                    $hasValue = TRUE;
0 ignored issues
show
Unused Code introduced by
The assignment to $hasValue is dead and can be removed.
Loading history...
813
814
                    $entryArray['count']++;
815
816
                    if ($entryArray['ITEM_STATE'] == 'NO') {
817
818
                        $entryArray['ITEM_STATE'] = 'IFSUB';
819
820
                    }
821
822
                    $entryArray['_SUB_MENU'][] = $this->getFacetsMenuEntry($field, $value, $count, $search, $entryArray['ITEM_STATE']);
823
824
                    if (++$i == $this->conf['limit']) {
825
826
                        break;
827
828
                    }
829
830
                } else {
831
832
                    break;
833
834
                }
835
836
            }
837
838
            $menuArray[] = $entryArray;
839
840
        }
841
842
        return $menuArray;
843
844
    }
845
846
}
847