Passed
Push — master ( 5f60a5...391298 )
by Timo
24:49
created

PageIndexer::authorizeFrontendUser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3.1172

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 13
cts 17
cp 0.7647
rs 9.2
c 0
b 0
f 0
cc 3
eloc 13
nc 3
nop 0
crap 3.1172
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
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
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;
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
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