Passed
Push — master ( ed38f6...30aafa )
by Timo
11:15
created

SiteRepository::getDefaultLanguage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 11
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
nc 1
nop 1
crap 1
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
    public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null)
72 169
    {
73
        $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 169
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
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
86 107
    {
87
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
88 107
        return $this->getSiteByRootPageId($rootPageId);
89 107
    }
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
    public function getSiteByRootPageId($rootPageId)
98 123
    {
99
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
100 123
101
        $methodResult = $this->runtimeCache->get($cacheId);
102 123
        if (!empty($methodResult)) {
103 123
            return $methodResult;
104 92
        }
105
106
        $methodResult = $this->buildSite($rootPageId);
107 123
        $this->runtimeCache->set($cacheId, $methodResult);
108 118
109
        return $methodResult;
110 118
    }
111
112
    /**
113
     * Returns the first available Site.
114
     *
115
     * @param bool $stopOnInvalidSite
116
     * @return Site
117
     */
118
    public function getFirstAvailableSite($stopOnInvalidSite = false)
119 22
    {
120
        $sites = $this->getAvailableSites($stopOnInvalidSite);
121 22
        return array_shift($sites);
122 22
    }
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
    public function getAvailableSites($stopOnInvalidSite = false)
131 67
    {
132
        $sites = [];
133 67
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
134 67
135
        $methodResult = $this->runtimeCache->get($cacheId);
136 67
        if (!empty($methodResult)) {
137 67
            return $methodResult;
138 16
        }
139
140
        $servers = $this->getSolrServersFromRegistry();
141 67
        foreach ($servers as $server) {
142 67
            if (isset($sites[$server['rootPageUid']])) {
143 67
                //get each site only once
144
                continue;
145 9
            }
146
147
            try {
148
                $sites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']);
149 67
            } catch (\InvalidArgumentException $e) {
150
                if ($stopOnInvalidSite) {
151
                    throw $e;
152 67
                }
153
            }
154
        }
155
156
        $methodResult = $sites;
157 67
        $this->runtimeCache->set($cacheId, $methodResult);
158 67
159
        return $methodResult;
160 67
    }
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
    public function getAllLanguages(Site $site)
169 1
    {
170
        $siteLanguages = [];
171 1
        $servers = $this->getSolrServersFromRegistry();
172 1
173
        foreach ($servers as $connectionKey => $solrConnection) {
174 1
            list($siteRootPageId, $systemLanguageId) = explode('|', $connectionKey);
175 1
176
            if ($siteRootPageId == $site->getRootPageId()) {
177 1
                $siteLanguages[] = $systemLanguageId;
178 1
            }
179
        }
180
181
        return $siteLanguages;
182 1
    }
183
184
    /**
185
     * Creates an instance of the Site object.
186
     *
187
     * @param integer $rootPageId
188
     * @throws \InvalidArgumentException
189
     * @return Site
190
     */
191
    protected function buildSite($rootPageId)
192 149
    {
193
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
194 149
195
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
196 149
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageId);
197 144
        $domain = $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId);
198 144
        $siteHash = $this->getSiteHashForDomain($domain);
199 144
        $defaultLanguage = $this->getDefaultLanguage($rootPageId);
200
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
201 144
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
            /** @scrutinizer ignore-type */ $siteHash,
208
            /** @scrutinizer ignore-type */ $pageRepository,
209
            /** @scrutinizer ignore-type */ $defaultLanguage
210
        );
211
    }
212
213
    /**
214
     * Retrieves the default language by the rootPageId of a site.
215 67
     *
216
     * @param int $rootPageId
217 67
     * @return int|mixed
218 67
     */
219
    protected function getDefaultLanguage($rootPageId)
220
    {
221
        $siteDefaultLanguage = 0;
222
223
        $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
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage);
228 144
229 144
        return $siteDefaultLanguage;
230 144
    }
231 143
232 143
    /**
233 143
     * Retrieves the configured solr servers from the registry.
234 143
     *
235
     * @return array
236
     */
237 1
    protected function getSolrServersFromRegistry()
238
    {
239
        $servers = (array)$this->registry->get('tx_solr', 'servers', []);
240
        return $servers;
241
    }
242
243
    /**
244 144
     * @param $rootPageId
245
     * @return NULL|string
246
     */
247 144
    protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId)
248 144
    {
249 144
            /** @var $siteService SiteService */
250
        $siteService = GeneralUtility::makeInstance(SiteService::class);
251
        $domain = $siteService->getFirstDomainForRootPage($rootPageId);
252
        if ($domain === '') {
253
            $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
254
            $rootLine = $pageSelect->getRootLine($rootPageId);
255
            $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
            return (string)$domain;
257 149
        }
258
259 149
        return $domain;
260 4
    }
261 4
262 4
    /**
263
     * @param string $domain
264
     * @return string
265
     */
266 145
    protected function getSiteHashForDomain($domain)
267 1
    {
268 1
        /** @var $siteHashService SiteHashService */
269 1
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
270
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
271
        return $siteHash;
272 144
    }
273
274
    /**
275
     * @param int $rootPageId
276
     * @param array $rootPageRecord
277
     * @throws \InvalidArgumentException
278
     */
279
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
280
    {
281
        if (empty($rootPageRecord)) {
282
            throw new \InvalidArgumentException(
283
                '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
                1487326416
285
            );
286
        }
287
288
        if (!Site::isRootPage($rootPageRecord)) {
289
            throw new \InvalidArgumentException(
290
                '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
                1309272922
292
            );
293
        }
294
    }
295
}
296