Completed
Push — master ( 6e98ac...8f8ac6 )
by Timo
36:51 queued 33:36
created

SiteRepository::buildLegacySite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 25
ccs 0
cts 0
cp 0
rs 9.7666
c 0
b 0
f 0
cc 1
nc 1
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\System\Cache\TwoLevelCache;
30
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
31
use ApacheSolrForTypo3\Solr\System\Records\SystemLanguage\SystemLanguageRepository;
32
use ApacheSolrForTypo3\Solr\System\Service\SiteService;
33
use ApacheSolrForTypo3\Solr\System\Util\SiteUtility;
34
use ApacheSolrForTypo3\Solr\Util;
35
use TYPO3\CMS\Backend\Utility\BackendUtility;
36
use TYPO3\CMS\Core\Registry;
37
use TYPO3\CMS\Core\Site\SiteFinder;
38
use TYPO3\CMS\Core\Utility\GeneralUtility;
39
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
40
use TYPO3\CMS\Frontend\Page\PageRepository;
41
42
/**
43
 * SiteRepository
44
 *
45
 * Responsible to retrieve instances of Site objects
46
 *
47
 * @author Thomas Hohn <[email protected]>
48
 */
49
class SiteRepository
50
{
51
    /**
52
     * Rootpage resolver
53
     *
54
     * @var RootPageResolver
55
     */
56
    protected $rootPageResolver;
57
58
    /**
59
     * @var TwoLevelCache
60
     */
61
    protected $runtimeCache;
62
63
    /**
64
     * @var Registry
65
     */
66
    protected $registry;
67
68
    /**
69
     * SiteRepository constructor.
70
     *
71 177
     * @param RootPageResolver|null $rootPageResolver
72
     * @param TwoLevelCache|null $twoLevelCache
73 177
     * @param Registry|null $registry
74 177
     */
75 177
    public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null)
76 177
    {
77
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
78
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'cache_runtime');
79
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
80
    }
81
82
    /**
83
     * Gets the Site for a specific page Id.
84
     *
85 112
     * @param int $pageId The page Id to get a Site object for.
86
     * @param string $mountPointIdentifier
87 112
     * @return SiteInterface Site for the given page Id.
88 112
     */
89
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
90
    {
91
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
92
        return $this->getSiteByRootPageId($rootPageId);
93
    }
94
95
    /**
96
     * Gets the Site for a specific root page Id.
97 127
     *
98
     * @param int $rootPageId Root page Id to get a Site object for.
99 127
     * @return SiteInterface Site for the given page Id.
100
     */
101 127
    public function getSiteByRootPageId($rootPageId)
102 127
    {
103 94
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
104
105
        $methodResult = $this->runtimeCache->get($cacheId);
106 127
        if (!empty($methodResult)) {
107 122
            return $methodResult;
108
        }
109 122
110
        $methodResult = $this->buildSite($rootPageId);
111
        $this->runtimeCache->set($cacheId, $methodResult);
112
113
        return $methodResult;
114
    }
115
116
    /**
117
     * Returns the first available Site.
118 24
     *
119
     * @param bool $stopOnInvalidSite
120 24
     * @return Site
121 24
     */
122
    public function getFirstAvailableSite($stopOnInvalidSite = false)
123
    {
124
        $sites = $this->getAvailableSites($stopOnInvalidSite);
125
        return array_shift($sites);
126
    }
127
128
    /**
129
     * Gets all available TYPO3 sites with Solr configured.
130 72
     *
131
     * @param bool $stopOnInvalidSite
132 72
     * @return Site[] An array of available sites
133 72
     */
134
    public function getAvailableSites($stopOnInvalidSite = false)
135 72
    {
136 72
        $sites = [];
137 16
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
138
139
        $methodResult = $this->runtimeCache->get($cacheId);
140 72
        if (!empty($methodResult)) {
141 72
            return $methodResult;
142 72
        }
143
144 9
        $servers = $this->getSolrServersFromRegistry();
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...lrServersFromRegistry() has been deprecated: This method is only required for old solr based sites. ( Ignorable by Annotation )

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

144
        $servers = /** @scrutinizer ignore-deprecated */ $this->getSolrServersFromRegistry();

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...
145
        foreach ($servers as $server) {
146
            if (isset($sites[$server['rootPageUid']])) {
147
                //get each site only once
148 72
                continue;
149
            }
150
151
            try {
152
                $sites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']);
153
            } catch (\InvalidArgumentException $e) {
154
                if ($stopOnInvalidSite) {
155
                    throw $e;
156 72
                }
157 72
            }
158
        }
159 72
160
        $methodResult = $sites;
161
        $this->runtimeCache->set($cacheId, $methodResult);
162
163
        return $methodResult;
164
    }
