Passed
Pull Request — master (#1249)
by
unknown
19:13
created

Site   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 369
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 92.22%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 30
lcom 1
cbo 5
dl 0
loc 369
ccs 83
cts 90
cp 0.9222
rs 10
c 1
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 22 3
A getRootPageId() 0 4 1
A getLanguages() 0 6 1
A getRootPage() 0 4 1
A clearSitePagesCache() 0 4 1
A isRootPage() 0 8 2
A getSolrConfiguration() 0 4 1
A getDefaultLanguage() 0 15 1
A getSiteHash() 0 6 1
A getDomain() 0 7 1
A getTitle() 0 4 1
A getSiteByPageId() 0 7 1
A getAvailableSitesSelector() 0 9 1
A getAvailableSites() 0 7 1
A getFirstAvailableSite() 0 7 1
A getLabel() 0 12 2
B getPages() 0 30 4
B getPageIdsFromCurrentDepthAndCallRecursive() 0 25 4
A getSysLanguageMode() 0 9 2
1
<?php
2
namespace ApacheSolrForTypo3\Solr;
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\Backend\SiteSelectorField;
28
use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService;
29
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\ConfigurationAwareRecordService;
30
use TYPO3\CMS\Backend\Utility\BackendUtility;
31
use TYPO3\CMS\Core\Utility\GeneralUtility;
32
use TYPO3\CMS\Frontend\Page\PageRepository;
33
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
34
35
/**
36
 * A site is a branch in a TYPO3 installation. Each site's root page is marked
37
 * by the "Use as Root Page" flag.
38
 *
39
 * @author Ingo Renner <[email protected]>
40
 */
41
class Site
42
{
43
    /**
44
     * Cache for ApacheSolrForTypo3\Solr\Site objects
45
     *
46
     * @var array
47
     */
48
    protected static $sitesCache = [];
49
50
    /**
51
     * Small cache for the list of pages in a site, so that the results of this
52
     * rather expensive operation can be used by all initializers without having
53
     * each initializer do it again.
54
     *
55
     * TODO Move to caching framework once TYPO3 4.6 is the minimum required
56
     * version.
57
     *
58
     * @var array
59
     */
60
    protected static $sitePagesCache = [];
61
62
    /**
63
     * Root page record.
64
     *
65
     * @var array
66
     */
67
    protected $rootPage = [];
68
69
    /**
70
     * The site's sys_language_mode
71
     *
72
     * @var string
73
     */
74
    protected $sysLanguageMode = null;
75
76
    /**
77
     * Constructor.
78
     *
79
     * @param int $rootPageId Site root page ID (uid). The page must be marked as site root ("Use as Root Page" flag).
80
     */
81 113
    public function __construct($rootPageId)
82
    {
83 113
        $page = (array)BackendUtility::getRecord('pages', $rootPageId);
84
85 113
        if (empty($page)) {
86 8
            throw new \InvalidArgumentException(
87
                'The page for the given page ID \'' . $rootPageId
88 8
                . '\' could not be found in the database and can therefore not be used as site root page.',
89
                1487326416
90 8
            );
91
        }
92
93 105
        if (!self::isRootPage($page)) {
94 1
            throw new \InvalidArgumentException(
95
                'The page for the given page ID \'' . $rootPageId
96 1
                . '\' is not marked as root page and can therefore not be used as site root page.',
97
                1309272922
98 1
            );
99
        }
100
101 104
        $this->rootPage = $page;
102 104
    }
103
104
    /**
105
     * Gets the Site for a specific page Id.
106
     *
107
     * @param int $pageId The page Id to get afunction Site object for.
108
     * @return Site Site for the given page Id.
109
     * @deprecated since 6.1 will be removed in 7.0
110
     */
111
    public static function getSiteByPageId($pageId)
112
    {
113
        GeneralUtility::logDeprecatedFunction();
114
115
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
116
        return $siteRepository->getSiteByPageId($pageId);
117
    }
118
119
    /**
120
     * Creates a dropdown selector of available TYPO3 sites with Solr
121
     * configured.
122
     *
123
     * @param string $selectorName Name to be used in the select's name attribute
124
     * @param Site $selectedSite Optional, currently selected site
125
     * @return string Site selector HTML code
126
     * @todo Extract into own class like indexing configuration selector
127
     * @deprecated since 6.1 will be removed in 7.0
128
     */
129
    public static function getAvailableSitesSelector(
130
        $selectorName,
131
        Site $selectedSite = null
132
    ) {
133
        GeneralUtility::logDeprecatedFunction();
134
135
        $siteSelectorField = GeneralUtility::makeInstance(SiteSelectorField::class);
136
        return $siteSelectorField->getAvailableSitesSelector($selectorName, $selectedSite);
137
    }
138
139
    /**
140
     * Gets all available TYPO3 sites with Solr configured.
141
     *
142
     * @param bool $stopOnInvalidSite
143
     *
144
     * @return Site[] An array of available sites
145
     * @deprecated since 6.1 will be removed in 7.0
146
     */
147
    public static function getAvailableSites($stopOnInvalidSite = false)
148
    {
149
        GeneralUtility::logDeprecatedFunction();
150
151
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
152
        return $siteRepository->getAvailableSites($stopOnInvalidSite);
153
    }
154
155
    /**
156
     * Returns the first available Site.
157
     *
158
     * @param bool $stopOnInvalidSite
159
     *
160
     * @return Site
161
     * @deprecated since 6.1 will be removed in 7.0
162
     */
163
    public static function getFirstAvailableSite($stopOnInvalidSite = false)
164
    {
165
        GeneralUtility::logDeprecatedFunction();
166
167
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
168
        return $siteRepository->getFirstAvailableSite($stopOnInvalidSite);
169
    }
170
171
    /**
172
     * Clears the $sitePagesCache
173
     *
174
     */
175
    public static function clearSitePagesCache()
176
    {
177
        self::$sitePagesCache = [];
178
    }
179
180
    /**
181
     * Takes an pagerecord and checks whether the page is marked as root page.
182
     *
183
     * @param array $page pagerecord
184
     * @return bool true if the page is marked as root page, false otherwise
185
     */
186 115
    public static function isRootPage($page)
187
    {
188 115
        if ($page['is_siteroot']) {
189 114
            return true;
190
        }
191
192 56
        return false;
193
    }
194
195
    /**
196
     * Gets the site's root page ID (uid).
197
     *
198
     * @return int The site's root page ID.
199
     */
200 36
    public function getRootPageId()
201
    {
202 36
        return $this->rootPage['uid'];
203
    }
204
205
    /**
206
     * Gets the site's label. The label is build from the the site title and root
207
     * page ID (uid).
208
     *
209
     * @return string The site's label.
210
     */
211 10
    public function getLabel()
212
    {
213 10
        $rootlineTitles = [];
214 10
        $rootLine = BackendUtility::BEgetRootLine($this->rootPage['uid']);
215
        // Remove last
216 10
        array_pop($rootLine);
217 10
        $rootLine = array_reverse($rootLine);
218 10
        foreach ($rootLine as $rootLineItem) {
219 10
            $rootlineTitles[] = $rootLineItem['title'];
220 10
        }
221 10
        return implode(' - ', $rootlineTitles) . ', Root Page ID: ' . $this->rootPage['uid'];
222
    }
223
224
    /**
225
     * Gets the site's Solr TypoScript configuration (plugin.tx_solr.*)
226
     *
227
     * @return  \ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration The Solr TypoScript configuration
228
     */
229 53
    public function getSolrConfiguration()
230
    {
231 53
        return Util::getSolrConfigurationFromPageId($this->rootPage['uid']);
232
    }
233
234
    /**
235
     * Gets the system languages (IDs) for which Solr connections have been
236
     * configured.
237
     *
238
     * @return array Array of system language IDs for which connections have been configured on this site.
239
     * @deprecated since 6.1 will be removed in 7.0
240
     */
241
    public function getLanguages()
242
    {
243
        GeneralUtility::logDeprecatedFunction();
244
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
245
        return $siteRepository->getAllLanguages($this);
246
    }
247
248
    /**
249
     * Gets the site's default language as configured in
250
     * config.sys_language_uid. If sys_language_uid is not set, 0 is assumed to
251
     * be the default.
252
     *
253
     * @return int The site's default language.
254
     */
255 1
    public function getDefaultLanguage()
256
    {
257 1
        $siteDefaultLanguage = 0;
258
259 1
        $configuration = Util::getConfigurationFromPageId(
260 1
            $this->rootPage['uid'],
261
            'config'
262 1
        );
263
264 1
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('sys_language_uid', $siteDefaultLanguage);
265
        // default language is set through default L GET parameter -> overruling config.sys_language_uid
266 1
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage);
267
268 1
        return $siteDefaultLanguage;
269
    }
270
271
    /**
272
     * Generates a list of page IDs in this site. Attention, this includes
273
     * all page types! Deleted pages are not included.
274
     *
275
     * @param int|string $rootPageId Page ID from where to start collection sub pages
276
     * @param int $maxDepth Maximum depth to descend into the site tree
277
     * @return array Array of pages (IDs) in this site
278
     */
279 9
    public function getPages($rootPageId = 'SITE_ROOT', $maxDepth = 999)
280
    {
281 9
        $pageIds = [];
282 9
        $maxDepth = intval($maxDepth);
283
284 9
        if ($rootPageId == 'SITE_ROOT') {
285 9
            $rootPageId = $this->rootPage['uid'];
286 9
            $pageIds[] = (int)$this->rootPage['uid'];
287 9
        }
288
289 9
        $recursionRootPageId = intval($rootPageId);
290
291
        // when we have a cached value, we can return it.
292 9
        if (!empty(self::$sitePagesCache[$rootPageId])) {
293 7
            return self::$sitePagesCache[$rootPageId];
294
        }
295
296 9
        if ($maxDepth <= 0) {
297
            // exiting the recursion loop, may write to cache now
298
            self::$sitePagesCache[$rootPageId] = $pageIds;
299
            return $pageIds;
300
        }
301
302
        // get the page ids of the current level and if needed call getPages recursive
303 9
        $pageIds = $this->getPageIdsFromCurrentDepthAndCallRecursive($maxDepth, $recursionRootPageId, $pageIds);
304
305
        // exiting the recursion loop, may write to cache now
306 9
        self::$sitePagesCache[$rootPageId] = $pageIds;
307 9
        return $pageIds;
308
    }
309
310
    /**
311
     * This method retrieves the pages ids from the current tree level an calls getPages recursive,
312
     * when the maxDepth has not been reached.
313
     *
314
     * @param int $maxDepth
315
     * @param int $recursionRootPageId
316
     * @param array $pageIds
317
     * @return array
318
     */
319 9
    protected function getPageIdsFromCurrentDepthAndCallRecursive($maxDepth, $recursionRootPageId, $pageIds)
320
    {
321 9
        static $initialPagesAdditionalWhereClause;
322
323
        // Only fetch $initialPagesAdditionalWhereClause on first call
324 9
        if (empty($initialPagesAdditionalWhereClause)) {
325 9
            $configurationAwareRecordService = GeneralUtility::makeInstance(ConfigurationAwareRecordService::class);
326
            // Fetch configuration in order to be able to read initialPagesAdditionalWhereClause
327 9
            $solrConfiguration = $this->getSolrConfiguration();
328 9
            $indexQueueConfigurationName = $configurationAwareRecordService->getIndexingConfigurationName('pages', $this->rootPage['uid'], $solrConfiguration);
329 9
            $initialPagesAdditionalWhereClause = $solrConfiguration->getInitialPagesAdditionalWhereClause($indexQueueConfigurationName);
330 9
        }
331
332 9
        $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid = ' . $recursionRootPageId . ' ' . BackendUtility::deleteClause('pages') . $initialPagesAdditionalWhereClause);
333
334 9
        while ($page = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
335 7
            $pageIds[] = (int)$page['uid'];
336
337 7
            if ($maxDepth > 1) {
338 7
                $pageIds = array_merge($pageIds, $this->getPages($page['uid'], $maxDepth - 1));
339 7
            }
340 7
        }
341 9
        $GLOBALS['TYPO3_DB']->sql_free_result($result);
342 9
        return $pageIds;
343
    }
344
345
    /**
346
     * Generates the site's unique Site Hash.
347
     *
348
     * The Site Hash is build from the site's main domain, the system encryption
349
     * key, and the extension "tx_solr". These components are concatenated and
350
     * sha1-hashed.
351
     *
352
     * @return string Site Hash.
353
     */
354 57
    public function getSiteHash()
355
    {
356
        /** @var $siteHashService SiteHashService */
357 57
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
358 57
        return $siteHashService->getSiteHashForDomain($this->getDomain());
359
    }
360
361
    /**
362
     * Gets the site's main domain. More specifically the first domain record in
363
     * the site tree.
364
     *
365
     * @return string The site's main domain.
366
     */
367 61
    public function getDomain()
368
    {
369 61
        $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
370 61
        $rootLine = $pageSelect->getRootLine($this->rootPage['uid']);
371
372 61
        return BackendUtility::firstDomainRecord($rootLine);
373
    }
374
375
    /**
376
     * Gets the site's root page.
377
     *
378
     * @return array The site's root page.
379
     */
380 1
    public function getRootPage()
381
    {
382 1
        return $this->rootPage;
383
    }
384
385
    /**
386
     * Gets the site's root page's title.
387
     *
388
     * @return string The site's root page's title
389
     */
390
    public function getTitle()
391
    {
392
        return $this->rootPage['title'];
393
    }
394
395
    /**
396
     * Gets the site's config.sys_language_mode setting
397
     *
398
     * @return string The site's config.sys_language_mode
399
     */
400 12
    public function getSysLanguageMode()
401
    {
402 12
        if (is_null($this->sysLanguageMode)) {
403 12
            Util::initializeTsfe($this->getRootPageId());
404 12
            $this->sysLanguageMode = $GLOBALS['TSFE']->sys_language_mode;
405 12
        }
406
407 12
        return $this->sysLanguageMode;
408
    }
409
}
410