Passed
Push — master ( 9c6cd5...151fd1 )
by Timo
25:51
created

SiteRepository   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Test Coverage

Coverage 97.8%

Importance

Changes 0
Metric Value
wmc 23
eloc 83
dl 0
loc 247
ccs 89
cts 91
cp 0.978
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getSiteHashForDomain() 0 6 1
A getFirstAvailableSite() 0 4 1
A validateRootPageRecord() 0 13 3
A getAllLanguages() 0 14 3
A getSiteByPageId() 0 4 1
A getSolrServersFromRegistry() 0 4 1
A getDefaultLanguage() 0 11 1
A getAvailableSites() 0 30 6
A __construct() 0 5 1
A buildSite() 0 19 1
A getDomainFromConfigurationOrFallbackToDomainRecord() 0 13 2
A getSiteByRootPageId() 0 13 2
1
<?php
2
3
namespace ApacheSolrForTypo3\Solr\Domain\Site;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2017 - Thomas Hohn <[email protected]>
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 3 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver;
29
use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache;
30
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
31
use ApacheSolrForTypo3\Solr\System\Service\SiteService;
32
use ApacheSolrForTypo3\Solr\Util;
33
use TYPO3\CMS\Backend\Utility\BackendUtility;
34
use TYPO3\CMS\Core\Registry;
35
use TYPO3\CMS\Core\Utility\GeneralUtility;
36
use TYPO3\CMS\Frontend\Page\PageRepository;
37
38
/**
39
 * SiteRepository
40
 *
41
 * Responsible to retrieve instances of Site objects
42
 *
43
 * @author Thomas Hohn <[email protected]>
44
 */
45
class SiteRepository
46
{
47
    /**
48
     * Rootpage resolver
49
     *
50
     * @var RootPageResolver
51
     */
52
    protected $rootPageResolver;
53
54
    /**
55
     * @var TwoLevelCache
56
     */
57
    protected $runtimeCache;
58
59
    /**
60
     * @var Registry
61
     */
62
    protected $registry;
63
64
    /**
65
     * SiteRepository constructor.
66
     *
67
     * @param RootPageResolver|null $rootPageResolver
68
     * @param TwoLevelCache|null $twoLevelCache
69
     * @param Registry|null $registry
70
     */
71 169
    public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null)
72
    {
73 169
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
74 169
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */ 'cache_runtime');
75 169
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
76 169
    }
77
78
    /**
79
     * Gets the Site for a specific page Id.
80
     *
81
     * @param int $pageId The page Id to get a Site object for.
82
     * @param string $mountPointIdentifier
83
     * @return Site Site for the given page Id.
84
     */
85 107
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
86
    {
87 107
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
88 107
        return $this->getSiteByRootPageId($rootPageId);
89
    }
90
91
    /**
92
     * Gets the Site for a specific root page Id.
93
     *
94
     * @param int $rootPageId Root page Id to get a Site object for.
95
     * @return Site Site for the given page Id.
96
     */
97 123
    public function getSiteByRootPageId($rootPageId)
98
    {
99 123
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
100
101 123
        $methodResult = $this->runtimeCache->get($cacheId);
102 123
        if (!empty($methodResult)) {
103 92
            return $methodResult;
104
        }
105
106 123
        $methodResult = $this->buildSite($rootPageId);
107 118
        $this->runtimeCache->set($cacheId, $methodResult);
108
109 118
        return $methodResult;
110
    }
111
112
    /**
113
     * Returns the first available Site.
114
     *
115
     * @param bool $stopOnInvalidSite
116
     * @return Site
117
     */
118 22
    public function getFirstAvailableSite($stopOnInvalidSite = false)
119
    {
120 22
        $sites = $this->getAvailableSites($stopOnInvalidSite);
121 22
        return array_shift($sites);
122
    }
123
124
    /**
125
     * Gets all available TYPO3 sites with Solr configured.
126
     *
127
     * @param bool $stopOnInvalidSite
128
     * @return Site[] An array of available sites
129
     */
130 67
    public function getAvailableSites($stopOnInvalidSite = false)
131
    {
132 67
        $sites = [];
133 67
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
134
135 67
        $methodResult = $this->runtimeCache->get($cacheId);
136 67
        if (!empty($methodResult)) {
137 16
            return $methodResult;
138
        }
139
140 67
        $servers = $this->getSolrServersFromRegistry();
141 67
        foreach ($servers as $server) {
142 67
            if (isset($sites[$server['rootPageUid']])) {
143
                //get each site only once
144 9
                continue;
145
            }
146
147
            try {
148 67
                $sites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']);
149
            } catch (\InvalidArgumentException $e) {
150
                if ($stopOnInvalidSite) {
151 67
                    throw $e;
152
                }
153
            }
154
        }
155
156 67
        $methodResult = $sites;
157 67
        $this->runtimeCache->set($cacheId, $methodResult);
158
159 67
        return $methodResult;
160
    }