165
166
    /**
167
     * Gets the system languages (IDs) for which Solr connections have been
168 1
     * configured.
169
     *
170 1
     * @param Site $site
171 1
     * @return array
172
     * @throws \ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException
173 1
     * @deprecated use $site->getConnectionConfig
174 1
     * @todo check if method is still needed
175
     */
176 1
    public function getAllLanguages(Site $site)
177 1
    {
178
        $siteLanguages = [];
179
        foreach ($site->getAllSolrConnectionConfigurations() as $solrConnectionConfiguration) {
180
            $siteLanguages[] = $solrConnectionConfiguration['language'];
181 1
        }
182
183
        return $siteLanguages;
184
    }
185
186
    /**
187
     * Creates an instance of the Site object.
188
     *
189
     * @param integer $rootPageId
190
     * @throws \InvalidArgumentException
191 157
     * @return SiteInterface
192
     */
193 157
    protected function buildSite($rootPageId)
194
    {
195 157
        if (empty($rootPageId)) {
196 152
            throw new \InvalidArgumentException('Root page id can not be empty');
197 152
        }
198 152
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
199 152
200 152
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
201
202 152
        //@todo The handling of the legacy site can be removed in EXT:solr 11
203 152
        if (!SiteUtility::getIsSiteManagedSite($rootPageId)) {
204 152
            return $this->buildLegacySite($rootPageRecord);
205 152
        }
206 152
207 152
        return $this->buildTypo3ManagedSite($rootPageRecord);
208 152
    }
209 152
210
    /**
211
     * Retrieves the default language by the rootPageId of a site.
212
     *
213
     * @param int $rootPageId
214
     * @return int|mixed
215
     * @deprecated Use Site directly
216
     */
217
    protected function getDefaultLanguage($rootPageId)
218
    {
219 152
        $siteDefaultLanguage = 0;
220
221 152
        $configuration = Util::getConfigurationFromPageId($rootPageId, 'config');
222
223 152
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('sys_language_uid', $siteDefaultLanguage);
224
        // default language is set through default L GET parameter -> overruling config.sys_language_uid
225 152
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage);
226
227 152
        return $siteDefaultLanguage;
228
    }
229 152
230
    /**
231
     * Retrieves the configured solr servers from the registry.
232
     *
233
     * @deprecated This method is only required for old solr based sites.
234
     * @return array
235
     */
236
    protected function getSolrServersFromRegistry()
237 72
    {
238
        $servers = (array)$this->registry->get('tx_solr', 'servers', []);
239 72
        return $servers;
240 72
    }
241
242
    /**
243
     * @param $rootPageId
244
     * @deprecated This method is only required for old solr based sites.
245
     * @return NULL|string
246
     */
247 152
    protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId)
248
    {
249
        /** @var $siteService SiteService */
250 152
        $siteService = GeneralUtility::makeInstance(SiteService::class);
251 152
        $domain = $siteService->getFirstDomainForRootPage($rootPageId);
252 152
        if ($domain === '') {
253 151
            $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
254 151
            $rootLine = $pageSelect->getRootLine($rootPageId);
255 151
            $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 151
            return (string)$domain;
257
        }
258
259 1
        return $domain;
260
    }
261
262
    /**
263
     * @param string $domain
264
     * @return string
265
     */
266 152
    protected function getSiteHashForDomain($domain)
267
    {
268
        /** @var $siteHashService SiteHashService */
269 152
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
270 152
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
271 152
        return $siteHash;
272
    }
273
274
    /**
275
     * @param int $rootPageId
276
     * @param array $rootPageRecord
277
     * @throws \InvalidArgumentException
278
     */
279 157
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
280
    {
281 157
        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 153
        if (!Site::isRootPage($rootPageRecord)) {
289 2
            throw new \InvalidArgumentException(
290 2
                '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 2
                1309272922
292
            );
293
        }
294 152
    }
