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

Util   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 469
Duplicated Lines 0 %

Test Coverage

Coverage 94.01%

Importance

Changes 0
Metric Value
wmc 54
dl 0
loc 469
ccs 157
cts 167
cp 0.9401
rs 6.8539
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getDocumentId() 0 12 2
A isAllowedPageType() 0 11 3
B getConfigurationFromExistingTSFE() 0 43 6
A getAllowedPageTypes() 0 5 1
B isDraftRecord() 0 13 5
C getConfigurationFromPageId() 0 36 7
A getPageOverlayTableName() 0 3 2
A getAbsRefPrefixFromTSFE() 0 13 3
A getIsTYPO3VersionBelow9() 0 3 1
A getConfigurationFromInitializedTSFE() 0 7 1
A getSolrConfigurationFromPageId() 0 4 1
A getPageDocumentId() 0 11 2
A getSolrConfiguration() 0 4 1
A containsOneOfTheStrings() 0 10 3
A buildTypoScriptConfigurationFromArray() 0 4 1
A isLocalizedRecord() 0 13 3
A buildConfigurationArray() 0 10 3
A getConfigurationPageIdToUse() 0 10 2
B initializeTsfe() 0 60 7

How to fix   Complexity   

Complex Class

Complex classes like Util often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Util, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace ApacheSolrForTypo3\Solr;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-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\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver;
28
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
29
use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService;
30
use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache;
31
use ApacheSolrForTypo3\Solr\System\Configuration\ConfigurationManager;
32
use ApacheSolrForTypo3\Solr\System\Configuration\ConfigurationPageResolver;
33
use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration;
34
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
35
use ApacheSolrForTypo3\Solr\System\DateTime\FormatService;
36
use TYPO3\CMS\Backend\Utility\BackendUtility;
37
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
38
use TYPO3\CMS\Core\TypoScript\ExtendedTemplateService;
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
41
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
42
use TYPO3\CMS\Frontend\Page\PageRepository;
43
44
/**
45
 * Utility class for tx_solr
46
 *
47
 * @author Ingo Renner <[email protected]>
48
 */
