Passed
Pull Request — release-11.2.x (#3594)
by Markus
14:43 queued 10:47
created

SiteRepository::getSiteHashForDomain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
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\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;
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
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
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
100 188
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'runtime');
101 188
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
102 188
        $this->siteFinder = $siteFinder ?? GeneralUtility::makeInstance(SiteFinder::class);
103 188
        $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class);
104 188
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
105 188
    }
106 188
107
    /**
108
     * Gets the Site for a specific page Id.
109
     *
110
     * @param int $pageId The page Id to get a Site object for.
111
     * @param string $mountPointIdentifier
112
     * @return SiteInterface Site for the given page Id.
113
     */
114
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
115 77
    {
116
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
117 77
        return $this->getSiteByRootPageId($rootPageId);
118 77
    }
119
120
    /**
121
     * Gets the Site for a specific root page Id.
122
     *
123
     * @param int $rootPageId Root page Id to get a Site object for.
124
     * @return SiteInterface Site for the given page Id.
125
     */
126
    public function getSiteByRootPageId($rootPageId)
127 99
    {
128
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
129 99
130
        $methodResult = $this->runtimeCache->get($cacheId);
131 99
        if (!empty($methodResult)) {
132 99
            return $methodResult;
133 72
        }
134
135
        $methodResult = $this->buildSite($rootPageId);
136 99
        $this->runtimeCache->set($cacheId, $methodResult);
137 92
138
        return $methodResult;
139 92
    }
140
141
    /**
142
     * Returns the first available Site.
143
     *
144
     * @param bool $stopOnInvalidSite
145
     * @throws \Exception
146
     * @return Site
147
     */
148
    public function getFirstAvailableSite($stopOnInvalidSite = false)
149 21
    {
150
        $sites = $this->getAvailableSites($stopOnInvalidSite);
151 21
        return array_shift($sites);
152 21
    }
153
154
    /**
155
     * Gets all available TYPO3 sites with Solr configured.
156
     *
157
     * @param bool $stopOnInvalidSite
158
     * @throws \Exception
159
     * @return Site[] An array of availablesites
160
     */
161
    public function getAvailableSites($stopOnInvalidSite = false)
162 102
    {
163
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
164 102
165
        $sites = $this->runtimeCache->get($cacheId);
166 102
        if (!empty($sites)) {
167 102
            return $sites;
168 22
        }
169
170
        $sites = $this->getAvailableTYPO3ManagedSites($stopOnInvalidSite);
171 102
        $this->runtimeCache->set($cacheId, $sites);
172 102
173
        return $sites;
174 102
    }
175
176
    /**
177
     * @param bool $stopOnInvalidSite
178
     * @return array
179
     * @throws \Exception
180
     */
181
    protected function getAvailableTYPO3ManagedSites(bool $stopOnInvalidSite): array
182 102
    {
183
        $typo3ManagedSolrSites = [];
184 102
        $typo3Sites = $this->siteFinder->getAllSites();
185 102
        foreach ($typo3Sites as $typo3Site) {
186 102
            try {
187
                $rootPageId = $typo3Site->getRootPageId();
188 102
                if (isset($typo3ManagedSolrSites[$rootPageId])) {
189 102
                    //get each site only once
190
                    continue;
191
                }
192
                $typo3ManagedSolrSite = $this->buildSite($rootPageId);
193 102
                if ($typo3ManagedSolrSite->isEnabled()) {
194 96
                    $typo3ManagedSolrSites[$rootPageId] = $typo3ManagedSolrSite;
195 96
                }
196
            } catch (\Exception $e) {
197
                if ($stopOnInvalidSite) {
198 98
                    throw $e;
199 98
                }
200
            }
201
        }
202
        return $typo3ManagedSolrSites;
203
    }
204 102
205
    /**
206
    * Creates an instance of the Site object.
207
    *
208
    * @param int $rootPageId
209
    * @throws \InvalidArgumentException
210
    * @return SiteInterface
211
    */
212
    protected function buildSite($rootPageId)