295
296
    /**
297
     * @param array $rootPageRecord
298
     * @return LegacySite
299
     */
300
    protected function buildLegacySite($rootPageRecord): LegacySite
301
    {
302
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageRecord['uid']);
303
        $domain = $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageRecord['uid']);
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...allbackToDomainRecord() has been deprecated: This method is only required for old solr based sites. ( Ignorable by Annotation )

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

303
        $domain = /** @scrutinizer ignore-deprecated */ $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageRecord['uid']);

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...
304
        $siteHash = $this->getSiteHashForDomain($domain);
305
        $defaultLanguage = $this->getDefaultLanguage($rootPageRecord['uid']);
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...y::getDefaultLanguage() has been deprecated: Use Site directly ( Ignorable by Annotation )

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

305
        $defaultLanguage = /** @scrutinizer ignore-deprecated */ $this->getDefaultLanguage($rootPageRecord['uid']);

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...
306
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
307
        $availableLanguageIds = GeneralUtility::makeInstance(SystemLanguageRepository::class)->findSystemLanguages();
308
309
        return GeneralUtility::makeInstance(
310
            LegacySite::class,
311
            /** @scrutinizer ignore-type */
312
            $solrConfiguration,
313
            /** @scrutinizer ignore-type */
314
            $rootPageRecord,
315
            /** @scrutinizer ignore-type */
316
            $domain,
317
            /** @scrutinizer ignore-type */
318
            $siteHash,
319
            /** @scrutinizer ignore-type */
320
            $pageRepository,
321
            /** @scrutinizer ignore-type */
322
            $defaultLanguage,
323
            /** @scrutinizer ignore-type */
324
            $availableLanguageIds
325
        );
326
    }
327
328
    /**
329
     * @param array $rootPageRecord
330
     * @return Typo3ManagedSite
331
     */
332
    protected function buildTypo3ManagedSite(array $rootPageRecord): Typo3ManagedSite
333
    {
334
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageRecord['uid']);
335
        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
336
        /** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
337
        $typo3Site = $siteFinder->getSiteByPageId($rootPageRecord['uid']);
338
        $domain = $typo3Site->getBase()->getHost();
339
340
        $siteHash = $this->getSiteHashForDomain($domain);
341
        $defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
342
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
343
        $availableLanguageIds = array_map(function($language) {
344
            return $language->getLanguageId();
345
        }, $typo3Site->getAllLanguages());
346
347
        $solrConnectionConfigurations = [];
348
        foreach ($availableLanguageIds as $languageUid) {
349
            $solrConnectionConfigurations[$languageUid] = [
350
                'connectionKey' =>  $rootPageRecord['uid'] . '|' . $languageUid,
351
                'rootPageTitle' => $rootPageRecord['title'],
352
                'rootPageUid' => $rootPageRecord['uid'],
353
                'read' => [
354
                    'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
355
                    'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
356
                    'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
357
                    // @todo: transform core to path
358
                    'path' =>
359
                        SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
360
                        SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
361
                    'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
362
                    'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''),
363
                    'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'read', 0)
364
                ],
365
                'write' => [
366
                    'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
367
                    'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
368
                    'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
369
                    // @todo: transform core to path
370
                    'path' =>
371
                        SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
372
                        SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
373
                    'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
374
                    'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''),
375
                    'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'write', 0)
376
                ],
377
378
                'language' => $languageUid
379
            ];
380
        }
381
382
        return GeneralUtility::makeInstance(
383
            Typo3ManagedSite::class,
384
            /** @scrutinizer ignore-type */
385
            $solrConfiguration,
386
            /** @scrutinizer ignore-type */
387
            $rootPageRecord,
388
            /** @scrutinizer ignore-type */
389
            $domain,
390
            /** @scrutinizer ignore-type */
391
            $siteHash,
392
            /** @scrutinizer ignore-type */
393
            $pageRepository,
394
            /** @scrutinizer ignore-type */
395
            $defaultLanguage,
396
            /** @scrutinizer ignore-type */
397
            $availableLanguageIds,
398
            /** @scrutinizer ignore-type */
399
            $solrConnectionConfigurations,
400
            /** @scrutinizer ignore-type */
401
            $typo3Site
402
        );
403
    }
404
}
405