Completed
Push — master ( 7da5f6...0e708e )
by Timo
44:47 queued 41:16
created

buildUriFromPageUidAndArguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
dl 0
loc 17
ccs 15
cts 15
cp 1
rs 9.7666
c 1
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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
 * @package ApacheSolrForTypo3\Solr\ViewHelpers
30
 */
31
class SearchFormViewHelper extends AbstractSolrFrontendTagBasedViewHelper
32
{
33
34
    /**
35
     * @var string
36
     */
37
    protected $tagName = 'form';
38
39
    /**
40
     * @var TypoScriptFrontendController
41
     */
42
    protected $frontendController;
43
44
    /**
45
     * @var bool
46
     */
47
    protected $escapeChildren = true;
48
49
    /**
50
     * @var bool
51
     */
52
    protected $escapeOutput = false;
53
54
    /**
55
     * Constructor
56
     */
57 39
    public function __construct()
58
    {
59 39
        parent::__construct();
60 39
        $this->frontendController = $GLOBALS['TSFE'];
61 39
    }
62
63
    /**
64
     * Initialize arguments.
65
     *
66
     * @return void
67
     */
68 36
    public function initializeArguments()
69
    {
70 36
        parent::initializeArguments();
71 36
        $this->registerTagAttribute('enctype', 'string', 'MIME type with which the form is submitted');
72 36
        $this->registerTagAttribute('method', 'string', 'Transfer type (GET or POST)', false, 'get');
73 36
        $this->registerTagAttribute('name', 'string', 'Name of form');
74 36
        $this->registerTagAttribute('onreset', 'string', 'JavaScript: On reset of the form');
75 36
        $this->registerTagAttribute('onsubmit', 'string', 'JavaScript: On submit of the form');
76 36
        $this->registerUniversalTagAttributes();
77
78 36
        $this->registerArgument('pageUid', 'integer', 'When not set current page is used', false);
79 36
        $this->registerArgument('additionalFilters', 'array', 'Additional filters', false);
80 36
        $this->registerArgument('additionalParams', 'array', 'Query parameters to be attached to the resulting URI', false, []);
81 36
        $this->registerArgument('pageType', 'integer', 'Type of the target page. See typolink.parameter', false, 0);
82
83 36
        $this->registerArgument('noCache', 'boolean', 'Set this to disable caching for the target page. You should not need this.', false, false);
84 36
        $this->registerArgument('noCacheHash', 'boolean', 'Set this to supress the cHash query parameter created by TypoLink. You should not need this.', false, false);
85 36
        $this->registerArgument('section', 'string', 'The anchor to be added to the action URI (only active if $actionUri is not set)', false, '');
86 36
        $this->registerArgument('absolute', 'boolean', 'If set, the URI of the rendered link is absolute', false, false);
87 36
        $this->registerArgument('addQueryString', 'boolean', 'If set, the current query parameters will be kept in the URI', false, false);
88 36
        $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the URI. Only active if $addQueryString = TRUE', false, []);
89 36
        $this->registerArgument('addQueryStringMethod', 'string', 'Set which parameters will be kept. Only active if $addQueryString = TRUE', false);
90 36
        $this->registerArgument('addSuggestUrl', 'boolean', 'Indicates if suggestUrl should be rendered or not', false, true);
91 36
        $this->registerArgument('suggestHeader', 'string', 'The header for the top results', false, 'Top Results');
92 36
        $this->registerArgument('suggestPageType', 'integer', 'The page type that should be used for the suggest', false, 7384);
93
94 36
    }
95
96
    /**
97
     * Render search form tag
98
     *
99
     * @return string
100
     */
101 39
    public function render()
102
    {
103 39
        $pageUid = $this->arguments['pageUid'];
104 39
        if ($pageUid === null && !empty($this->getTypoScriptConfiguration()->getSearchTargetPage())) {
105 37
            $pageUid = $this->getTypoScriptConfiguration()->getSearchTargetPage();
106
        }
107
108 39
        $uri = $this->buildUriFromPageUidAndArguments($pageUid);
109
110 39
        $this->tag->addAttribute('action', trim($uri));
111 39
        if ($this->arguments['addSuggestUrl']) {
112 36
            $this->tag->addAttribute('data-suggest', $this->getSuggestUrl($this->arguments['additionalFilters'], $pageUid));
113
        }
114 39
        $this->tag->addAttribute('data-suggest-header', htmlspecialchars($this->arguments['suggestHeader']));
115 39
        $this->tag->addAttribute('accept-charset', $this->frontendController->metaCharset);
116
117
        // Get search term
118
        // @extensionScannerIgnoreLine
119 39
        $this->getTemplateVariableContainer()->add('q', $this->getQueryString());
120
        // @extensionScannerIgnoreLine
121 39
        $this->getTemplateVariableContainer()->add('pageUid', $pageUid);
122
        // @extensionScannerIgnoreLine
123 39
        $this->getTemplateVariableContainer()->add('languageUid', Util::getLanguageUid());
124
        // @extensionScannerIgnoreLine
125 39
        $this->getTemplateVariableContainer()->add('existingParameters', $this->getExistingSearchParameters());
126
        // @extensionScannerIgnoreLine
127 39
        $this->getTemplateVariableContainer()->add('addPageAndLanguageId', !$this->getIsSiteManagedSite($pageUid));
128 39
        $formContent = $this->renderChildren();
129
        // @extensionScannerIgnoreLine
130 39
        $this->getTemplateVariableContainer()->remove('addPageAndLanguageId');
131
        // @extensionScannerIgnoreLine
132 39
        $this->getTemplateVariableContainer()->remove('q');
133
        // @extensionScannerIgnoreLine
134 39
        $this->getTemplateVariableContainer()->remove('pageUid');
135
        // @extensionScannerIgnoreLine
136 39
        $this->getTemplateVariableContainer()->remove('languageUid');
137
        // @extensionScannerIgnoreLine
138 39
        $this->getTemplateVariableContainer()->remove('existingParameters');
139
140 39
        $this->tag->setContent($formContent);
141
142 39
        return $this->tag->render();
143
    }
144
145
    /**
146
     * Get the existing search parameters in an array
147
     * Returns an empty array if search.keepExistingParametersForNewSearches is not set
148
     *
149
     * @return array
150
     */
151 39
    protected function getExistingSearchParameters()
152
    {
153 39
        $searchParameters = [];
154 39
        if ($this->getTypoScriptConfiguration()->getSearchKeepExistingParametersForNewSearches()) {
155 36
            $arguments = GeneralUtility::_GPmerged('tx_solr');
156 36
            unset($arguments['q'], $arguments['id'], $arguments['L']);
157 36
            $searchParameters = $this->translateSearchParametersToInputTagAttributes($arguments);
158
        }
159 39
        return $searchParameters;
160
    }
161
162
    /**
163
     * Translate the multi-dimensional array of existing arguments into a flat array of name-value pairs for the input tags
164
     *
165
     * @param $arguments
166
     * @param string $nameAttributePrefix
167
     * @return array
168
     */
169 36
    protected function translateSearchParametersToInputTagAttributes($arguments, $nameAttributePrefix = '')
170
    {
171 36
        $attributes = [];
172 36
        foreach ($arguments as $key => $value) {
173
            $name = $nameAttributePrefix . '[' . $key . ']';
174
            if (is_array($value)) {
175
                $attributes = array_merge(
176
                    $attributes,
177
                    $this->translateSearchParametersToInputTagAttributes($value, $name)
178
                );
179
            } else {
180
                $attributes[$name] = $value;
181
            }
182
        }
183 36
        return $attributes;
184
    }
185
186
    /**
187
     * When a site is managed with site management the language and the id are encoded in the path segment of the url.
188
     * When no speaking urls are active (e.g. with TYPO3 8 and no realurl) this information is passed as query parameter
189
     * and would get lost when it is only part of the query arguments in the action parameter of the form.
190
     *
191
     * @return boolean
192
     */
193 36
    protected function getIsSiteManagedSite($pageId)
194
    {
195 36
        return SiteUtility::getIsSiteManagedSite($pageId);
196
    }
197
198
    /**
199
     * @return \TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface
200
     */
201 36
    protected function getTemplateVariableContainer()
202
    {
203 36
        return $this->templateVariableContainer;
204
    }
205
206
    /**
207
     * @return string
208
     */
209 39
    protected function getQueryString()
210
    {
211 39
        $resultSet = $this->getSearchResultSet();
212 39
        if ($resultSet === null) {
213 5
            return '';
214
        }
215 34
        return trim($this->getSearchResultSet()->getUsedSearchRequest()->getRawUserQuery());
216
    }
217
218
    /**
219
     * @param NULL|array $additionalFilters
220
     * @param int $pageUid
221
     * @return string
222
     */
223 36
    protected function getSuggestUrl($additionalFilters, $pageUid)
224
    {
225 36
        $uriBuilder = $this->getControllerContext()->getUriBuilder();
226 36
        $pluginNamespace = $this->getTypoScriptConfiguration()->getSearchPluginNamespace();
227 36
        $suggestUrl = $uriBuilder->reset()->setTargetPageUid($pageUid)->setTargetPageType($this->arguments['suggestPageType'])->setUseCacheHash(false)->setArguments([$pluginNamespace => ['additionalFilters' => $additionalFilters]])->build();
228
229 36
        $urlService = GeneralUtility::makeInstance(UrlHelper::class, $suggestUrl);
230 36
        $suggestUrl = $urlService->removeQueryParameter('cHash')->getUrl();
231
232 36
        return $suggestUrl;
233
    }
234
235
    /**
236
     * @param int|null $pageUid
237
     * @return string
238
     */
239 39
    protected function buildUriFromPageUidAndArguments($pageUid): string
240
    {
241 39
        $uriBuilder = $this->getControllerContext()->getUriBuilder();
242
        $uri = $uriBuilder
243 39
            ->reset()
244 39
            ->setTargetPageUid($pageUid)
245 39
            ->setTargetPageType($this->arguments['pageType'])
246 39
            ->setNoCache($this->arguments['noCache'])
247 39
            ->setUseCacheHash(!$this->arguments['noCacheHash'])
248 39
            ->setArguments($this->arguments['additionalParams'])
249 39
            ->setCreateAbsoluteUri($this->arguments['absolute'])
250 39
            ->setAddQueryString($this->arguments['addQueryString'])
251 39
            ->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString'])
252 39
            ->setAddQueryStringMethod($this->arguments['addQueryStringMethod'] ?? '')
253 39
            ->setSection($this->arguments['section'])
254 39
            ->build();
255 39
        return $uri;
256
    }
257
}
258