Passed
Pull Request — release-11.2.x (#3528)
by Rafael
12:34
created

SiteRepository   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 291
Duplicated Lines 0 %

Test Coverage

Coverage 95.37%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 23
eloc 111
c 1
b 0
f 0
dl 0
loc 291
ccs 103
cts 108
cp 0.9537
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A getFirstAvailableSite() 0 4 1
A validateRootPageRecord() 0 13 3
A getSiteHashForDomain() 0 6 1
A getSiteByPageId() 0 4 1
A getAvailableTYPO3ManagedSites() 0 23 6
A getAvailableSites() 0 13 2
A buildSite() 0 10 2
A getSiteByRootPageId() 0 13 2
A buildTypo3ManagedSite() 0 75 4
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\FrontendEnvironment;
30
use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache;
31
use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration;
32
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
33
use ApacheSolrForTypo3\Solr\System\Util\SiteUtility;
34
use ApacheSolrForTypo3\Solr\Util;
35
use TYPO3\CMS\Backend\Utility\BackendUtility;
36
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
37
use TYPO3\CMS\Core\Registry;
38
use TYPO3\CMS\Core\Site\SiteFinder;
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
41
/**
42
 * SiteRepository
43
 *
44
 * Responsible to retrieve instances of Site objects
45
 *
46
 * @author Thomas Hohn <[email protected]>
47
 */
48
class SiteRepository
49
{
50
    /**
51
     * Rootpage resolver
52
     *
53
     * @var RootPageResolver
54
     */
55
    protected $rootPageResolver;
56
57
    /**
58
     * @var TwoLevelCache
59
     */
60
    protected $runtimeCache;
61
62
    /**
63
     * @var Registry
64
     */
65
    protected $registry;
66
67
    /**
68
     * @var SiteFinder
69
     */
70
    protected $siteFinder;
71
72
    /**
73
     * @var ExtensionConfiguration
74
     */
75
    protected $extensionConfiguration;
76
77
    /**
78
     * @var FrontendEnvironment
79
     */
80
    protected $frontendEnvironment = null;
81
82
    /**
83
     * SiteRepository constructor.
84
     *
85
     * @param RootPageResolver|null $rootPageResolver
86
     * @param TwoLevelCache|null $twoLevelCache
87
     * @param Registry|null $registry
88
     * @param SiteFinder|null $siteFinder
89
     * @param ExtensionConfiguration| null
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $ExtensionConfiguration| is correct as it would always require null to be passed?
Loading history...
90
     */
91 188
    public function __construct(
92
        RootPageResolver $rootPageResolver = null,
93
        TwoLevelCache $twoLevelCache = null,
94
        Registry $registry = null,
95
        SiteFinder $siteFinder = null,
96
        ExtensionConfiguration $extensionConfiguration = null,
97
        FrontendEnvironment $frontendEnvironment = null
98
    )
99
    {
100 188
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
101 188
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'runtime');
102 188
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
103 188
        $this->siteFinder = $siteFinder ?? GeneralUtility::makeInstance(SiteFinder::class);
104 188
        $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class);
105 188
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
106 188
    }
107
108
    /**
109
     * Gets the Site for a specific page Id.
110
     *
111
     * @param int $pageId The page Id to get a Site object for.
112
     * @param string $mountPointIdentifier
113
     * @return SiteInterface Site for the given page Id.
114
     */
115 77
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
116
    {
117 77
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
118 77
        return $this->getSiteByRootPageId($rootPageId);
119
    }
120
121
    /**
122
     * Gets the Site for a specific root page Id.
123
     *
124
     * @param int $rootPageId Root page Id to get a Site object for.
125
     * @return SiteInterface Site for the given page Id.
126
     */
127 99
    public function getSiteByRootPageId($rootPageId)
128
    {
129 99
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
130
131 99
        $methodResult = $this->runtimeCache->get($cacheId);
132 99
        if (!empty($methodResult)) {
133 72
            return $methodResult;
134
        }
135
136 99
        $methodResult = $this->buildSite($rootPageId);
137 92
        $this->runtimeCache->set($cacheId, $methodResult);
138
139 92
        return $methodResult;
140
    }
141
142
    /**
143
     * Returns the first available Site.
144
     *
145
     * @param bool $stopOnInvalidSite
146
     * @throws \Exception
147
     * @return Site
148
     */
149 21
    public function getFirstAvailableSite($stopOnInvalidSite = false)
150
    {
151 21
        $sites = $this->getAvailableSites($stopOnInvalidSite);
152 21
        return array_shift($sites);
153
    }
154
155
    /**
156
     * Gets all available TYPO3 sites with Solr configured.
157
     *
158
     * @param bool $stopOnInvalidSite
159
     * @throws \Exception
160
     * @return Site[] An array of availablesites
161
     */
162 102
    public function getAvailableSites($stopOnInvalidSite = false)
163
    {
164 102
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
165
166 102
        $sites = $this->runtimeCache->get($cacheId);
167 102
        if (!empty($sites)) {
168 22
            return $sites;
169
        }
170
171 102
        $sites = $this->getAvailableTYPO3ManagedSites($stopOnInvalidSite);
172 102
        $this->runtimeCache->set($cacheId, $sites);
173
174 102
        return $sites;
175
    }
176
177
    /**
178
     * @param bool $stopOnInvalidSite
179
     * @return array
180
     * @throws \Exception
181
     */
