Passed
Push — master ( e1aede...36be10 )
by Timo
33:39 queued 01:53
created

SiteRepository::getAvailableSites()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 13
ccs 8
cts 8
cp 1
rs 10
cc 2
nc 2
nop 1
crap 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\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 TYPO3\CMS\Backend\Utility\BackendUtility;
35
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
36
use TYPO3\CMS\Core\Registry;
37
use TYPO3\CMS\Core\Site\SiteFinder;
38
use TYPO3\CMS\Core\Utility\GeneralUtility;
39
40
/**
41
 * SiteRepository
42
 *
43
 * Responsible to retrieve instances of Site objects
44
 *
45
 * @author Thomas Hohn <[email protected]>
46
 */
47
class SiteRepository
48
{
49
    /**
50
     * Rootpage resolver
51
     *
52
     * @var RootPageResolver
53
     */
54
    protected $rootPageResolver;
55
56
    /**
57
     * @var TwoLevelCache
58
     */
59
    protected $runtimeCache;
60
61
    /**
62
     * @var Registry
63
     */
64
    protected $registry;
65
66
    /**
67
     * @var SiteFinder
68
     */
69
    protected $siteFinder;
70
71
    /**
72
     * @var ExtensionConfiguration
73
     */
74
    protected $extensionConfiguration;
75
76
    /**
77
     * @var FrontendEnvironment
78
     */
79
    protected $frontendEnvironment = null;
80
81
    /**
82
     * SiteRepository constructor.
83
     *
84
     * @param RootPageResolver|null $rootPageResolver
85
     * @param TwoLevelCache|null $twoLevelCache
86
     * @param Registry|null $registry
87
     * @param SiteFinder|null $siteFinder
88
     * @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...
89
     */
90 195
    public function __construct(
91
        RootPageResolver $rootPageResolver = null,
92
        TwoLevelCache $twoLevelCache = null,
93
        Registry $registry = null,
94
        SiteFinder $siteFinder = null,
95
        ExtensionConfiguration $extensionConfiguration = null,
96
        FrontendEnvironment $frontendEnvironment = null
97
    )
98
    {
99 195
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
100 195
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'cache_runtime');
101 195
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
102 195
        $this->siteFinder = $siteFinder ?? GeneralUtility::makeInstance(SiteFinder::class);
103 195
        $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class);
104 195
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
105 195
    }
106
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 113
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
115
    {
116 113
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
117 113
        return $this->getSiteByRootPageId($rootPageId);
118
    }
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 130
    public function getSiteByRootPageId($rootPageId)
127
    {
128 130
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
129
130 130
        $methodResult = $this->runtimeCache->get($cacheId);
131 130
        if (!empty($methodResult)) {
132 98
            return $methodResult;
133
        }
134
135 130
        $methodResult = $this->buildSite($rootPageId);
136 123
        $this->runtimeCache->set($cacheId, $methodResult);
137
138 123
        return $methodResult;
139
    }
140
141
    /**
142
     * Returns the first available Site.
143
     *
144
     * @param bool $stopOnInvalidSite
145
     * @throws \Exception
146
     * @return Site
147
     */
148 21
    public function getFirstAvailableSite($stopOnInvalidSite = false)
149
    {
150 21
        $sites = $this->getAvailableSites($stopOnInvalidSite);
151 21
        return array_shift($sites);
152
    }
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 79
    public function getAvailableSites($stopOnInvalidSite = false)
162
    {
163 79
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
164
165 79
        $sites = $this->runtimeCache->get($cacheId);
166 79
        if (!empty($sites)) {
167 13
            return $sites;
168
        }
169
170 79
        $sites = $this->getAvailableTYPO3ManagedSites($stopOnInvalidSite);
171 79
        $this->runtimeCache->set($cacheId, $sites);
172
173 79
        return $sites;
174
    }
175
176
    /**
177
     * @param bool $stopOnInvalidSite
178
     * @return array
179
     * @throws \Exception
180
     */
181 79
    protected function getAvailableTYPO3ManagedSites(bool $stopOnInvalidSite): array
182
    {
183 79
        $typo3ManagedSolrSites = [];
184 79
        $typo3Sites = $this->siteFinder->getAllSites();
185 79
        foreach ($typo3Sites as $typo3Site) {
186
            try {
187 79
                $rootPageId = $typo3Site->getRootPageId();
188 79
                if (isset($typo3ManagedSolrSites[$rootPageId])) {
189
                    //get each site only once
190
                    continue;
191
                }
192
193 79
                $typo3ManagedSolrSites[$rootPageId] = $this->buildSite($rootPageId);
194
195 68
            } catch (\Exception $e) {
196 68
                if ($stopOnInvalidSite) {
197
                    throw $e;
198
                }
199
            }
200
        }
201 79
        return $typo3ManagedSolrSites;
202
    }