161
162
    /**
163
     * Gets the system languages (IDs) for which Solr connections have been
164
     * configured.
165
     *
166
     * @return array Array of system language IDs for which connections have been configured on this site.
167
     */
168 1
    public function getAllLanguages(Site $site)
169
    {
170 1
        $siteLanguages = [];
171 1
        $servers = $this->getSolrServersFromRegistry();
172
173 1
        foreach ($servers as $connectionKey => $solrConnection) {
174 1
            list($siteRootPageId, $systemLanguageId) = explode('|', $connectionKey);
175
176 1
            if ($siteRootPageId == $site->getRootPageId()) {
177 1
                $siteLanguages[] = $systemLanguageId;
178
            }
179
        }
180
181 1
        return $siteLanguages;
182
    }
183
184
    /**
185
     * Creates an instance of the Site object.
186
     *
187
     * @param integer $rootPageId
188
     * @throws \InvalidArgumentException
189
     * @return Site
190
     */
191 149
    protected function buildSite($rootPageId)
192
    {
193 149
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
194
195 149
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
196 144
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageId);
197 144
        $domain = $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId);
198 144
        $siteHash = $this->getSiteHashForDomain($domain);
199 144
        $defaultLanguage = $this->getDefaultLanguage($rootPageId);
200 144
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
201
202 144
        return GeneralUtility::makeInstance(
203 144
            Site::class,
204 144
            /** @scrutinizer ignore-type */ $solrConfiguration,
205 144
            /** @scrutinizer ignore-type */ $rootPageRecord,
206 144
            /** @scrutinizer ignore-type */ $domain,
207 144
            /** @scrutinizer ignore-type */ $siteHash,
208 144
            /** @scrutinizer ignore-type */ $pageRepository,
209 144
            /** @scrutinizer ignore-type */ $defaultLanguage
210
        );
211
    }
212
213
    /**
214
     * Retrieves the default language by the rootPageId of a site.
215
     *
216
     * @param int $rootPageId
217
     * @return int|mixed
218
     */
219 144
    protected function getDefaultLanguage($rootPageId)
220
    {
221 144
        $siteDefaultLanguage = 0;
222
223 144
        $configuration = Util::getConfigurationFromPageId($rootPageId, 'config');
224
225 144
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('sys_language_uid', $siteDefaultLanguage);
226
        // default language is set through default L GET parameter -> overruling config.sys_language_uid
227 144
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage);
228
229 144
        return $siteDefaultLanguage;
230
    }
231
232
    /**
233
     * Retrieves the configured solr servers from the registry.
234
     *
235
     * @return array
236
     */
237 67
    protected function getSolrServersFromRegistry()
238
    {
239 67
        $servers = (array)$this->registry->get('tx_solr', 'servers', []);
240 67
        return $servers;
241
    }
242
243
    /**
244
     * @param $rootPageId
245
     * @return NULL|string
246
     */
247 144
    protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId)
248
    {
249
            /** @var $siteService SiteService */
250 144
        $siteService = GeneralUtility::makeInstance(SiteService::class);
251 144
        $domain = $siteService->getFirstDomainForRootPage($rootPageId);
252 144
        if ($domain === '') {
253 143
            $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
254 143
            $rootLine = $pageSelect->getRootLine($rootPageId);
255 143
            $domain = BackendUtility::firstDomainRecord($rootLine);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Backend\Utilit...ty::firstDomainRecord() has been deprecated: since TYPO3 v9.4, will be removed in TYPO3 v10.0. Use Link Generation / Router instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

255
            $domain = /** @scrutinizer ignore-deprecated */ BackendUtility::firstDomainRecord($rootLine);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
256 143
            return (string)$domain;
257
        }
258
259 1
        return $domain;
260
    }
261
262
    /**
263
     * @param string $domain
264
     * @return string
265
     */
266 144
    protected function getSiteHashForDomain($domain)
267
    {
268
        /** @var $siteHashService SiteHashService */
269 144
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
270 144
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
271 144
        return $siteHash;
272
    }
273
274
    /**
275
     * @param int $rootPageId
276
     * @param array $rootPageRecord
277
     * @throws \InvalidArgumentException
278
     */
279 149
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
280
    {
281 149
        if (empty($rootPageRecord)) {
282 4
            throw new \InvalidArgumentException(
283 4
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' could not be found in the database and can therefore not be used as site root rootPageRecord.',
284 4
                1487326416
285
            );
286
        }
287
288 145
        if (!Site::isRootPage($rootPageRecord)) {
289 1
            throw new \InvalidArgumentException(
290 1
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
291 1
                1309272922
292
            );
293
        }
294 144
    }
295
}
296