182 102
    protected function getAvailableTYPO3ManagedSites(bool $stopOnInvalidSite): array
183
    {
184 102
        $typo3ManagedSolrSites = [];
185 102
        $typo3Sites = $this->siteFinder->getAllSites();
186 102
        foreach ($typo3Sites as $typo3Site) {
187
            try {
188 102
                $rootPageId = $typo3Site->getRootPageId();
189 102
                if (isset($typo3ManagedSolrSites[$rootPageId])) {
190
                    //get each site only once
191
                    continue;
192
                }
193 102
                $typo3ManagedSolrSite = $this->buildSite($rootPageId);
194 96
                if ($typo3ManagedSolrSite->isEnabled()) {
195 96
                    $typo3ManagedSolrSites[$rootPageId] = $typo3ManagedSolrSite;
196
                }
197
198 98
            } catch (\Exception $e) {
199 98
                if ($stopOnInvalidSite) {
200
                    throw $e;
201
                }
202
            }
203
        }
204 102
        return $typo3ManagedSolrSites;
205
    }
206
207
     /**
208
     * Creates an instance of the Site object.
209
     *
210
     * @param integer $rootPageId
211
     * @throws \InvalidArgumentException
212
     * @return SiteInterface
213
     */
214 162
    protected function buildSite($rootPageId)
215
    {
216 162
        if (empty($rootPageId)) {
217
            throw new \InvalidArgumentException('Root page id can not be empty');
218
        }
219 162
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
220
221 162
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
222
223 151
        return $this->buildTypo3ManagedSite($rootPageRecord);
224
    }
225
226
    /**
227
     * @param string $domain
228
     * @return string
229
     */
230 151
    protected function getSiteHashForDomain($domain)
231
    {
232
        /** @var $siteHashService SiteHashService */
233 151
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
234 151
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
235 151
        return $siteHash;
236
    }
237
238
    /**
239
     * @param int $rootPageId
240
     * @param array $rootPageRecord
241
     * @throws \InvalidArgumentException
242
     */
243 162
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
244
    {
245 162
        if (empty($rootPageRecord)) {
246 104
            throw new \InvalidArgumentException(
247 104
                '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.',
248 104
                1487326416
249
            );
250
        }
251
252 152
        if (!Site::isRootPage($rootPageRecord)) {
253 4
            throw new \InvalidArgumentException(
254 4
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
255 4
                1309272922
256
            );
257
        }
258 151
    }
259
260
    /**
261
     * @param array $rootPageRecord
262
     * @return Typo3ManagedSite
263
     */
264 151
    protected function buildTypo3ManagedSite(array $rootPageRecord): ?Typo3ManagedSite
265
    {
266 151
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($rootPageRecord['uid'], Util::getLanguageUid());
267
        /** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
268
        try {
269 151
            $typo3Site = $this->siteFinder->getSiteByPageId($rootPageRecord['uid']);
270
        } catch (SiteNotFoundException $e) {
271
            return null;
272
        }
273 151
        $domain = $typo3Site->getBase()->getHost();
274
275 151
        $siteHash = $this->getSiteHashForDomain($domain);
276 151
        $defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
277 151
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
278
        $availableLanguageIds = array_map(function($language) {
279 151
            return $language->getLanguageId();
280 151
        }, $typo3Site->getLanguages());
281
282 151
        $solrConnectionConfigurations = [];
283
284 151
        foreach ($availableLanguageIds as $languageUid) {
285 151
            $solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true);
286 151
            if ($solrEnabled) {
287 151
                $solrConnectionConfigurations[$languageUid] = [
288 151
                    'connectionKey' =>  $rootPageRecord['uid'] . '|' . $languageUid,
289 151
                    'rootPageTitle' => $rootPageRecord['title'],
290 151
                    'rootPageUid' => $rootPageRecord['uid'],
291
                    'read' => [
292 151
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
293 151
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
294 151
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
295
                        // @todo: transform core to path
296
                        'path' =>
297 151
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
298 151
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
299 151
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
300 151
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', '')
301
                    ],
302
                    'write' => [
303 151
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
304 151
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
305 151
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
306
                        // @todo: transform core to path
307
                        'path' =>
308 151
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'write', '/solr/') .
309 151
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'write', 'core_en') . '/' ,
310 151
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
311 151
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', '')
312
                    ],
313
314 151
                    'language' => $languageUid
315
                ];
316
            }
317
        }
318
319 151
        return GeneralUtility::makeInstance(
320
            Typo3ManagedSite::class,
321
            /** @scrutinizer ignore-type */
322 151
            $solrConfiguration,
323
            /** @scrutinizer ignore-type */
324 151
            $rootPageRecord,
325
            /** @scrutinizer ignore-type */
326 151
            $domain,
327
            /** @scrutinizer ignore-type */
328 151
            $siteHash,
329
            /** @scrutinizer ignore-type */
330 151
            $pageRepository,
331
            /** @scrutinizer ignore-type */
332 151
            $defaultLanguage,
333
            /** @scrutinizer ignore-type */
334 151
            $availableLanguageIds,
335
            /** @scrutinizer ignore-type */
336 151
            $solrConnectionConfigurations,
337
            /** @scrutinizer ignore-type */
338 151
            $typo3Site
339
        );
340
    }
341
342
}
343