49
class Util
50
{
51
52
    /**
53
     * Generates a document id for documents representing page records.
54
     *
55
     * @param int $uid The page's uid
56
     * @param int $typeNum The page's typeNum
57
     * @param int $language the language id, defaults to 0
58
     * @param string $accessGroups comma separated list of uids of groups that have access to that page
59
     * @param string $mountPointParameter The mount point parameter that is used to access the page.
60
     * @return string The document id for that page
61
     */
62 66
    public static function getPageDocumentId($uid, $typeNum = 0, $language = 0, $accessGroups = '0,-1', $mountPointParameter = '')
63
    {
64 66
        $additionalParameters = $typeNum . '/' . $language . '/' . $accessGroups;
65
66 66
        if ((string)$mountPointParameter !== '') {
67 2
            $additionalParameters = $mountPointParameter . '/' . $additionalParameters;
68
        }
69
70 66
        $documentId = self::getDocumentId('pages', $uid, $uid, $additionalParameters);
71
72 66
        return $documentId;
73
    }
74
75
    /**
76
     * Generates a document id in the form $siteHash/$type/$uid.
77
     *
78
     * @param string $table The records table name
79
     * @param int $rootPageId The record's site root id
80
     * @param int $uid The record's uid
81
     * @param string $additionalIdParameters Additional ID parameters
82
     * @return string A document id
83
     */
84 85
    public static function getDocumentId($table, $rootPageId, $uid, $additionalIdParameters = '')
85
    {
86 85
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
87 85
        $site = $siteRepository->getSiteByPageId($rootPageId);
88 85
        $siteHash = $site->getSiteHash();
89
90 85
        $documentId = $siteHash . '/' . $table . '/' . $uid;
91 85
        if (!empty($additionalIdParameters)) {
92 66
            $documentId .= '/' . $additionalIdParameters;
93
        }
94
95 85
        return $documentId;
96
    }
97
98
    /**
99
     * Shortcut to retrieve the TypoScript configuration for EXT:solr
100
     * (plugin.tx_solr) from TSFE.
101
     *
102
     * @return TypoScriptConfiguration
103
     */
104 175
    public static function getSolrConfiguration()
105
    {
106 175
        $configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
107 175
        return $configurationManager->getTypoScriptConfiguration();
108
    }
109
110
    /**
111
     * Gets the Solr configuration for a specific root page id.
112
     * To be used from the backend.
113
     *
114
     * @param int $pageId Id of the (root) page to get the Solr configuration from.
115
     * @param bool $initializeTsfe Optionally initializes a full TSFE to get the configuration, defaults to FALSE
116
     * @param int $language System language uid, optional, defaults to 0
117
     * @return TypoScriptConfiguration The Solr configuration for the requested tree.
118
     */
119 151
    public static function getSolrConfigurationFromPageId($pageId, $initializeTsfe = false, $language = 0)
120
    {
121 151
        $rootPath = '';
122 151
        return self::getConfigurationFromPageId($pageId, $rootPath, $initializeTsfe, $language);
123
    }
124
125
    /**
126
     * Loads the TypoScript configuration for a given page id and language.
127
     * Language usage may be disabled to get the default TypoScript
128
     * configuration.
129
     *
130
     * @param int $pageId Id of the (root) page to get the Solr configuration from.
131
     * @param string $path The TypoScript configuration path to retrieve.
132
     * @param bool $initializeTsfe Optionally initializes a full TSFE to get the configuration, defaults to FALSE
133
     * @param int $language System language uid, optional, defaults to 0
134
     * @param bool $useTwoLevelCache Flag to enable the two level cache for the typoscript configuration array
135
     * @return TypoScriptConfiguration The Solr configuration for the requested tree.
136
     */
137 152
    public static function getConfigurationFromPageId($pageId, $path, $initializeTsfe = false, $language = 0, $useTwoLevelCache = true)
138
    {
139 152
        $pageId = self::getConfigurationPageIdToUse($pageId);
140
141 152
        static $configurationObjectCache = [];
142 152
        $cacheId = md5($pageId . '|' . $path . '|' . $language);
143 152
        if (isset($configurationObjectCache[$cacheId])) {
144 69
            return $configurationObjectCache[$cacheId];
145
        }
146
147
        // If we're on UID 0, we cannot retrieve a configuration currently.
148
        // getRootline() below throws an exception (since #typo3-60 )
149
        // as UID 0 cannot have any parent rootline by design.
150 152
        if ($pageId == 0) {
151 2
            return $configurationObjectCache[$cacheId] = self::buildTypoScriptConfigurationFromArray([], $pageId, $language, $path);
152
        }
153
154 151
        if ($useTwoLevelCache) {
155
            /** @var $cache TwoLevelCache */
156 151
            $cache = GeneralUtility::makeInstance(TwoLevelCache::class, 'tx_solr_configuration');
157 151
            $configurationArray = $cache->get($cacheId);
158
        }
159
160 151
        if (!empty($configurationArray)) {
161
            // we have a cache hit and can return it.
162
            return $configurationObjectCache[$cacheId] = self::buildTypoScriptConfigurationFromArray($configurationArray, $pageId, $language, $path);
163
        }
164
165
        // we have nothing in the cache. We need to build the configurationToUse
166 151
        $configurationArray = self::buildConfigurationArray($pageId, $path, $initializeTsfe, $language);
167
168 151
        if ($useTwoLevelCache && isset($cache)) {
169 151
            $cache->set($cacheId, $configurationArray);
170
        }
171
172 151
        return $configurationObjectCache[$cacheId] = self::buildTypoScriptConfigurationFromArray($configurationArray, $pageId, $language, $path);
173
    }
174
175
    /**
176
     * This method retrieves the closest pageId where a configuration is located, when this
177
     * feature is enabled.
178
     *
179
     * @param int $pageId
180
     * @return int
181
     */
182 152
    protected static function getConfigurationPageIdToUse($pageId)
183
    {
184 152
        $extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class);
185 152
        if ($extensionConfiguration->getIsUseConfigurationFromClosestTemplateEnabled()) {
186
            /** @var $configurationPageResolve ConfigurationPageResolver */
187
            $configurationPageResolver = GeneralUtility::makeInstance(ConfigurationPageResolver::class);
188
            $pageId = $configurationPageResolver->getClosestPageIdWithActiveTemplate($pageId);
189
            return $pageId;
190
        }
191 152
        return $pageId;
192
    }
193
194
    /**
195
     * Initializes a TSFE, if required and builds an configuration array, containing the solr configuration.
196
     *
197
     * @param integer $pageId
198
     * @param string $path
199
     * @param boolean $initializeTsfe
200
     * @param integer $language
201
     * @return array
202
     */
