PageIndexer::hook_indexContent()   B
last analyzed

Complexity

Conditions 10
Paths 167

Size

Total Lines 66
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 28.656

Importance

Changes 0
Metric Value
eloc 43
c 0
b 0
f 0
dl 0
loc 66
ccs 24
cts 56
cp 0.4286
rs 7.1083
cc 10
nc 167
nop 1
crap 28.656

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
        // disable TSFE cache for TYPO3 v9
86 10
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'][__CLASS__] = $pageIndexingHookRegistration . '->disableCaching';
87
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'][__CLASS__] = $pageIndexingHookRegistration;
88
89 10
        // indexes fields defined in plugin.tx_solr.index.queue.pages.fields
90
        $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['Indexer']['indexPageSubstitutePageDocument']['ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\PageFieldMappingIndexer'] = PageFieldMappingIndexer::class;
91
92
        // making sure this instance is reused when called by the hooks registered before
93
        // \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction() and \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj() use
94
        // these storages while the object was instantiated by
95
        // ApacheSolrForTypo3\Solr\IndexQueue\FrontendHelper\Manager before.
96 10
        // \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance() also uses a dedicated cache
97
        $GLOBALS['T3_VAR']['callUserFunction_classPool'][__CLASS__] = $this;
98
        //$GLOBALS['T3_VAR']['getUserObj'][$pageIndexingHookRegistration] = $this;
99 10
100 10
        $this->registerAuthorizationService();
101
    }
102
103
    /**
104
     * Returns the status of whether a page was indexed.
105
     *
106
     * @return array Page indexed status.
107
     */
108
    public function getData()
109
    {
110
        return $this->responseData;
111
    }
112
113
    #
114
    # Indexer authorisation for access restricted pages / content
115
    #
116
117
    /**
118
     * Fakes a logged in user to retrieve access restricted content.
119
     *
120
     * @return void
121 2
     */
122
    public function authorizeFrontendUser()
123 2
    {
124 2
        $accessRootline = $this->getAccessRootline();
125
        $stringAccessRootline = (string)$accessRootline;
126 2
127
        if (empty($stringAccessRootline)) {
128
            return;
129
        }
130 2
131 2
        if (!is_array($GLOBALS['TSFE']->fe_user->user)) {
132
            $GLOBALS['TSFE']->fe_user->user = [];
133
        }
134 2
135 2
        $groups = $accessRootline->getGroups();
136
        $groupList = implode(',', $groups);
137 2
138 2
        $GLOBALS['TSFE']->fe_user->user['username'] = AuthorizationService::SOLR_INDEXER_USERNAME;
139
        $GLOBALS['TSFE']->fe_user->user['usergroup'] = $groupList;
140 2
141 2
        $this->responseData['authorization'] = [
142 2
            'username' => $GLOBALS['TSFE']->fe_user->user['username'],
143
            'usergroups' => $GLOBALS['TSFE']->fe_user->user['usergroup']
144 2
        ];
145
    }
146
147
    /**
148
     * Gets the access rootline as defined by the request.
149
     *
150
     * @return Rootline The access rootline to use for indexing.
151 10
     */
152
    protected function getAccessRootline()
153 10
    {
154
        $stringAccessRootline = '';
155 10
156
        if ($this->request->getParameter('accessRootline')) {
157
            $stringAccessRootline = $this->request->getParameter('accessRootline');
158
        }
159 10
160 10
        $accessRootline = GeneralUtility::makeInstance(Rootline::class, /** @scrutinizer ignore-type */ $stringAccessRootline);
161
        return $accessRootline;
162
    }
163
164
    /**
165
     * Registers an authentication service to authorize / grant the indexer to
166
     * access protected pages.
167
     *
168
     * @return void
169 10
     */
170
    protected function registerAuthorizationService()
171 10
    {
172
        $overrulingPriority = $this->getHighestAuthenticationServicePriority() + 1;
173 10
174 10
        ExtensionManagementUtility::addService(
175 10
            'solr', // extension key
176 10
            'auth', // service type
177
            AuthorizationService::class,
178
            // service key
179 10
            [// service meta data
180 10
                'title' => 'Solr Indexer Authorization',
181
                'description' => 'Authorizes the Solr Index Queue indexer to access protected pages.',
182 10
183
                'subtype' => 'getUserFE,authUserFE,getGroupsFE',
184
185 10
                'available' => true,
186 10
                'priority' => $overrulingPriority,
187
                'quality' => 100,
188 10
189 10
                'os' => '',
190
                'exec' => '',
191 10
192
                'classFile' => ExtensionManagementUtility::extPath('solr') . 'Classes/IndexQueue/FrontendHelper/AuthorizationService.php',
193
                'className' => AuthorizationService::class,
194
            ]
195 10
        );
196
    }
197
198
    /**
199
     * Determines the highest priority of all registered authentication
200
     * services.
201
     *
202
     * @return int Highest priority of all registered authentication service
203 10
     */
204
    protected function getHighestAuthenticationServicePriority()
205 10
    {
206
        $highestPriority = 0;
207 10
208 2
        if (is_array($GLOBALS['T3_SERVICES']['auth'])) {
209 2
            foreach ($GLOBALS['T3_SERVICES']['auth'] as $service) {
210 2
                if ($service['priority'] > $highestPriority) {
211
                    $highestPriority = $service['priority'];
212
                }
213
            }
214
        }
215 10
216
        return $highestPriority;
217
    }
218
219
    #
220
    # Indexing
221
    #
