Passed
Push — master ( 4a0c05...84842d )
by Rafael
137:02 queued 134:07
created

SearchFormViewHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.0156

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 4
cp 0.75
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1.0156
1
<?php
2
namespace ApacheSolrForTypo3\Solr\ViewHelpers;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use ApacheSolrForTypo3\Solr\System\Url\UrlHelper;
18
use ApacheSolrForTypo3\Solr\System\Util\SiteUtility;
19
use ApacheSolrForTypo3\Solr\Util;
20
use TYPO3\CMS\Core\Utility\GeneralUtility;
21
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
22
23
24
/**
25
 * Class SearchFormViewHelper
26
 *
27
 * @author Frans Saris <[email protected]>
28
 * @author Timo Hund <[email protected]>
29
 */
30
class SearchFormViewHelper extends AbstractSolrFrontendTagBasedViewHelper
31
{
32
33
    /**
34
     * @var string
35
     */
36
    protected $tagName = 'form';
37
38
    /**
39
     * @var TypoScriptFrontendController
40
     */
41
    protected $frontendController;
42
43
    /**
44
     * @var bool
45
     */
46
    protected $escapeChildren = true;
47
48
    /**
49
     * @var bool
50
     */
51
    protected $escapeOutput = false;
52
53
    /**
54
     * Constructor
55
     */
56 36
    public function __construct()
57
    {
58 36
        parent::__construct();
59 36
        $this->frontendController = $GLOBALS['TSFE'];
60 36
    }
61
62
    /**
63
     * Initialize arguments.
64
     *
65
     * @return void
66
     */
67 36
    public function initializeArguments()
68
    {
69 36
        parent::initializeArguments();
70 36
        $this->registerTagAttribute('enctype', 'string', 'MIME type with which the form is submitted');
71 36
        $this->registerTagAttribute('method', 'string', 'Transfer type (GET or POST)', false, 'get');
72 36
        $this->registerTagAttribute('name', 'string', 'Name of form');
73 36
        $this->registerTagAttribute('onreset', 'string', 'JavaScript: On reset of the form');
74 36
        $this->registerTagAttribute('onsubmit', 'string', 'JavaScript: On submit of the form');
75 36
        $this->registerUniversalTagAttributes();
76
77 36
        $this->registerArgument('pageUid', 'integer', 'When not set current page is used', false);
78 36
        $this->registerArgument('additionalFilters', 'array', 'Additional filters', false);
79 36
        $this->registerArgument('additionalParams', 'array', 'Query parameters to be attached to the resulting URI', false, []);
80 36
        $this->registerArgument('pageType', 'integer', 'Type of the target page. See typolink.parameter', false, 0);
81
82 36
        $this->registerArgument('noCache', 'boolean', 'Set this to disable caching for the target page. You should not need this.', false, false);
83 36
        $this->registerArgument('noCacheHash', 'boolean', 'Set this to supress the cHash query parameter created by TypoLink. You should not need this.', false, false);
84 36
        $this->registerArgument('section', 'string', 'The anchor to be added to the action URI (only active if $actionUri is not set)', false, '');
85 36
        $this->registerArgument('absolute', 'boolean', 'If set, the URI of the rendered link is absolute', false, false);
86 36
        $this->registerArgument('addQueryString', 'boolean', 'If set, the current query parameters will be kept in the URI', false, false);
87 36
        $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the URI. Only active if $addQueryString = TRUE', false, []);
88 36
        $this->registerArgument('addQueryStringMethod', 'string', 'Set which parameters will be kept. Only active if $addQueryString = TRUE', false);
89 36
        $this->registerArgument('addSuggestUrl', 'boolean', 'Indicates if suggestUrl should be rendered or not', false, true);
90 36
        $this->registerArgument('suggestHeader', 'string', 'The header for the top results', false, 'Top Results');
91 36
        $this->registerArgument('suggestPageType', 'integer', 'The page type that should be used for the suggest', false, 7384);
92
93 36
    }
94
95
    /**
96
     * Render search form tag
97
     *
98
     * @return string
99
     */
100 36
    public function render()
101
    {
102 36
        $pageUid = $this->arguments['pageUid'];
103 36
        if ($pageUid === null && !empty($this->getTypoScriptConfiguration()->getSearchTargetPage())) {
104 36
            $pageUid = $this->getTypoScriptConfiguration()->getSearchTargetPage();
105
        }
106
107 36
        $uri = $this->buildUriFromPageUidAndArguments($pageUid);
108
109 36
        $this->tag->addAttribute('action', trim($uri));
110 36
        if ($this->arguments['addSuggestUrl']) {
111 36
            $this->tag->addAttribute('data-suggest', $this->getSuggestUrl($this->arguments['additionalFilters'], $pageUid));
112
        }
113 36
        $this->tag->addAttribute('data-suggest-header', htmlspecialchars($this->arguments['suggestHeader']));
114 36
        $this->tag->addAttribute('accept-charset', $this->frontendController->metaCharset);
115
116
        // Get search term
117
        // @extensionScannerIgnoreLine
118 36
        $this->getTemplateVariableContainer()->add('q', $this->getQueryString());
119
        // @extensionScannerIgnoreLine
120 36
        $this->getTemplateVariableContainer()->add('pageUid', $pageUid);
121
        // @extensionScannerIgnoreLine
122 36
        $this->getTemplateVariableContainer()->add('languageUid', Util::getLanguageUid());
123
        // @extensionScannerIgnoreLine
124 36
        $this->getTemplateVariableContainer()->add('existingParameters', $this->getExistingSearchParameters());
125
        // @extensionScannerIgnoreLine
126 36
        $this->getTemplateVariableContainer()->add('addPageAndLanguageId', !$this->getIsSiteManagedSite($pageUid));
127 36
        $formContent = $this->renderChildren();
128
        // @extensionScannerIgnoreLine
129 36
        $this->getTemplateVariableContainer()->remove('addPageAndLanguageId');
130
        // @extensionScannerIgnoreLine
131 36
        $this->getTemplateVariableContainer()->remove('q');
132
        // @extensionScannerIgnoreLine
133 36
        $this->getTemplateVariableContainer()->remove('pageUid');
134
        // @extensionScannerIgnoreLine
135 36
        $this->getTemplateVariableContainer()->remove('languageUid');
136
        // @extensionScannerIgnoreLine
137 36
        $this->getTemplateVariableContainer()->remove('existingParameters');
138
139 36
        $this->tag->setContent($formContent);
140
141 36
        return $this->tag->render();
142
    }
143
144
    /**
145
     * Get the existing search parameters in an array
146
     * Returns an empty array if search.keepExistingParametersForNewSearches is not set
147
     *
148
     * @return array
149
     */
150 36
    protected function getExistingSearchParameters()
151
    {
152 36
        $searchParameters = [];
153 36
        if ($this->getTypoScriptConfiguration()->getSearchKeepExistingParametersForNewSearches()) {
154 36
            $arguments = GeneralUtility::_GPmerged($this->getTypoScriptConfiguration()->getSearchPluginNamespace());
155 36
            unset($arguments['q'], $arguments['id'], $arguments['L']);
156 36
            $searchParameters = $this->translateSearchParametersToInputTagAttributes($arguments);
157
        }
158 36
        return $searchParameters;
159
    }
160
161
    /**
162
     * Translate the multi-dimensional array of existing arguments into a flat array of name-value pairs for the input tags
163
     *
164
     * @param $arguments
165
     * @param string $nameAttributePrefix
166
     * @return array
167
     */
168 36
    protected function translateSearchParametersToInputTagAttributes($arguments, $nameAttributePrefix = '')
169
    {
170 36
        $attributes = [];
171 36
        foreach ($arguments as $key => $value) {
172
            $name = $nameAttributePrefix . '[' . $key . ']';
173
            if (is_array($value)) {
174
                $attributes = array_merge(
175
                    $attributes,
176
                    $this->translateSearchParametersToInputTagAttributes($value, $name)
177
                );
178
            } else {
179
                $attributes[$name] = $value;
180
            }
181
        }
182 36
        return $attributes;
183
    }
184
185
    /**
186
     * When a site is managed with site management the language and the id are encoded in the path segment of the url.
187
     * When no speaking urls are active (e.g. with TYPO3 8 and no realurl) this information is passed as query parameter
188
     * and would get lost when it is only part of the query arguments in the action parameter of the form.
189
     *
190
     * @return boolean
191
     */
192 36
    protected function getIsSiteManagedSite($pageId)
193
    {
194 36
        return SiteUtility::getIsSiteManagedSite($pageId);
195
    }
196
197
    /**
198
     * @return \TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface
199
     */
200 36
    protected function getTemplateVariableContainer()
201
    {
202 36
        return $this->templateVariableContainer;
203
    }
204
205
    /**
206
     * @return string
207
     */
208 36
    protected function getQueryString()
209
    {
210 36
        $resultSet = $this->getSearchResultSet();
211 36
        if ($resultSet === null) {
212 2
            return '';
213
        }
214 34
        return trim($this->getSearchResultSet()->getUsedSearchRequest()->getRawUserQuery());
215
    }
216
217
    /**
218
     * @param NULL|array $additionalFilters
219
     * @param int $pageUid
220
     * @return string
221
     */
222 36
    protected function getSuggestUrl($additionalFilters, $pageUid)
223
    {
224 36
        $uriBuilder = $this->getControllerContext()->getUriBuilder();
225 36
        $pluginNamespace = $this->getTypoScriptConfiguration()->getSearchPluginNamespace();
226 36
        $suggestUrl = $uriBuilder->reset()->setTargetPageUid($pageUid)->setTargetPageType($this->arguments['suggestPageType'])->setUseCacheHash(false)->setArguments([$pluginNamespace => ['additionalFilters' => $additionalFilters]])->build();
0 ignored issues
show
Unused Code introduced by
The call to TYPO3\CMS\Extbase\Mvc\We...lder::setUseCacheHash() has too many arguments starting with false. ( Ignorable by Annotation )

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

226
        $suggestUrl = $uriBuilder->reset()->setTargetPageUid($pageUid)->setTargetPageType($this->arguments['suggestPageType'])->/** @scrutinizer ignore-call */ setUseCacheHash(false)->setArguments([$pluginNamespace => ['additionalFilters' => $additionalFilters]])->build();

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
227
228 36
        $urlService = GeneralUtility::makeInstance(UrlHelper::class, $suggestUrl);
229 36
        $suggestUrl = $urlService->removeQueryParameter('cHash')->getUrl();
230
231 36
        return $suggestUrl;
232
    }
233
234
    /**
235
     * @param int|null $pageUid
236
     * @return string
237
     */
238 36
    protected function buildUriFromPageUidAndArguments($pageUid): string
239
    {
240 36
        $uriBuilder = $this->getControllerContext()->getUriBuilder();
241
        $uri = $uriBuilder
242 36
            ->reset()
243 36
            ->setTargetPageUid($pageUid)
0 ignored issues
show
Bug introduced by
It seems like $pageUid can also be of type null; however, parameter $targetPageUid of TYPO3\CMS\Extbase\Mvc\We...der::setTargetPageUid() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

243
            ->setTargetPageUid(/** @scrutinizer ignore-type */ $pageUid)
Loading history...
244 36
            ->setTargetPageType($this->arguments['pageType'] ?? 0)
245 36
            ->setNoCache($this->arguments['noCache'] ?? false)
246 36
            ->setUseCacheHash(!$this->arguments['noCacheHash'])
0 ignored issues
show
Unused Code introduced by
The call to TYPO3\CMS\Extbase\Mvc\We...lder::setUseCacheHash() has too many arguments starting with ! $this->arguments['noCacheHash']. ( Ignorable by Annotation )

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

246
            ->/** @scrutinizer ignore-call */ setUseCacheHash(!$this->arguments['noCacheHash'])

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
247 36
            ->setArguments($this->arguments['additionalParams'] ?? [])
248 36
            ->setCreateAbsoluteUri($this->arguments['absolute'] ?? false)
249 36
            ->setAddQueryString($this->arguments['addQueryString'] ?? false)
250 36
            ->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString'] ?? [])
251 36
            ->setAddQueryStringMethod($this->arguments['addQueryStringMethod'] ?? '')
252 36
            ->setSection($this->arguments['section'] ?? '')
253 36
            ->build();
254 36
        return $uri;
255
    }
256
}
257