203 151
    protected static function buildConfigurationArray($pageId, $path, $initializeTsfe, $language)
204
    {
205 151
        if ($initializeTsfe) {
206 7
            self::initializeTsfe($pageId, $language);
207 6
            $configurationToUse = self::getConfigurationFromInitializedTSFE($path);
208
        } else {
209 151
            $configurationToUse = self::getConfigurationFromExistingTSFE($pageId, $path, $language);
210
        }
211
212 151
        return is_array($configurationToUse) ? $configurationToUse : [];
213
    }
214
215
    /**
216
     * Builds the configuration object from a config array and returns it.
217
     *
218
     * @param array $configurationToUse
219
     * @param int $pageId
220
     * @param int $languageId
221
     * @param string $typoScriptPath
222
     * @return TypoScriptConfiguration
223
     */
224 152
    protected static function buildTypoScriptConfigurationFromArray(array $configurationToUse, $pageId, $languageId, $typoScriptPath)
225
    {
226 152
        $configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
227 152
        return $configurationManager->getTypoScriptConfiguration($configurationToUse, $pageId, $languageId, $typoScriptPath);
228
    }
229
230
    /**
231
     * This function is used to retrieve the configuration from a previous initialized TSFE
232
     * (see: getConfigurationFromPageId)
233
     *
234
     * @param string $path
235
     * @return mixed
236
     */
237 6
    private static function getConfigurationFromInitializedTSFE($path)
238
    {
239
        /** @var $tmpl ExtendedTemplateService */
240 6
        $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
241 6
        $configuration = $tmpl->ext_getSetup($GLOBALS['TSFE']->tmpl->setup, $path);
242 6
        $configurationToUse = $configuration[0];
243 6
        return $configurationToUse;
244
    }
245
246
    /**
247
     * This function is used to retrieve the configuration from an existing TSFE instance
248
     * @param $pageId
249
     * @param $path
250
     * @param $language
251
     * @return mixed
252
     */
253 151
    private static function getConfigurationFromExistingTSFE($pageId, $path, $language)
254
    {
255 151
        if (is_int($language)) {
256 151
            GeneralUtility::_GETset($language, 'L');
257
        }
258
259
            /** @var $pageSelect PageRepository */
260 151
        $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
261 151
        $rootLine = $pageSelect->getRootLine($pageId);
262
263 151
        $initializedTsfe = false;
264 151
        $initializedPageSelect = false;
265 151
        if (empty($GLOBALS['TSFE']->sys_page)) {
266 81
            if (empty($GLOBALS['TSFE'])) {
267 81
                $GLOBALS['TSFE'] = new \stdClass();
268 81
                $GLOBALS['TSFE']->tmpl = new \stdClass();
269 81
                $GLOBALS['TSFE']->tmpl->rootLine = $rootLine;
270 81
                $GLOBALS['TSFE']->sys_page = $pageSelect;
271 81
                $GLOBALS['TSFE']->id = $pageId;
272 81
                $GLOBALS['TSFE']->tx_solr_initTsfe = 1;
273 81
                $initializedTsfe = true;
274
            }
275
276 81
            $GLOBALS['TSFE']->sys_page = $pageSelect;
277 81
            $initializedPageSelect = true;
278
        }
279
            /** @var $tmpl ExtendedTemplateService */
280 151
        $tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
281 151
        $tmpl->tt_track = false; // Do not log time-performance information
282 151
        $tmpl->init();
283 151
        $tmpl->runThroughTemplates($rootLine); // This generates the constants/config + hierarchy info for the template.
284 151
        $tmpl->generateConfig();
285
286 151
        $getConfigurationFromInitializedTSFEAndWriteToCache = $tmpl->ext_getSetup($tmpl->setup, $path);
287 151
        $configurationToUse = $getConfigurationFromInitializedTSFEAndWriteToCache[0];
288
289 151
        if ($initializedPageSelect) {
290 81
            $GLOBALS['TSFE']->sys_page = null;
291
        }
292 151
        if ($initializedTsfe) {
293 81
            unset($GLOBALS['TSFE']);
294
        }
295 151
        return $configurationToUse;
296
    }