222
223
    /**
224
     * Generates the current page's URL.
225
     *
226
     * Uses the provided GET parameters, page id and language id.
227
     *
228
     * @return string URL of the current page.
229 10
     */
230
    protected function generatePageUrl()
231 10
    {
232
        if ($this->request->getParameter('overridePageUrl')) {
233
            return $this->request->getParameter('overridePageUrl');
234
        }
235
236 10
            /** @var $contentObject ContentObjectRenderer */
237
        $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
238
239 10
        $typolinkConfiguration = [
240 10
            'parameter' => intval($this->page->id),
241
            'linkAccessRestrictedPages' => '1'
242
        ];
243 10
244 10
        $language = GeneralUtility::_GET('L');
245 1
        if (!empty($language)) {
246
            $typolinkConfiguration['additionalParams'] = '&L=' . $language;
247
        }
248 10
249
        $url = $contentObject->typoLink_URL($typolinkConfiguration);
250
251 10
        // clean up
252
        if ($url == '') {
253
            $url = '/';
254
        }
255 10
256
        return $url;
257
    }
258
259
    /**
260
     * Handles the indexing of the page content during post processing of a
261
     * generated page.
262
     *
263
     * @param TypoScriptFrontendController $page TypoScript frontend
264 10
     */
265
    public function hook_indexContent(TypoScriptFrontendController $page)
266 10
    {
267
        $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__);
268 10
269 10
        $this->page = $page;
270
        $configuration = Util::getSolrConfiguration();
271 10
272 10
        $logPageIndexed = $configuration->getLoggingIndexingPageIndexed();
273
        if (!$this->page->config['config']['index_enable']) {
274
            if ($logPageIndexed) {
275
                $this->logger->log(
276
                    SolrLogManager::ERROR,
277
                    'Indexing is disabled. Set config.index_enable = 1 .'
278
                );
279
            }
280
            return;
281
        }
282
283 10
        try {
284 10
            $indexQueueItem = $this->getIndexQueueItem();
285
            if (is_null($indexQueueItem)) {
286
                throw new \UnexpectedValueException('Can not get index queue item', 1482162337);
287
            }
288 10
289
            $solrConnection = $this->getSolrConnection($indexQueueItem);
290
291 10
            /** @var $indexer Typo3PageIndexer */
292 10
            $indexer = GeneralUtility::makeInstance(Typo3PageIndexer::class, /** @scrutinizer ignore-type */ $page);
293 10
            $indexer->setSolrConnection($solrConnection);
294 10
            $indexer->setPageAccessRootline($this->getAccessRootline());
295 10
            $indexer->setPageUrl($this->generatePageUrl());
296 10
            $indexer->setMountPointParameter($GLOBALS['TSFE']->MP);
297
            $indexer->setIndexQueueItem($indexQueueItem);
298 10
299 10
            $this->responseData['pageIndexed'] = (int)$indexer->indexPage();
300 10
            $this->responseData['originalPageDocument'] = (array)$indexer->getPageSolrDocument();
301 10
            $this->responseData['solrConnection'] = [
302 10
                'rootPage' => $indexQueueItem->getRootPageUid(),
303 10
                'sys_language_uid' => Util::getLanguageUid(),
304
                'solr' => (string)$solrConnection->getNode('write')
305
            ];
306 10
307 10
            $documentsSentToSolr = $indexer->getDocumentsSentToSolr();
308 10
            foreach ($documentsSentToSolr as $document) {
309
                $this->responseData['documentsSentToSolr'][] = (array)$document;
310
            }
311
        } catch (\Exception $e) {
312
            if ($configuration->getLoggingExceptions()) {
313
                $this->logger->log(
314
                    SolrLogManager::ERROR,
315
                    'Exception while trying to index page ' . $page->id,
316
                    [
317
                        $e->__toString()
318
                    ]
319
                );
320
            }
321
        }
322 10
323
        if ($logPageIndexed) {
324
            $success = $this->responseData['pageIndexed'] ? 'Success' : 'Failed';
325
            $severity = $this->responseData['pageIndexed'] ? SolrLogManager::NOTICE : SolrLogManager::ERROR;
326
327
            $this->logger->log(
328
                $severity,
329
                'Page indexed: ' . $success,
330
                $this->responseData
331
            );
332 10
        }
333
    }
334
335
    /**
336
     * Gets the solr connection to use for indexing the page based on the
337
     * Index Queue item's properties.
338
     *
339
     * @param Item $indexQueueItem
340
     * @return SolrConnection Solr server connection
341 10
     */
342
    protected function getSolrConnection(Item $indexQueueItem)
343
    {
344 10
        /** @var $connectionManager ConnectionManager */
345
        $connectionManager = GeneralUtility::makeInstance(ConnectionManager::class);
346 10
347 10
        $solrConnection = $connectionManager->getConnectionByRootPageId(
348 10
            $indexQueueItem->getRootPageUid(),
349
            Util::getLanguageUid()
350
        );
351 10
352
        return $solrConnection;
353
    }
354
355
    /**
356
     * This method retrieves the item from the index queue, that is indexed in this request.
357
     *
358
     * @return \ApacheSolrForTypo3\Solr\IndexQueue\Item
359 10
     */
360
    protected function getIndexQueueItem()
361
    {
362 10
        /** @var $indexQueue Queue */
363 10
        $indexQueue = GeneralUtility::makeInstance(Queue::class);
364 10
        $indexQueueItem = $indexQueue->getItem($this->request->getParameter('item'));
365
        return $indexQueueItem;
366
    }
367
}
368