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\ConnectionManager; |
19
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSetService; |
20
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequestBuilder; |
21
|
|
|
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException; |
22
|
|
|
use ApacheSolrForTypo3\Solr\Search; |
23
|
|
|
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; |
24
|
|
|
use ApacheSolrForTypo3\Solr\Mvc\Controller\SolrControllerContext; |
25
|
|
|
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; |
26
|
|
|
use ApacheSolrForTypo3\Solr\System\Service\ConfigurationService; |
27
|
|
|
use ApacheSolrForTypo3\Solr\System\Configuration\ConfigurationManager as SolrConfigurationManager; |
28
|
|
|
use ApacheSolrForTypo3\Solr\Util; |
29
|
|
|
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; |
30
|
|
|
use TYPO3\CMS\Core\TypoScript\TypoScriptService; |
31
|
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility; |
32
|
|
|
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; |
33
|
|
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; |
34
|
|
|
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext; |
35
|
|
|
use TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException; |
36
|
|
|
use TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException; |
37
|
|
|
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; |
38
|
|
|
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Class AbstractBaseController |
42
|
|
|
* |
43
|
|
|
* @property SolrControllerContext $controllerContext |
44
|
|
|
* |
45
|
|
|
* @author Frans Saris <[email protected]> |
46
|
|
|
* @author Timo Hund <[email protected]> |
47
|
|
|
*/ |
48
|
|
|
abstract class AbstractBaseController extends ActionController |
49
|
|
|
{ |
50
|
|
|
/** |
51
|
|
|
* The HTTP code 503 message. |
52
|
|
|
* @var string |
53
|
|
|
*/ |
54
|
|
|
protected const STATUS_503_MESSAGE = 'Apache Solr Server is not available.'; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @var ContentObjectRenderer|null |
58
|
|
|
*/ |
59
|
|
|
private ?ContentObjectRenderer $contentObjectRenderer = null; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @var TypoScriptFrontendController|null |
63
|
|
|
*/ |
64
|
|
|
protected ?TypoScriptFrontendController $typoScriptFrontendController = null; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @var SolrConfigurationManager|null |
68
|
|
|
*/ |
69
|
|
|
private ?SolrConfigurationManager $solrConfigurationManager = null; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* The configuration is private if you need it please get it from the controllerContext. |
73
|
|
|
* |
74
|
|
|
* @var TypoScriptConfiguration|null |
75
|
|
|
*/ |
76
|
|
|
protected ?TypoScriptConfiguration $typoScriptConfiguration = null; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @var SearchResultSetService|null |
80
|
|
|
*/ |
81
|
|
|
protected ?SearchResultSetService $searchService = null; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @var SearchRequestBuilder|null |
85
|
|
|
*/ |
86
|
|
|
protected ?SearchRequestBuilder $searchRequestBuilder = null; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @var bool |
90
|
|
|
*/ |
91
|
|
|
protected bool $resetConfigurationBeforeInitialize = true; |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @param ConfigurationManagerInterface $configurationManager |
95
|
|
|
* @return void |
96
|
|
|
*/ |
97
|
|
|
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) |
98
|
|
|
{ |
99
|
|
|
$this->configurationManager = $configurationManager; |
100
|
|
|
// @extensionScannerIgnoreLine |
101
|
|
|
$this->contentObjectRenderer = $this->configurationManager->getContentObject(); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @param ContentObjectRenderer $contentObjectRenderer |
106
|
|
|
*/ |
107
|
|
|
public function setContentObjectRenderer(ContentObjectRenderer $contentObjectRenderer) |
108
|
|
|
{ |
109
|
|
|
$this->contentObjectRenderer = $contentObjectRenderer; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @return ContentObjectRenderer|null |
114
|
|
|
*/ |
115
|
|
|
public function getContentObjectRenderer(): ?ContentObjectRenderer |
116
|
|
|
{ |
117
|
|
|
return $this->contentObjectRenderer; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @param SolrConfigurationManager $configurationManager |
122
|
|
|
*/ |
123
|
|
|
public function injectSolrConfigurationManager(SolrConfigurationManager $configurationManager) |
124
|
|
|
{ |
125
|
|
|
$this->solrConfigurationManager = $configurationManager; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param bool $resetConfigurationBeforeInitialize |
130
|
|
|
*/ |
131
|
|
|
public function setResetConfigurationBeforeInitialize(bool $resetConfigurationBeforeInitialize) |
132
|
|
|
{ |
133
|
|
|
$this->resetConfigurationBeforeInitialize = $resetConfigurationBeforeInitialize; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Initialize the controller context |
138
|
|
|
* |
139
|
|
|
* @return ControllerContext ControllerContext to be passed to the view |
140
|
|
|
* @api |
141
|
|
|
*/ |
142
|
|
|
protected function buildControllerContext() |
143
|
|
|
{ |
144
|
|
|
/** @var $controllerContext SolrControllerContext */ |
145
|
|
|
$controllerContext = $this->objectManager->get(SolrControllerContext::class); |
|
|
|
|
146
|
|
|
$controllerContext->setRequest($this->request); |
147
|
|
|
// $controllerContext->setResponse($this->response); |
148
|
|
|
if ($this->arguments !== null) { |
149
|
|
|
$controllerContext->setArguments($this->arguments); |
150
|
|
|
} |
151
|
|
|
$controllerContext->setUriBuilder($this->uriBuilder); |
152
|
|
|
|
153
|
|
|
$controllerContext->setTypoScriptConfiguration($this->typoScriptConfiguration); |
|
|
|
|
154
|
|
|
|
155
|
|
|
return $controllerContext; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Initialize action |
160
|
|
|
* @throws AspectNotFoundException |
161
|
|
|
*/ |
162
|
|
|
protected function initializeAction() |
163
|
|
|
{ |
164
|
|
|
// Reset configuration (to reset flexform overrides) if resetting is enabled |
165
|
|
|
if ($this->resetConfigurationBeforeInitialize) { |
166
|
|
|
$this->solrConfigurationManager->reset(); |
|
|
|
|
167
|
|
|
} |
168
|
|
|
/** @var TypoScriptService $typoScriptService */ |
169
|
|
|
$typoScriptService = $this->objectManager->get(TypoScriptService::class); |
|
|
|
|
170
|
|
|
|
171
|
|
|
// Merge settings done by typoscript with solrConfiguration plugin.tx_solr (obsolete when part of ext:solr) |
172
|
|
|
$frameWorkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK); |
173
|
|
|
$pluginSettings = []; |
174
|
|
|
foreach (['search', 'settings', 'suggest', 'statistics', 'logging', 'general', 'solr', 'view'] as $key) { |
175
|
|
|
if (isset($frameWorkConfiguration[$key])) { |
176
|
|
|
$pluginSettings[$key] = $frameWorkConfiguration[$key]; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
$this->typoScriptConfiguration = $this->solrConfigurationManager->getTypoScriptConfiguration(); |
181
|
|
|
if ($pluginSettings !== []) { |
182
|
|
|
$this->typoScriptConfiguration->mergeSolrConfiguration( |
183
|
|
|
$typoScriptService->convertPlainArrayToTypoScriptArray($pluginSettings), |
184
|
|
|
true, |
185
|
|
|
false |
186
|
|
|
); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
$this->objectManager->get(ConfigurationService::class) |
|
|
|
|
190
|
|
|
->overrideConfigurationWithFlexFormSettings( |
191
|
|
|
$this->contentObjectRenderer->data['pi_flexform'], |
192
|
|
|
$this->typoScriptConfiguration |
193
|
|
|
); |
194
|
|
|
|
195
|
|
|
parent::initializeAction(); |
196
|
|
|
$this->typoScriptFrontendController = $GLOBALS['TSFE']; |
197
|
|
|
$this->initializeSettings(); |
198
|
|
|
|
199
|
|
|
if ($this->actionMethodName !== 'solrNotAvailableAction') { |
200
|
|
|
$this->initializeSearch(); |
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Inject settings of plugin.tx_solr |
206
|
|
|
* |
207
|
|
|
* @return void |
208
|
|
|
*/ |
209
|
|
|
protected function initializeSettings() |
210
|
|
|
{ |
211
|
|
|
/** @var $typoScriptService TypoScriptService */ |
212
|
|
|
$typoScriptService = $this->objectManager->get(TypoScriptService::class); |
|
|
|
|
213
|
|
|
|
214
|
|
|
// Make sure plugin.tx_solr.settings are available in the view as {settings} |
215
|
|
|
$this->settings = $typoScriptService->convertTypoScriptArrayToPlainArray( |
216
|
|
|
$this->typoScriptConfiguration->getObjectByPathOrDefault('plugin.tx_solr.settings.', []) |
|
|
|
|
217
|
|
|
); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Initialize the Solr connection and |
222
|
|
|
* test the connection through a ping |
223
|
|
|
* @throws AspectNotFoundException |
224
|
|
|
*/ |
225
|
|
|
protected function initializeSearch() |
226
|
|
|
{ |
227
|
|
|
/** @var ConnectionManager $solrConnection */ |
228
|
|
|
try { |
229
|
|
|
$solrConnection = $this->objectManager->get(ConnectionManager::class)->getConnectionByPageId($this->typoScriptFrontendController->id, Util::getLanguageUid(), $this->typoScriptFrontendController->MP); |
|
|
|
|
230
|
|
|
$search = $this->objectManager->get(Search::class, $solrConnection); |
|
|
|
|
231
|
|
|
|
232
|
|
|
/** @noinspection PhpParamsInspection */ |
233
|
|
|
$this->searchService = $this->objectManager->get( |
|
|
|
|
234
|
|
|
SearchResultSetService::class, |
235
|
|
|
/** @scrutinizer ignore-type */ |
236
|
|
|
$this->typoScriptConfiguration, |
237
|
|
|
/** @scrutinizer ignore-type */ |
238
|
|
|
$search |
239
|
|
|
); |
240
|
|
|
} catch (NoSolrConnectionFoundException $e) { |
241
|
|
|
$this->logSolrUnavailable(); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* @return SearchRequestBuilder |
247
|
|
|
*/ |
248
|
|
|
protected function getSearchRequestBuilder(): SearchRequestBuilder |
249
|
|
|
{ |
250
|
|
|
if ($this->searchRequestBuilder === null) { |
251
|
|
|
$this->searchRequestBuilder = GeneralUtility::makeInstance(SearchRequestBuilder::class, /** @scrutinizer ignore-type */ $this->typoScriptConfiguration); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
return $this->searchRequestBuilder; |
|
|
|
|
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Called when the solr server is unavailable. |
259
|
|
|
* |
260
|
|
|
* @return void |
261
|
|
|
*/ |
262
|
|
|
protected function logSolrUnavailable() |
263
|
|
|
{ |
264
|
|
|
if ($this->typoScriptConfiguration->getLoggingExceptions()) { |
265
|
|
|
/** @var SolrLogManager $logger */ |
266
|
|
|
$logger = GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__); |
267
|
|
|
$logger->log(SolrLogManager::ERROR, 'Solr server is not available'); |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Emits signal for various actions |
273
|
|
|
* |
274
|
|
|
* @param string $className Name of the class containing the signal |
275
|
|
|
* @param string $signalName Name of the signal slot |
276
|
|
|
* @param array $signalArguments arguments for the signal slot |
277
|
|
|
* |
278
|
|
|
* @return array|mixed |
279
|
|
|
* @throws InvalidSlotException |
280
|
|
|
* @throws InvalidSlotReturnException |
281
|
|
|
*/ |
282
|
|
|
protected function emitActionSignal(string $className, string $signalName, array $signalArguments) |
283
|
|
|
{ |
284
|
|
|
return $this->signalSlotDispatcher->dispatch($className, $signalName, $signalArguments)[0]; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.