297
298
    /**
299
     * Initializes the TSFE for a given page ID and language.
300
     *
301
     * @param int $pageId The page id to initialize the TSFE for
302
     * @param int $language System language uid, optional, defaults to 0
303
     * @param bool $useCache Use cache to reuse TSFE
304
     * @return void
305
     */
306 24
    public static function initializeTsfe($pageId, $language = 0, $useCache = true)
307
    {
308 24
        static $tsfeCache = [];
309
310
        // resetting, a TSFE instance with data from a different page Id could be set already
311 24
        unset($GLOBALS['TSFE']);
312
313 24
        $cacheId = $pageId . '|' . $language;
314
315 24
        if (!is_object($GLOBALS['TT'])) {
316 24
            $GLOBALS['TT'] = GeneralUtility::makeInstance(TimeTracker::class, false);
317
        }
318
319 24
        if (!isset($tsfeCache[$cacheId]) || !$useCache) {
320 24
            GeneralUtility::_GETset($language, 'L');
321
322 24
            $GLOBALS['TSFE'] = GeneralUtility::makeInstance(TypoScriptFrontendController::class,
323 24
                $GLOBALS['TYPO3_CONF_VARS'], $pageId, 0);
324
325
            // for certain situations we need to trick TSFE into granting us
326
            // access to the page in any case to make getPageAndRootline() work
327
            // see http://forge.typo3.org/issues/42122
328 24
            $pageRecord = BackendUtility::getRecord('pages', $pageId, 'fe_group');
329 24
            $groupListBackup = $GLOBALS['TSFE']->gr_list;
330 24
            $GLOBALS['TSFE']->gr_list = $pageRecord['fe_group'];
331
332 24
            $GLOBALS['TSFE']->sys_page = GeneralUtility::makeInstance(PageRepository::class);
333 24
            $GLOBALS['TSFE']->getPageAndRootline();
334
335
            // restore gr_list
336 24
            $GLOBALS['TSFE']->gr_list = $groupListBackup;
337
338 24
            $GLOBALS['TSFE']->initTemplate();
339 24
            $GLOBALS['TSFE']->forceTemplateParsing = true;
340 24
            $GLOBALS['TSFE']->initFEuser();
341 24
            $GLOBALS['TSFE']->initUserGroups();
342
            //  $GLOBALS['TSFE']->getCompressedTCarray(); // seems to cause conflicts sometimes
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
343
344 24
            $GLOBALS['TSFE']->no_cache = true;
345 24
            $GLOBALS['TSFE']->tmpl->start($GLOBALS['TSFE']->rootLine);
346 24
            $GLOBALS['TSFE']->no_cache = false;
347 24
            $GLOBALS['TSFE']->getConfigArray();
348
349 24
            $GLOBALS['TSFE']->settingLanguage();
350 24
            if (!$useCache) {
351
                $GLOBALS['TSFE']->settingLocale();
352
            }
353
354 24
            $GLOBALS['TSFE']->newCObj();
355 24
            $GLOBALS['TSFE']->absRefPrefix = self::getAbsRefPrefixFromTSFE($GLOBALS['TSFE']);
356 24
            $GLOBALS['TSFE']->calculateLinkVars();
357
358 24
            if ($useCache) {
359 24
                $tsfeCache[$cacheId] = $GLOBALS['TSFE'];
360
            }
361
        }
362
363 24
        if ($useCache) {
364 24
            $GLOBALS['TSFE'] = $tsfeCache[$cacheId];
365 24
            $GLOBALS['TSFE']->settingLocale();
366
        }
367 24
    }
368
369
    /**
370
     * Check if record ($table, $uid) is a workspace record
371
     *
372
     * @param string $table The table the record belongs to
373
     * @param int $uid The record's uid
374
     * @return bool TRUE if the record is in a draft workspace, FALSE if it's a LIVE record
375
     */
376 39
    public static function isDraftRecord($table, $uid)
377
    {
378 39
        $isWorkspaceRecord = false;
379
380 39
        if ((ExtensionManagementUtility::isLoaded('workspaces')) && (BackendUtility::isTableWorkspaceEnabled($table))) {
381
            $record = BackendUtility::getRecord($table, $uid, 'pid, t3ver_state');
382
383
            if ($record['pid'] == '-1' || $record['t3ver_state'] > 0) {
384
                $isWorkspaceRecord = true;
385
            }
386
        }
387
388 39
        return $isWorkspaceRecord;
389
    }