213
    {
214 162
        if (empty($rootPageId)) {
215
            throw new \InvalidArgumentException('Root page id can not be empty');
216 162
        }
217
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
218
219 162
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
220
221 162
        return $this->buildTypo3ManagedSite($rootPageRecord);
222
    }
223 151
224
    /**
225
     * @param string $domain
226
     * @return string
227
     */
228
    protected function getSiteHashForDomain($domain)
229
    {
230 151
        /** @var $siteHashService SiteHashService */
231
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
232
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
233 151
        return $siteHash;
234 151
    }
235 151
236
    /**
237
     * @param int $rootPageId
238
     * @param array $rootPageRecord
239
     * @throws \InvalidArgumentException
240
     */
241
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
242
    {
243 162
        if (empty($rootPageRecord)) {
244
            throw new \InvalidArgumentException(
245 162
                '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.',
246 104
                1487326416
247 104
            );
248 104
        }
249
250
        if (!Site::isRootPage($rootPageRecord)) {
251
            throw new \InvalidArgumentException(
252 152
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
253 4
                1309272922
254 4
            );
255 4
        }
256
    }
257
258 151
    /**
259
     * @param array $rootPageRecord
260
     * @return Typo3ManagedSite
261
     */
262
    protected function buildTypo3ManagedSite(array $rootPageRecord): ?Typo3ManagedSite
263
    {
264 151
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($rootPageRecord['uid'], Util::getLanguageUid());
265
        /** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
266 151
        try {
267
            $typo3Site = $this->siteFinder->getSiteByPageId($rootPageRecord['uid']);
268
        } catch (SiteNotFoundException $e) {
269 151
            return null;
270
        }
271
        $domain = $typo3Site->getBase()->getHost();
272
273 151
        $siteHash = $this->getSiteHashForDomain($domain);
274
        $defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
275 151
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
276 151
        $availableLanguageIds = array_map(function ($language) {
277 151
            return $language->getLanguageId();
278
        }, $typo3Site->getLanguages());
279 151
280 151
        $solrConnectionConfigurations = [];
281
282 151
        foreach ($availableLanguageIds as $languageUid) {
283
            $solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true);
284 151
            if ($solrEnabled) {
285 151
                $solrConnectionConfigurations[$languageUid] = [
286 151
                    'connectionKey' =>  $rootPageRecord['uid'] . '|' . $languageUid,
287 151
                    'rootPageTitle' => $rootPageRecord['title'],
288 151
                    'rootPageUid' => $rootPageRecord['uid'],
289 151
                    'read' => [
290 151
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
291
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
292 151
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
293 151
                        // @todo: transform core to path
294 151
                        'path' =>
295
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
296
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
297 151
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
298 151
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''),
299 151
                    ],
300 151
                    'write' => [
301
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
302
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
303 151
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
304 151
                        // @todo: transform core to path
305 151
                        'path' =>
306
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'write', '/solr/') .
307
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'write', 'core_en') . '/' ,
308 151
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
309 151
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''),
310 151
                    ],
311 151
312
                    'language' => $languageUid,
313
                ];
314 151
            }
315
        }
316
317
        return GeneralUtility::makeInstance(
318
            Typo3ManagedSite::class,
319 151
            /** @scrutinizer ignore-type */
320
            $solrConfiguration,
321
            /** @scrutinizer ignore-type */
322 151
            $rootPageRecord,
323
            /** @scrutinizer ignore-type */
324 151
            $domain,
325
            /** @scrutinizer ignore-type */
326 151
            $siteHash,
327
            /** @scrutinizer ignore-type */
328 151
            $pageRepository,
329
            /** @scrutinizer ignore-type */
330 151
            $defaultLanguage,
331
            /** @scrutinizer ignore-type */
332 151
            $availableLanguageIds,
333
            /** @scrutinizer ignore-type */
334 151
            $solrConnectionConfigurations,
335
            /** @scrutinizer ignore-type */
336 151
            $typo3Site
337
        );
338 151
    }
339
}
340