Passed
Push — task/2976_TYPO3.11_compatibili... ( 4d1a77...3b9190 )
by Rafael
03:39
created

SearchController::initializeView()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.1755

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 12
ccs 7
cts 9
cp 0.7778
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.1755
1
<?php
2
3
namespace ApacheSolrForTypo3\Solr\Controller;
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet;
19
use ApacheSolrForTypo3\Solr\Pagination\ResultsPagination;
20
use ApacheSolrForTypo3\Solr\Pagination\ResultsPaginator;
21
use ApacheSolrForTypo3\Solr\System\Solr\SolrUnavailableException;
22
use ApacheSolrForTypo3\Solr\Util;
23
use Psr\Http\Message\ResponseInterface;
24
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
25
use TYPO3\CMS\Extbase\Http\ForwardResponse;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
28
use TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException;
29
use TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException;
30
use TYPO3\CMS\Fluid\View\TemplateView;
31
use TYPO3Fluid\Fluid\View\ViewInterface;
32
33
/**
34
 * Class SearchController
35
 *
36
 * @author Frans Saris <[email protected]>
37
 * @author Timo Hund <[email protected]>
38
 */
39
class SearchController extends AbstractBaseController
40
{
41
    /**
42
     * @var TemplateView
43
     */
44
    protected $view;
45
46
    /**
47
     * Provide search query in extbase arguments.
48
     */
49 34
    protected function initializeAction()
50
    {
51 34
        parent::initializeAction();
52 34
        $this->mapGlobalQueryStringWhenEnabled();
53 34
    }
54
55
    /**
56
     * @return void
57
     */
58 34
    protected function mapGlobalQueryStringWhenEnabled()
59
    {
60 34
        $query = GeneralUtility::_GET('q');
61
62 34
        $useGlobalQueryString = $query !== null && !$this->typoScriptConfiguration->getSearchIgnoreGlobalQParameter();
0 ignored issues
show
Bug introduced by
The method getSearchIgnoreGlobalQParameter() does not exist on null. ( Ignorable by Annotation )

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

62
        $useGlobalQueryString = $query !== null && !$this->typoScriptConfiguration->/** @scrutinizer ignore-call */ getSearchIgnoreGlobalQParameter();

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...
63
64 34
        if ($useGlobalQueryString) {
65 1
            $this->request->setArgument('q', $query);
66
        }
67 34
    }
68
69
    /**
70
     * @param ViewInterface $view
71
     */
72 34
    public function initializeView($view)
73
    {
74 34
        if ($view instanceof TemplateView) {
75 34
            $customTemplate = $this->getCustomTemplateFromConfiguration();
76 34
            if ($customTemplate === '') {
77 33
                return;
78
            }
79
80 1
            if (strpos($customTemplate, 'EXT:') !== false) {
81 1
                $view->setTemplatePathAndFilename($customTemplate);
82
            } else {
83
                $view->setTemplate($customTemplate);
84
            }
85
        }
86 1
    }
87
88
    /**
89
     * @return string
90
     */
91 34
    protected function getCustomTemplateFromConfiguration(): string
92
    {
93 34
        $templateKey = str_replace('Action', '', $this->actionMethodName);
94 34
        return $this->typoScriptConfiguration->getViewTemplateByFileKey($templateKey);
95
    }
96
97
    /**
98
     * Results
99
     * @return ResponseInterface
100
     * @throws AspectNotFoundException
101
     * @throws NoSuchArgumentException
102
     * @throws InvalidSlotException
103
     * @throws InvalidSlotReturnException
104
     */
105 32
    public function resultsAction(): ResponseInterface
106
    {
107
        try {
108 32
            $arguments = $this->request->getArguments();
109 32
            $pageId = $this->typoScriptFrontendController->getRequestedId();
0 ignored issues
show
Bug introduced by
The method getRequestedId() does not exist on null. ( Ignorable by Annotation )

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

109
            /** @scrutinizer ignore-call */ 
110
            $pageId = $this->typoScriptFrontendController->getRequestedId();

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...
110 32
            $languageId = Util::getLanguageUid();
111 32
            $searchRequest = $this->getSearchRequestBuilder()->buildForSearch($arguments, $pageId, $languageId);
112
113 32
            $searchResultSet = $this->searchService->search($searchRequest);
0 ignored issues
show
Bug introduced by
The method search() does not exist on null. ( Ignorable by Annotation )

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

113
            /** @scrutinizer ignore-call */ 
114
            $searchResultSet = $this->searchService->search($searchRequest);

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...
114
115
            // we pass the search result set to the controller context, to have the possibility
116
            // to access it without passing it from partial to partial
117 32
            $this->controllerContext->setSearchResultSet($searchResultSet);
118
119 32
            $currentPage = $this->request->hasArgument('page') ? (int)$this->request->getArgument('page') : 1;
120 32
            $itemsPerPage = $searchResultSet->getUsedResultsPerPage();
121 32
            $paginator = GeneralUtility::makeInstance(ResultsPaginator::class, $searchResultSet, $currentPage, $itemsPerPage);
122 32
            $pagination = GeneralUtility::makeInstance(ResultsPagination::class, $paginator);
123 32
            $pagination->setMaxPageNumbers((int)$this->typoScriptConfiguration->getMaxPaginatorLinks(0));
124
125 32
            $values = [
126 32
                'additionalFilters' => $this->getAdditionalFilters(),
127 32
                'resultSet' => $searchResultSet,
128 32
                'pluginNamespace' => $this->typoScriptConfiguration->getSearchPluginNamespace(),
129 32
                'arguments' => $arguments,
130 32
                'pagination' => $pagination,
131 32
                'currentPage' => $currentPage,
132
            ];
133
134 32
            $values = $this->emitActionSignal(__CLASS__, __FUNCTION__, [$values]);
135
136 32
            $this->view->assignMultiple($values);
137
        } catch (SolrUnavailableException $e) {
138
            return $this->handleSolrUnavailable();
139
        }
140 32
        return $this->htmlResponse();
141
    }
142
143
    /**
144
     * Form
145
     */
146 1
    public function formAction(): ResponseInterface
147
    {
148 1
        $values = [
149 1
            'search' => $this->searchService->getSearch(),
150 1
            'additionalFilters' => $this->getAdditionalFilters(),
151 1
            'pluginNamespace' => $this->typoScriptConfiguration->getSearchPluginNamespace()
152
        ];
153 1
        $values = $this->emitActionSignal(__CLASS__, __FUNCTION__, [$values]);
154
155 1
        $this->view->assignMultiple($values);
156 1
        return $this->htmlResponse();
157
    }
158
159
    /**
160
     * Frequently Searched
161
     */
162
    public function frequentlySearchedAction(): ResponseInterface
163
    {
164
        /** @var  $searchResultSet SearchResultSet */
165
        $searchResultSet = GeneralUtility::makeInstance(SearchResultSet::class);
166
167
        $pageId = $this->typoScriptFrontendController->getRequestedId();
168
        $languageId = Util::getLanguageUid();
169
        $searchRequest = $this->getSearchRequestBuilder()->buildForFrequentSearches($pageId, $languageId);
170
        $searchResultSet->setUsedSearchRequest($searchRequest);
171
172
        $this->controllerContext->setSearchResultSet($searchResultSet);
173
174
        $values = [
175
            'additionalFilters' => $this->getAdditionalFilters(),
176
            'resultSet' => $searchResultSet
177
        ];
178
        $values = $this->emitActionSignal(__CLASS__, __FUNCTION__, [$values]);
179
180
        $this->view->assignMultiple($values);
181
        return $this->htmlResponse();
182
    }
183
184
    /**
185
     * This action allows to render a detailView with data from solr.
186
     *
187
     * @param string $documentId
188
     * @return ResponseInterface
189
     */
190 1
    public function detailAction(string $documentId = ''): ResponseInterface
191
    {
192
        try {
193 1
            $document = $this->searchService->getDocumentById($documentId);
194 1
            $this->view->assign('document', $document);
195
        } catch (SolrUnavailableException $e) {
196
            return $this->handleSolrUnavailable();
197
        }
198 1
        return $this->htmlResponse();
199
    }
200
201
    /**
202
     * Rendered when no search is available.
203
     * @return ResponseInterface
204
     */
205
    public function solrNotAvailableAction(): ResponseInterface
206
    {
207
        return $this->htmlResponse()
208
            ->withStatus(503, self::STATUS_503_MESSAGE);
209
    }
210
211
    /**
212
     * Called when the solr server is unavailable.
213
     */
214
    protected function handleSolrUnavailable(): ResponseInterface
215
    {
216
        parent::logSolrUnavailable();
217
        return new ForwardResponse('solrNotAvailable');
218
    }
219
220
    /**
221
     * This method can be overwritten to add additionalFilters for the autosuggest.
222
     * By default, suggest controller will apply the configured filters from the typoscript configuration.
223
     *
224
     * @return array
225
     */
226 33
    protected function getAdditionalFilters(): array
227
    {
228 33
        return [];
229
    }
230
}
231