390
391
    /**
392
     * Checks whether a record is a localization overlay.
393
     *
394
     * @param string $tableName The record's table name
395
     * @param array $record The record to check
396
     * @return bool TRUE if the record is a language overlay, FALSE otherwise
397
     */
398 32
    public static function isLocalizedRecord($tableName, array $record)
399
    {
400 32
        $isLocalizedRecord = false;
401
402 32
        if (isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])) {
403 7
            $translationOriginalPointerField = $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'];
404
405 7
            if ($record[$translationOriginalPointerField] > 0) {
406 3
                $isLocalizedRecord = true;
407
            }
408
        }
409
410 32
        return $isLocalizedRecord;
411
    }
412
413
    /**
414
     * Check if the page type of a page record is allowed
415
     *
416
     * @param array $pageRecord The pages database row
417
     * @param string $configurationName The name of the configuration to use.
418
     *
419
     * @return bool TRUE if the page type is allowed, otherwise FALSE
420
     */
421 30
    public static function isAllowedPageType(array $pageRecord, $configurationName = 'pages')
422
    {
423 30
        $isAllowedPageType = false;
424 30
        $configurationName = is_null($configurationName) ? 'pages' : $configurationName;
425 30
        $allowedPageTypes = self::getAllowedPageTypes($pageRecord['uid'], $configurationName);
426
427 30
        if (in_array($pageRecord['doktype'], $allowedPageTypes)) {
428 29
            $isAllowedPageType = true;
429
        }
430
431 30
        return $isAllowedPageType;
432
    }
433
434
    /**
435
     * Get allowed page types
436
     *
437
     * @param int $pageId Page ID
438
     * @param string $configurationName The name of the configuration to use.
439
     *
440
     * @return array Allowed page types to compare to a doktype of a page record
441
     */
442 30
    public static function getAllowedPageTypes($pageId, $configurationName = 'pages')
443
    {
444 30
        $rootPath = '';
445 30
        $configuration = self::getConfigurationFromPageId($pageId, $rootPath);
446 30
        return $configuration->getIndexQueueAllowedPageTypesArrayByConfigurationName($configurationName);
447
    }
448
449
    /**
450
     * Resolves the configured absRefPrefix to a valid value and resolved if absRefPrefix
451
     * is set to "auto".
452
     *
453
     * @param TypoScriptFrontendController $TSFE
454
     * @return string
455
     */
456 24
    public static function getAbsRefPrefixFromTSFE(TypoScriptFrontendController $TSFE)
457
    {
458 24
        $absRefPrefix = '';
459 24
        if (empty($TSFE->config['config']['absRefPrefix'])) {
460 21
            return $absRefPrefix;
461
        }
462
463 3
        $absRefPrefix = trim($TSFE->config['config']['absRefPrefix']);
464 3
        if ($absRefPrefix === 'auto') {
465 1
            $absRefPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
466
        }
467
468 3
        return $absRefPrefix;
469
    }
470
471
    /**
472
     * @todo This method is just added for pages_language_overlay compatibility checks and will be removed when TYPO8 support is dropped
473
     * @return boolean
474
     */
475 235
    public static function getIsTYPO3VersionBelow9()
476
    {
477 235
        return (bool)version_compare(TYPO3_branch, '9.0', '<');
478
    }
479
480
    /**
481
     * @todo This method is just added for pages_language_overlay compatibility checks and will be removed when TYPO8 support is dropped
482
     * @return string
483
     */
484
    public static function getPageOverlayTableName()
485
    {
486
        return self::getIsTYPO3VersionBelow9() ? 'pages_language_overlay' : 'pages';
487
    }
488
489
    /**
490
     * This function can be used to check if one of the strings in needles is
491
     * contained in the haystack.
492
     *
493
     *
494
     * Example:
495
     *
496
     * haystack: the brown fox
497
     * needles: ['hello', 'world']
498
     * result: false
499
     *
500
     * haystack: the brown fox
501
     * needles: ['is', 'fox']
502
     * result: true
503
     *
504
     * @param string $haystack
505
     * @param array $needles
506
     * @return bool
507
     */
508 52
    public static function containsOneOfTheStrings($haystack, array $needles)
509
    {
510 52
        foreach ($needles as $needle) {
511 52
            $position = strpos($haystack, $needle);
512 52
            if ($position !== false) {
513 52
                return true;
514
            }
515
        }
516
517 49
        return false;
518
    }
519
}
520