1
|
|
|
<?php |
2
|
|
|
namespace ApacheSolrForTypo3\Solr\IndexQueue\FrontendHelper; |
3
|
|
|
|
4
|
|
|
/*************************************************************** |
5
|
|
|
* Copyright notice |
6
|
|
|
* |
7
|
|
|
* (c) 2011-2015 Ingo Renner <[email protected]> |
8
|
|
|
* All rights reserved |
9
|
|
|
* |
10
|
|
|
* This script is part of the TYPO3 project. The TYPO3 project is |
11
|
|
|
* free software; you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU General Public License as published by |
13
|
|
|
* the Free Software Foundation; either version 3 of the License, or |
14
|
|
|
* (at your option) any later version. |
15
|
|
|
* |
16
|
|
|
* The GNU General Public License can be found at |
17
|
|
|
* http://www.gnu.org/copyleft/gpl.html. |
18
|
|
|
* |
19
|
|
|
* This script is distributed in the hope that it will be useful, |
20
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
21
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22
|
|
|
* GNU General Public License for more details. |
23
|
|
|
* |
24
|
|
|
* This copyright notice MUST APPEAR in all copies of the script! |
25
|
|
|
***************************************************************/ |
26
|
|
|
|
27
|
|
|
use ApacheSolrForTypo3\Solr\Access\Rootline; |
28
|
|
|
use ApacheSolrForTypo3\Solr\ConnectionManager; |
29
|
|
|
use ApacheSolrForTypo3\Solr\IndexQueue\Item; |
30
|
|
|
use ApacheSolrForTypo3\Solr\IndexQueue\Queue; |
31
|
|
|
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; |
32
|
|
|
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; |
33
|
|
|
use ApacheSolrForTypo3\Solr\Typo3PageIndexer; |
34
|
|
|
use ApacheSolrForTypo3\Solr\Util; |
35
|
|
|
use TYPO3\CMS\Core\SingletonInterface; |
36
|
|
|
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; |
37
|
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility; |
38
|
|
|
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; |
39
|
|
|
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Index Queue Page Indexer frontend helper to ask the frontend page indexer to |
43
|
|
|
* index the page. |
44
|
|
|
* |
45
|
|
|
* @author Ingo Renner <[email protected]> |
46
|
|
|
*/ |
47
|
|
|
class PageIndexer extends AbstractFrontendHelper implements SingletonInterface |
48
|
|
|
{ |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* This frontend helper's executed action. |
52
|
|
|
* |
53
|
|
|
* @var string |
54
|
|
|
*/ |
55
|
|
|
protected $action = 'indexPage'; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* the page currently being indexed. |
59
|
|
|
* |
60
|
|
|
* @var TypoScriptFrontendController |
61
|
|
|
*/ |
62
|
|
|
protected $page; |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Response data |
66
|
|
|
* |
67
|
|
|
* @var array |
68
|
|
|
*/ |
69
|
|
|
protected $responseData = []; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @var \TYPO3\CMS\Core\Log\Logger |
73
|
|
|
*/ |
74
|
|
|
protected $logger = null; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Activates a frontend helper by registering for hooks and other |
78
|
|
|
* resources required by the frontend helper to work. |
79
|
|
|
*/ |
80
|
10 |
|
public function activate() |
81
|
|
|
{ |
82
|
10 |
|
$pageIndexingHookRegistration = PageIndexer::class; |
83
|
|
|
|
84
|
10 |
|
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'][__CLASS__] = $pageIndexingHookRegistration . '->authorizeFrontendUser'; |
85
|
10 |
|
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'][__CLASS__] = $pageIndexingHookRegistration . '->disableCaching'; |
86
|
10 |
|
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'][__CLASS__] = $pageIndexingHookRegistration; |
87
|
|
|
|
88
|
|
|
// indexes fields defined in plugin.tx_solr.index.queue.pages.fields |
89
|
10 |
|
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['Indexer']['indexPageSubstitutePageDocument']['ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\PageFieldMappingIndexer'] = PageFieldMappingIndexer::class; |
90
|
|
|
|
91
|
|
|
// making sure this instance is reused when called by the hooks registered before |
92
|
|
|
// \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction() and \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj() use |
|
|
|
|
93
|
|
|
// these storages while the object was instantiated by |
94
|
|
|
// ApacheSolrForTypo3\Solr\IndexQueue\FrontendHelper\Manager before. |
95
|
|
|
// \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance() also uses a dedicated cache |
96
|
10 |
|
$GLOBALS['T3_VAR']['callUserFunction_classPool'][__CLASS__] = $this; |
97
|
|
|
//$GLOBALS['T3_VAR']['getUserObj'][$pageIndexingHookRegistration] = $this; |
|
|
|
|
98
|
|
|
|
99
|
10 |
|
$this->registerAuthorizationService(); |
100
|
10 |
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Returns the status of whether a page was indexed. |
104
|
|
|
* |
105
|
|
|
* @return array Page indexed status. |
106
|
|
|
*/ |
107
|
|
|
public function getData() |
108
|
|
|
{ |
109
|
|
|
return $this->responseData; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
# |
113
|
|
|
# Indexer authorisation for access restricted pages / content |
114
|
|
|
# |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Fakes a logged in user to retrieve access restricted content. |
118
|
|
|
* |
119
|
|
|
* @return void |
120
|
|
|
*/ |
121
|
2 |
|
public function authorizeFrontendUser() |
122
|
|
|
{ |
123
|
2 |
|
$accessRootline = $this->getAccessRootline(); |
124
|
2 |
|
$stringAccessRootline = (string)$accessRootline; |
125
|
|
|
|
126
|
2 |
|
if (empty($stringAccessRootline)) { |
127
|
|
|
return; |
128
|
|
|
} |
129
|
|
|
|
130
|
2 |
|
if (!is_array($GLOBALS['TSFE']->fe_user->user)) { |
131
|
2 |
|
$GLOBALS['TSFE']->fe_user->user = []; |
132
|
|
|
} |
133
|
|
|
|
134
|
2 |
|
$groups = $accessRootline->getGroups(); |
135
|
2 |
|
$groupList = implode(',', $groups); |
136
|
|
|
|
137
|
2 |
|
$GLOBALS['TSFE']->fe_user->user['username'] = AuthorizationService::SOLR_INDEXER_USERNAME; |
138
|
2 |
|
$GLOBALS['TSFE']->fe_user->user['usergroup'] = $groupList; |
139
|
|
|
|
140
|
2 |
|
$this->responseData['authorization'] = [ |
141
|
2 |
|
'username' => $GLOBALS['TSFE']->fe_user->user['username'], |
142
|
2 |
|
'usergroups' => $GLOBALS['TSFE']->fe_user->user['usergroup'] |
143
|
|
|
]; |
144
|
2 |
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Gets the access rootline as defined by the request. |
148
|
|
|
* |
149
|
|
|
* @return Rootline The access rootline to use for indexing. |
150
|
|
|
*/ |
151
|
10 |
|
protected function getAccessRootline() |
152
|
|
|
{ |
153
|
10 |
|
$stringAccessRootline = ''; |
154
|
|
|
|
155
|
10 |
|
if ($this->request->getParameter('accessRootline')) { |
156
|
|
|
$stringAccessRootline = $this->request->getParameter('accessRootline'); |
157
|
|
|
} |
158
|
|
|
|
159
|
10 |
|
$accessRootline = GeneralUtility::makeInstance(Rootline::class, $stringAccessRootline); |
160
|
10 |
|
return $accessRootline; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Registers an authentication service to authorize / grant the indexer to |
165
|
|
|
* access protected pages. |
166
|
|
|
* |
167
|
|
|
* @return void |
168
|
|
|
*/ |
169
|
10 |
|
protected function registerAuthorizationService() |
170
|
|
|
{ |
171
|
10 |
|
$overrulingPriority = $this->getHighestAuthenticationServicePriority() + 1; |
172
|
|
|
|
173
|
10 |
|
ExtensionManagementUtility::addService( |
174
|
10 |
|
'solr', // extension key |
175
|
10 |
|
'auth', // service type |
176
|
10 |
|
AuthorizationService::class, |
177
|
|
|
// service key |
178
|
|
|
[// service meta data |
179
|
10 |
|
'title' => 'Solr Indexer Authorization', |
180
|
10 |
|
'description' => 'Authorizes the Solr Index Queue indexer to access protected pages.', |
181
|
|
|
|
182
|
10 |
|
'subtype' => 'getUserFE,authUserFE,getGroupsFE', |
183
|
|
|
|
184
|
|
|
'available' => true, |
185
|
10 |
|
'priority' => $overrulingPriority, |
186
|
10 |
|
'quality' => 100, |
187
|
|
|
|
188
|
10 |
|
'os' => '', |
189
|
10 |
|
'exec' => '', |
190
|
|
|
|
191
|
10 |
|
'classFile' => ExtensionManagementUtility::extPath('solr') . 'Classes/IndexQueue/FrontendHelper/AuthorizationService.php', |
192
|
|
|
'className' => AuthorizationService::class, |
193
|
|
|
] |
194
|
|
|
); |
195
|
10 |
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Determines the highest priority of all registered authentication |
199
|
|
|
* services. |
200
|
|
|
* |
201
|
|
|
* @return int Highest priority of all registered authentication service |
202
|
|
|
*/ |
203
|
10 |
|
protected function getHighestAuthenticationServicePriority() |
204
|
|
|
{ |
205
|
10 |
|
$highestPriority = 0; |
206
|
|
|
|
207
|
10 |
|
if (is_array($GLOBALS['T3_SERVICES']['auth'])) { |
208
|
2 |
|
foreach ($GLOBALS['T3_SERVICES']['auth'] as $service) { |
209
|
2 |
|
if ($service['priority'] > $highestPriority) { |
210
|
2 |
|
$highestPriority = $service['priority']; |
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
215
|
10 |
|
return $highestPriority; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
# |
219
|
|
|
# Indexing |
220
|
|
|
# |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Generates the current page's URL. |
224
|
|
|
* |
225
|
|
|
* Uses the provided GET parameters, page id and language id. |
226
|
|
|
* |
227
|
|
|
* @return string URL of the current page. |
228
|
|
|
*/ |
229
|
10 |
|
protected function generatePageUrl() |
230
|
|
|
{ |
231
|
10 |
|
if ($this->request->getParameter('overridePageUrl')) { |
232
|
|
|
return $this->request->getParameter('overridePageUrl'); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** @var $contentObject ContentObjectRenderer */ |
236
|
10 |
|
$contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); |
237
|
|
|
|
238
|
|
|
$typolinkConfiguration = [ |
239
|
10 |
|
'parameter' => intval($this->page->id), |
240
|
10 |
|
'linkAccessRestrictedPages' => '1' |
241
|
|
|
]; |
242
|
|
|
|
243
|
10 |
|
$language = GeneralUtility::_GET('L'); |
244
|
10 |
|
if (!empty($language)) { |
245
|
1 |
|
$typolinkConfiguration['additionalParams'] = '&L=' . $language; |
246
|
|
|
} |
247
|
|
|
|
248
|
10 |
|
$url = $contentObject->typoLink_URL($typolinkConfiguration); |
249
|
|
|
|
250
|
|
|
// clean up |
251
|
10 |
|
if ($url == '') { |
252
|
|
|
$url = '/'; |
253
|
|
|
} |
254
|
|
|
|
255
|
10 |
|
return $url; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* Handles the indexing of the page content during post processing of a |
260
|
|
|
* generated page. |
261
|
|
|
* |
262
|
|
|
* @param TypoScriptFrontendController $page TypoScript frontend |
263
|
|
|
*/ |
264
|
10 |
|
public function hook_indexContent(TypoScriptFrontendController $page) |
265
|
|
|
{ |
266
|
10 |
|
$this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__); |
267
|
|
|
|
268
|
10 |
|
$this->page = $page; |
269
|
10 |
|
$configuration = Util::getSolrConfiguration(); |
270
|
|
|
|
271
|
10 |
|
$logPageIndexed = $configuration->getLoggingIndexingPageIndexed(); |
272
|
10 |
|
if (!$this->page->config['config']['index_enable']) { |
273
|
|
|
if ($logPageIndexed) { |
274
|
|
|
$this->logger->log( |
275
|
|
|
SolrLogManager::ERROR, |
276
|
|
|
'Indexing is disabled. Set config.index_enable = 1 .' |
277
|
|
|
); |
278
|
|
|
} |
279
|
|
|
return; |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
try { |
283
|
10 |
|
$indexQueueItem = $this->getIndexQueueItem(); |
284
|
10 |
|
if (is_null($indexQueueItem)) { |
285
|
|
|
throw new \UnexpectedValueException('Can not get index queue item', 1482162337); |
286
|
|
|
} |
287
|
|
|
|
288
|
10 |
|
$solrConnection = $this->getSolrConnection($indexQueueItem); |
289
|
|
|
|
290
|
|
|
/** @var $indexer Typo3PageIndexer */ |
291
|
10 |
|
$indexer = GeneralUtility::makeInstance(Typo3PageIndexer::class, $page); |
292
|
10 |
|
$indexer->setSolrConnection($solrConnection); |
293
|
10 |
|
$indexer->setPageAccessRootline($this->getAccessRootline()); |
294
|
10 |
|
$indexer->setPageUrl($this->generatePageUrl()); |
295
|
10 |
|
$indexer->setMountPointParameter($GLOBALS['TSFE']->MP); |
296
|
10 |
|
$indexer->setIndexQueueItem($indexQueueItem); |
297
|
|
|
|
298
|
10 |
|
$this->responseData['pageIndexed'] = (int)$indexer->indexPage(); |
299
|
10 |
|
$this->responseData['originalPageDocument'] = (array)$indexer->getPageSolrDocument(); |
300
|
|
|
$this->responseData['solrConnection'] = [ |
301
|
10 |
|
'rootPage' => $indexQueueItem->getRootPageUid(), |
302
|
10 |
|
'sys_language_uid' => $GLOBALS['TSFE']->sys_language_uid, |
303
|
10 |
|
'solr' => (string)$solrConnection |
304
|
|
|
]; |
305
|
|
|
|
306
|
|
|
$documentsSentToSolr = $indexer->getDocumentsSentToSolr(); |
307
|
|
|
foreach ($documentsSentToSolr as $document) { |
308
|
|
|
$this->responseData['documentsSentToSolr'][] = (array)$document; |
309
|
|
|
} |
310
|
10 |
|
} catch (\Exception $e) { |
311
|
10 |
|
if ($configuration->getLoggingExceptions()) { |
312
|
10 |
|
$this->logger->log( |
313
|
10 |
|
SolrLogManager::ERROR, |
314
|
10 |
|
'Exception while trying to index page ' . $page->id, |
315
|
|
|
[ |
316
|
10 |
|
$e->__toString() |
317
|
|
|
] |
318
|
|
|
); |
319
|
|
|
} |
320
|
|
|
} |
321
|
|
|
|
322
|
10 |
|
if ($logPageIndexed) { |
323
|
|
|
$success = $this->responseData['pageIndexed'] ? 'Success' : 'Failed'; |
324
|
|
|
$severity = $this->responseData['pageIndexed'] ? SolrLogManager::NOTICE : SolrLogManager::ERROR; |
325
|
|
|
|
326
|
|
|
$this->logger->log( |
327
|
|
|
$severity, |
328
|
|
|
'Page indexed: ' . $success, |
329
|
|
|
$this->responseData |
330
|
|
|
); |
331
|
|
|
} |
332
|
10 |
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Gets the solr connection to use for indexing the page based on the |
336
|
|
|
* Index Queue item's properties. |
337
|
|
|
* |
338
|
|
|
* @param Item $indexQueueItem |
339
|
|
|
* @return SolrConnection Solr server connection |
340
|
|
|
*/ |
341
|
10 |
|
protected function getSolrConnection(Item $indexQueueItem) |
342
|
|
|
{ |
343
|
|
|
/** @var $connectionManager ConnectionManager */ |
344
|
10 |
|
$connectionManager = GeneralUtility::makeInstance(ConnectionManager::class); |
345
|
|
|
|
346
|
10 |
|
$solrConnection = $connectionManager->getConnectionByRootPageId( |
347
|
10 |
|
$indexQueueItem->getRootPageUid(), |
348
|
10 |
|
$GLOBALS['TSFE']->sys_language_uid |
349
|
|
|
); |
350
|
|
|
|
351
|
10 |
|
return $solrConnection; |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
/** |
355
|
|
|
* This method retrieves the item from the index queue, that is indexed in this request. |
356
|
|
|
* |
357
|
|
|
* @return \ApacheSolrForTypo3\Solr\IndexQueue\Item |
358
|
|
|
*/ |
359
|
10 |
|
protected function getIndexQueueItem() |
360
|
|
|
{ |
361
|
|
|
/** @var $indexQueue Queue */ |
362
|
10 |
|
$indexQueue = GeneralUtility::makeInstance(Queue::class); |
363
|
10 |
|
$indexQueueItem = $indexQueue->getItem($this->request->getParameter('item')); |
364
|
10 |
|
return $indexQueueItem; |
365
|
|
|
} |
366
|
|
|
} |
367
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.