203
204
     /**
205
     * Creates an instance of the Site object.
206
     *
207
     * @param integer $rootPageId
208
     * @throws \InvalidArgumentException
209
     * @return SiteInterface
210
     */
211 170
    protected function buildSite($rootPageId)
212
    {
213 170
        if (empty($rootPageId)) {
214
            throw new \InvalidArgumentException('Root page id can not be empty');
215
        }
216 170
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
217
218 170
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
219
220 159
        return $this->buildTypo3ManagedSite($rootPageRecord);
221
    }
222
223
    /**
224
     * @param string $domain
225
     * @return string
226
     */
227 159
    protected function getSiteHashForDomain($domain)
228
    {
229
        /** @var $siteHashService SiteHashService */
230 159
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
231 159
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
232 159
        return $siteHash;
233
    }
234
235
    /**
236
     * @param int $rootPageId
237
     * @param array $rootPageRecord
238
     * @throws \InvalidArgumentException
239
     */
240 170
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
241
    {
242 170
        if (empty($rootPageRecord)) {
243 73
            throw new \InvalidArgumentException(
244 73
                '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.',
245 73
                1487326416
246
            );
247
        }
248
249 160
        if (!Site::isRootPage($rootPageRecord)) {
250 3
            throw new \InvalidArgumentException(
251 3
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
252 3
                1309272922
253
            );
254
        }
255 159
    }
256
257
    /**
258
     * @param array $rootPageRecord
259
     * @return Typo3ManagedSite
260
     */
261 159
    protected function buildTypo3ManagedSite(array $rootPageRecord): ?Typo3ManagedSite
262
    {
263 159
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($rootPageRecord['uid']);
264
        /** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
265
        try {
266 159
            $typo3Site = $this->siteFinder->getSiteByPageId($rootPageRecord['uid']);
267
        } catch (SiteNotFoundException $e) {
268
            return null;
269
        }
270 159
        $domain = $typo3Site->getBase()->getHost();
271
272 159
        $siteHash = $this->getSiteHashForDomain($domain);
273 159
        $defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
274 159
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
275
        $availableLanguageIds = array_map(function($language) {
276 159
            return $language->getLanguageId();
277 159
        }, $typo3Site->getLanguages());
278
279 159
        $solrConnectionConfigurations = [];
280
281 159
        foreach ($availableLanguageIds as $languageUid) {
282 159
            $solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type null|string expected by parameter $defaultValue of ApacheSolrForTypo3\Solr\...getConnectionProperty(). ( Ignorable by Annotation )

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

282
            $solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', /** @scrutinizer ignore-type */ true);
Loading history...
283 159
            if ($solrEnabled) {
284 159
                $solrConnectionConfigurations[$languageUid] = [
285 159
                    'connectionKey' =>  $rootPageRecord['uid'] . '|' . $languageUid,
286 159
                    'rootPageTitle' => $rootPageRecord['title'],
287 159
                    'rootPageUid' => $rootPageRecord['uid'],
288
                    'read' => [
289 159
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
290 159
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
291 159
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
292
                        // @todo: transform core to path
293
                        'path' =>
294 159
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
295 159
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
296 159
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
297 159
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''),
298 159
                        'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'read', 0)
299
                    ],
300
                    'write' => [
301 159
                        'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
302 159
                        'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
303 159
                        'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
304
                        // @todo: transform core to path
305
                        'path' =>
306 159
                            SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
307 159
                            SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
308 159
                        'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
309 159
                        'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''),
310 159
                        'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'write', 0)
311
                    ],
312
313 159
                    'language' => $languageUid
314
                ];
315
            }
316
        }
317
318 159
        return GeneralUtility::makeInstance(
319 159
            Typo3ManagedSite::class,
320
            /** @scrutinizer ignore-type */
321 159
            $solrConfiguration,
322
            /** @scrutinizer ignore-type */
323 159
            $rootPageRecord,
324
            /** @scrutinizer ignore-type */
325 159
            $domain,
326
            /** @scrutinizer ignore-type */
327 159
            $siteHash,
328
            /** @scrutinizer ignore-type */
329 159
            $pageRepository,
330
            /** @scrutinizer ignore-type */
331 159
            $defaultLanguage,
332
            /** @scrutinizer ignore-type */
333 159
            $availableLanguageIds,
334
            /** @scrutinizer ignore-type */
335 159
            $solrConnectionConfigurations,
336
            /** @scrutinizer ignore-type */
337 159
            $typo3Site
338
        );
339
    }
340
341
}
342