Completed
Push — master ( 99ae82...fdefe7 )
by Timo
10s
created

PageIndexer::getData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
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 2 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\SolrService;
28
use ApacheSolrForTypo3\Solr\Util;
29
use TYPO3\CMS\Core\SingletonInterface;
30
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
33
34
/**
35
 * Index Queue Page Indexer frontend helper to ask the frontend page indexer to
36
 * index the page.
37
 *
38
 * @author Ingo Renner <[email protected]>
39
 */
40
class PageIndexer extends AbstractFrontendHelper implements SingletonInterface
41
{
42
43
    /**
44
     * This frontend helper's executed action.
45
     *
46
     * @var string
47
     */
48
    protected $action = 'indexPage';
49
50
    /**
51
     * the page currently being indexed.
52
     *
53
     * @var TypoScriptFrontendController
54
     */
55
    protected $page;
56
57
    /**
58
     * Response data
59
     *
60
     * @var array
61
     */
62
    protected $responseData = array();
63
64
    /**
65
     * Activates a frontend helper by registering for hooks and other
66
     * resources required by the frontend helper to work.
67
     */
68 2
    public function activate()
69
    {
70 2
        $pageIndexingHookRegistration = 'ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\PageIndexer';
71
72 2
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['initFEuser'][__CLASS__] = '&' . $pageIndexingHookRegistration . '->authorizeFrontendUser';
73 2
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'][__CLASS__] = '&' . $pageIndexingHookRegistration . '->disableCaching';
74 2
        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['pageIndexing'][__CLASS__] = $pageIndexingHookRegistration;
75
76
        // indexes fields defined in plugin.tx_solr.index.queue.pages.fields
77 2
        $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['Indexer']['indexPageSubstitutePageDocument']['ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\PageFieldMappingIndexer'] = 'ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\PageFieldMappingIndexer';
78
79
        // making sure this instance is reused when called by the hooks registered before
80
        // \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction() and \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj() use
81
        // these storages while the object was instantiated by
82
        // ApacheSolrForTypo3\Solr\IndexQueue\FrontendHelper\Manager before.
83
        // \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance() also uses a dedicated cache
84 2
        $GLOBALS['T3_VAR']['callUserFunction_classPool'][__CLASS__] = $this;
85
        //$GLOBALS['T3_VAR']['getUserObj'][$pageIndexingHookRegistration] = $this;
86
87 2
        $this->registerAuthorizationService();
88
# Since TypoScript is not available at this point we cannot bind it to some TS configuration option whether to log or not
89
#		\TYPO3\CMS\Core\Utility\GeneralUtility::devLog('Registered Solr Page Indexer authorization service', 'solr', 1, array(
90
#			'auth services' => $GLOBALS['T3_SERVICES']['auth']
91
#		));
92 2
    }
93
94
    /**
95
     * Returns the status of whether a page was indexed.
96
     *
97
     * @return array Page indexed status.
98
     */
99
    public function getData()
100
    {
101
        return $this->responseData;
102
    }
103
104
    #
105
    # Indexer authorisation for access restricted pages / content
106
    #
107
108
    /**
109
     * Fakes a logged in user to retrieve access restricted content.
110
     *
111
     * @return void
112
     */
113
    public function authorizeFrontendUser()
114
    {
115
        $accessRootline = $this->getAccessRootline();
116
        $stringAccessRootline = (string)$accessRootline;
117
118
        if (empty($stringAccessRootline)) {
119
            return;
120
        }
121
122
        if (!is_array($GLOBALS['TSFE']->fe_user->user)) {
123
            $GLOBALS['TSFE']->fe_user->user = array();
124
        }
125
126
        $groups = $accessRootline->getGroups();
127
        $groupList = implode(',', $groups);
128
129
        $GLOBALS['TSFE']->fe_user->user['username'] = AuthorizationService::SOLR_INDEXER_USERNAME;
130
        $GLOBALS['TSFE']->fe_user->user['usergroup'] = $groupList;
131
132
        $this->responseData['authorization'] = array(
133
            'username' => $GLOBALS['TSFE']->fe_user->user['username'],
134
            'usergroups' => $GLOBALS['TSFE']->fe_user->user['usergroup']
135
        );
136
    }
137
138
    /**
139
     * Gets the access rootline as defined by the request.
140
     *
141
     * @return \ApacheSolrForTypo3\Solr\Access\Rootline The access rootline to use for indexing.
142
     */
143 2
    protected function getAccessRootline()
144
    {
145 2
        $stringAccessRootline = '';
146
147 2
        if ($this->request->getParameter('accessRootline')) {
148
            $stringAccessRootline = $this->request->getParameter('accessRootline');
149
        }
150
151 2
        $accessRootline = GeneralUtility::makeInstance(
152 2
            'ApacheSolrForTypo3\\Solr\\Access\\Rootline',
153
            $stringAccessRootline
154
        );
155
156 2
        return $accessRootline;
157
    }
158
159
    /**
160
     * Registers an authentication service to authorize / grant the indexer to
161
     * access protected pages.
162
     *
163
     * @return void
164
     */
165 2
    protected function registerAuthorizationService()
166
    {
167 2
        $overrulingPriority = $this->getHighestAuthenticationServicePriority() + 1;
168
169 2
        ExtensionManagementUtility::addService(
170 2
            'solr', // extension key
171 2
            'auth', // service type
172 2
            'ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\AuthorizationService',
173
            // service key
174
            array( // service meta data
175 2
                'title' => 'Solr Indexer Authorization',
176 2
                'description' => 'Authorizes the Solr Index Queue indexer to access protected pages.',
177
178 2
                'subtype' => 'getUserFE,authUserFE,getGroupsFE',
179
180
                'available' => true,
181 2
                'priority' => $overrulingPriority,
182 2
                'quality' => 100,
183
184 2
                'os' => '',
185 2
                'exec' => '',
186
187 2
                'classFile' => $GLOBALS['PATH_solr'] . 'Classes/IndexQueue/FrontendHelper/AuthorizationService.php',
188 2
                'className' => 'ApacheSolrForTypo3\\Solr\\IndexQueue\\FrontendHelper\\AuthorizationService',
189
            )
190
        );
191 2
    }
192
193
    /**
194
     * Determines the highest priority of all registered authentication
195
     * services.
196
     *
197
     * @return int Highest priority of all registered authentication service
198
     */
199 2
    protected function getHighestAuthenticationServicePriority()
200
    {
201 2
        $highestPriority = 0;
202
203 2
        if (is_array($GLOBALS['T3_SERVICES']['auth'])) {
204
            foreach ($GLOBALS['T3_SERVICES']['auth'] as $service) {
205
                if ($service['priority'] > $highestPriority) {
206
                    $highestPriority = $service['priority'];
207
                }
208
            }
209
        }
210
211 2
        return $highestPriority;
212
    }
213
214
    #
215
    # Indexing
216
    #
217
218
    /**
219
     * Generates the current page's URL.
220
     *
221
     * Uses the provided GET parameters, page id and language id.
222
     *
223
     * @return string URL of the current page.
224
     */
225 2
    protected function generatePageUrl()
226
    {
227 2
        if ($this->request->getParameter('overridePageUrl')) {
228
            return $this->request->getParameter('overridePageUrl');
229
        }
230
231 2
        $contentObject = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
232
233
        $typolinkConfiguration = array(
234 2
            'parameter' => intval($this->page->id),
235 2
            'linkAccessRestrictedPages' => '1'
236
        );
237
238 2
        $language = GeneralUtility::_GET('L');
239 2
        if (!empty($language)) {
240
            $typolinkConfiguration['additionalParams'] = '&L=' . $language;
241
        }
242
243 2
        $url = $contentObject->typoLink_URL($typolinkConfiguration);
244
245
        // clean up
246 2
        if ($url == '') {
247
            $url = '/';
248
        }
249
250 2
        return $url;
251
    }
252
253
    /**
254
     * Handles the indexing of the page content during post processing of a
255
     * generated page.
256
     *
257
     * @param TypoScriptFrontendController $page TypoScript frontend
258
     */
259 2
    public function hook_indexContent(TypoScriptFrontendController $page)
260
    {
261 2
        $this->page = $page;
262 2
        $configuration = Util::getSolrConfiguration();
263
264 2
        $logPageIndexed = $configuration->getLoggingIndexingPageIndexed();
265 2
        if (!$this->page->config['config']['index_enable']) {
266
            if ($logPageIndexed) {
267
                GeneralUtility::devLog('Indexing is disabled. Set config.index_enable = 1 .',
268
                    'solr', 3);
269
            }
270
            return;
271
        }
272
273
        try {
274 2
            $indexer = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\Typo3PageIndexer',
275
                $page);
276 2
            $indexer->setSolrConnection($this->getSolrConnection());
277 2
            $indexer->setPageAccessRootline($this->getAccessRootline());
278 2
            $indexer->setPageUrl($this->generatePageUrl());
279 2
            $indexer->setMountPointParameter($GLOBALS['TSFE']->MP);
280
281 2
            $this->responseData['pageIndexed'] = (int)$indexer->indexPage();
282 2
            $this->responseData['originalPageDocument'] = (array)$indexer->getPageSolrDocument();
283
284 2
            $documentsSentToSolr = $indexer->getDocumentsSentToSolr();
285 2
            foreach ($documentsSentToSolr as $document) {
286 2
                $this->responseData['documentsSentToSolr'][] = (array)$document;
287
            }
288
        } catch (\Exception $e) {
289
            if ($configuration->getLoggingExceptions()) {
290
                GeneralUtility::devLog('Exception while trying to index page ' . $page->id,
291
                    'solr', 3, array(
292
                        $e->__toString()
293
                    ));
294
            }
295
        }
296
297 2
        if ($logPageIndexed) {
298
            $success = $this->responseData['pageIndexed'] ? 'Success' : 'Failed';
299
            $severity = $this->responseData['pageIndexed'] ? -1 : 3;
300
301
            GeneralUtility::devLog('Page indexed: ' . $success, 'solr',
302
                $severity, $this->responseData);
303
        }
304 2
    }
305
306
    /**
307
     * Gets the solr connection to use for indexing the page based on the
308
     * Index Queue item's properties.
309
     *
310
     * @return SolrService Solr server connection
311
     */
312 2
    protected function getSolrConnection()
313
    {
314 2
        $indexQueue = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\IndexQueue\\Queue');
315 2
        $connectionManager = GeneralUtility::makeInstance('ApacheSolrForTypo3\\Solr\\ConnectionManager');
316
317 2
        $indexQueueItem = $indexQueue->getItem(
318 2
            $this->request->getParameter('item')
319
        );
320
321 2
        $solrConnection = $connectionManager->getConnectionByRootPageId(
322 2
            $indexQueueItem->getRootPageUid(),
323 2
            $GLOBALS['TSFE']->sys_language_uid
324
        );
325
326
        // log the Solr connection used and why
327 2
        $this->responseData['solrConnection'] = array(
328 2
            'rootPage' => $indexQueueItem->getRootPageUid(),
329 2
            'sys_language_uid' => $GLOBALS['TSFE']->sys_language_uid,
330 2
            'solr' => (string)$solrConnection
331
        );
332
333 2
        return $solrConnection;
334
    }
335
}
336