Completed
Push — master ( 3b0ef5...7e6ca3 )
by Timo
44:49 queued 41:28
created

SiteRepository::getAvailableTYPO3ManagedSites()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.9256

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 21
ccs 8
cts 12
cp 0.6667
rs 9.5555
cc 5
nc 9
nop 1
crap 5.9256
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
     * @var SiteFinder
70
     */
71
    protected $siteFinder;
72
73
    /**
74
     * SiteRepository constructor.
75
     *
76
     * @param RootPageResolver|null $rootPageResolver
77
     * @param TwoLevelCache|null $twoLevelCache
78
     * @param Registry|null $registry
79
     * @param SiteFinder
80
     */
81 195
    public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null, SiteFinder $siteFinder = null)
82
    {
83 195
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
84 195
        $this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'cache_runtime');
85 195
        $this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
86 195
        $this->siteFinder = $siteFinder ?? GeneralUtility::makeInstance(SiteFinder::class);
87 195
    }
88
89
    /**
90
     * Gets the Site for a specific page Id.
91
     *
92
     * @param int $pageId The page Id to get a Site object for.
93
     * @param string $mountPointIdentifier
94
     * @return SiteInterface Site for the given page Id.
95
     */
96 118
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
97
    {
98 118
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
99 118
        return $this->getSiteByRootPageId($rootPageId);
100
    }
101
102
    /**
103
     * Gets the Site for a specific root page Id.
104
     *
105
     * @param int $rootPageId Root page Id to get a Site object for.
106
     * @return SiteInterface Site for the given page Id.
107
     */
108 134
    public function getSiteByRootPageId($rootPageId)
109
    {
110 134
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
111
112 134
        $methodResult = $this->runtimeCache->get($cacheId);
113 134
        if (!empty($methodResult)) {
114 97
            return $methodResult;
115
        }
116
117 134
        $methodResult = $this->buildSite($rootPageId);
118 127
        $this->runtimeCache->set($cacheId, $methodResult);
119
120 127
        return $methodResult;
121
    }
122
123
    /**
124
     * Returns the first available Site.
125
     *
126
     * @param bool $stopOnInvalidSite
127
     * @throws \Exception
128
     * @return Site
129
     */
130 24
    public function getFirstAvailableSite($stopOnInvalidSite = false)
131
    {
132 24
        $sites = $this->getAvailableSites($stopOnInvalidSite);
133 24
        return array_shift($sites);
134
    }
135
136
    /**
137
     * Gets all available TYPO3 sites with Solr configured.
138
     *
139
     * @param bool $stopOnInvalidSite
140
     * @throws \Exception
141
     * @return Site[] An array of availablesites
142
     */
143 79
    public function getAvailableSites($stopOnInvalidSite = false)
144
    {
145 79
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
146
147 79
        $methodResult = $this->runtimeCache->get($cacheId);
148 79
        if (!empty($methodResult)) {
149 16
            return $methodResult;
150
        }
151
152 79
        $legacySites = $this->getAvailableLegacySites($stopOnInvalidSite);
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...tAvailableLegacySites() has been deprecated: deprecated since EXT:solr 10 will be removed with EXT:solr 11 please use the site handling now ( Ignorable by Annotation )

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

152
        $legacySites = /** @scrutinizer ignore-deprecated */ $this->getAvailableLegacySites($stopOnInvalidSite);

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...
153 79
        $typo3ManagedSolrSites = $this->getAvailableTYPO3ManagedSites($stopOnInvalidSite);
154
155 79
        $methodResult = array_merge($legacySites, $typo3ManagedSolrSites);
156 79
        $this->runtimeCache->set($cacheId, $methodResult);
157
158 79
        return $methodResult;
159
    }
160
161
    /**
162
     * @deprecated deprecated since EXT:solr 10 will be removed with EXT:solr 11 please use the site handling now
163
     * @param bool $stopOnInvalidSite
164
     * @return array
165
     */
166 79
    protected function getAvailableLegacySites(bool $stopOnInvalidSite): array
167
    {
168 79
        $serversFromRegistry = $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

168
        $serversFromRegistry = /** @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...
169 79
        if(empty($serversFromRegistry)) {
170 6
            return [];
171
        }
172
173 76
        trigger_error('Method getAvailableLegacySites is deprecated since EXT:solr 10 and will be removed in v11, please use the site handling to configure EXT:solr', E_USER_DEPRECATED);
174 76
        $legacySites = [];
175 76
        foreach ($serversFromRegistry as $server) {
176 76
            if (isset($legacySites[$server['rootPageUid']])) {
177
                //get each site only once
178 6
                continue;
179
            }
180
181
            try {
182 76
                $legacySites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']);
183 4
            } catch (\InvalidArgumentException $e) {
184 4
                if ($stopOnInvalidSite) {
185
                    throw $e;
186
                }
187
            }
188
        }
189 76
        return $legacySites;
190
    }
191
192
193
    /**
194
     * @param bool $stopOnInvalidSite
195
     * @return array
196
     * @throws \Exception
197
     */
198 79
    protected function getAvailableTYPO3ManagedSites(bool $stopOnInvalidSite): array
199
    {
200 79
        $typo3ManagedSolrSites = [];
201 79
        $typo3Sites = $this->siteFinder->getAllSites();
202 79
        foreach ($typo3Sites as $typo3Site) {
203
            try {
204 3
                $rootPageId = $typo3Site->getRootPageId();
205 3
                if (isset($typo3ManagedSolrSites[$rootPageId])) {
206
                    //get each site only once
207
                    continue;
208
                }
209
210 3
                $typo3ManagedSolrSites[$rootPageId] = $this->buildSite($rootPageId);
211
212
            } catch (\Exception $e) {
213
                if ($stopOnInvalidSite) {
214
                    throw $e;
215
                }
216
            }
217
        }
218 79
        return $typo3ManagedSolrSites;
219
    }
220
221
    /**
222
     * Gets the system languages (IDs) for which Solr connections have been
223
     * configured.
224
     *
225
     * @param Site $site
226
     * @return array
227
     * @throws \ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException
228
     * @deprecated use $site->getConnectionConfig
229
     * @todo check if method is still needed
230
     */
231
    public function getAllLanguages(Site $site)
232
    {
233
        trigger_error('Method getAllLanguages is deprecated since EXT:solr 10 and will be removed in v11, use  $site->getConnectionConfig instead', E_USER_DEPRECATED);
234
235
        $siteLanguages = [];
236
        foreach ($site->getAllSolrConnectionConfigurations() as $solrConnectionConfiguration) {
237
            $siteLanguages[] = $solrConnectionConfiguration['language'];
238
        }
239
240
        return $siteLanguages;
241
    }
242
243
    /**
244
     * Creates an instance of the Site object.
245
     *
246
     * @param integer $rootPageId
247
     * @throws \InvalidArgumentException
248
     * @return SiteInterface
249
     */
250 170
    protected function buildSite($rootPageId)
251
    {
252 170
        if (empty($rootPageId)) {
253
            throw new \InvalidArgumentException('Root page id can not be empty');
254
        }
255 170
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
256
257 170
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
258
259
        //@todo The handling of the legacy site can be removed in EXT:solr 11
260 159
        if (!SiteUtility::getIsSiteManagedSite($rootPageId)) {
261 159
            return $this->buildLegacySite($rootPageRecord);
0 ignored issues
show
Deprecated Code introduced by
The function ApacheSolrForTypo3\Solr\...tory::buildLegacySite() has been deprecated: buildLegacySite is deprecated and will be removed in EXT:solr 11. Please configure your system with the TYPO3 sitehandling ( Ignorable by Annotation )

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

261
            return /** @scrutinizer ignore-deprecated */ $this->buildLegacySite($rootPageRecord);

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...
262
        }
263
264
        return $this->buildTypo3ManagedSite($rootPageRecord);
265
    }
266
267
    /**
268
     * Retrieves the default language by the rootPageId of a site.
269
     *
270
     * @param int $rootPageId
271
     * @return int|mixed
272
     * @deprecated Use Site directly
273
     */
274 159
    protected function getDefaultLanguage($rootPageId)
275
    {
276 159
        trigger_error('Method getDefaultLanguage is deprecated since EXT:solr 10 and will be removed in v11, use  the site directly instead', E_USER_DEPRECATED);
277
278 159
        $siteDefaultLanguage = 0;
279
280 159
        $configuration = Util::getConfigurationFromPageId($rootPageId, 'config');
281
282 159
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('sys_language_uid', $siteDefaultLanguage);
283
        // default language is set through default L GET parameter -> overruling config.sys_language_uid
284 159
        $siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage);
285
286 159
        return $siteDefaultLanguage;
287
    }
288
289
    /**
290
     * Retrieves the configured solr servers from the registry.
291
     *
292
     * @deprecated This method is only required for old solr based sites.
293
     * @return array
294
     */
295 76
    protected function getSolrServersFromRegistry()
296
    {
297 76
        trigger_error('Method getSolrServersFromRegistry is deprecated since EXT:solr 10 and will be removed in v11, use sitehanlding instead', E_USER_DEPRECATED);
298
299 76
        $servers = (array)$this->registry->get('tx_solr', 'servers', []);
300 76
        return $servers;
301
    }
302
303
    /**
304
     * @param $rootPageId
305
     * @deprecated This method is only required for old solr based sites.
306
     * @return NULL|string
307
     */
308 159
    protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId)
309
    {
310 159
        trigger_error('Method getDomainFromConfigurationOrFallbackToDomainRecord is deprecated since EXT:solr 10 and will be removed in v11, use sitehanlding instead', E_USER_DEPRECATED);
311
312
        /** @var $siteService SiteService */
313 159
        $siteService = GeneralUtility::makeInstance(SiteService::class);
314 159
        $domain = $siteService->getFirstDomainForRootPage($rootPageId);
315 159
        if ($domain === '') {
316 158
            $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
317 158
            $rootLine = $pageSelect->getRootLine($rootPageId);
318 158
            $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

318
            $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...
319 158
            return (string)$domain;
320
        }
321
322 1
        return $domain;
323
    }
324
325
    /**
326
     * @param string $domain
327
     * @return string
328
     */
329 159
    protected function getSiteHashForDomain($domain)
330
    {
331
        /** @var $siteHashService SiteHashService */
332 159
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
333 159
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
334 159
        return $siteHash;
335
    }
336
337
    /**
338
     * @param int $rootPageId
339
     * @param array $rootPageRecord
340
     * @throws \InvalidArgumentException
341
     */
342 170
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
343
    {
344 170
        if (empty($rootPageRecord)) {
345 10
            throw new \InvalidArgumentException(
346 10
                '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.',
347 10
                1487326416
348
            );
349
        }
350
351 160
        if (!Site::isRootPage($rootPageRecord)) {
352 2
            throw new \InvalidArgumentException(
353 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.',
354 2
                1309272922
355
            );
356
        }
357 159
    }
358
359
    /**
360
     *
361
     * @deprecated buildLegacySite is deprecated and will be removed in EXT:solr 11. Please configure your system with the TYPO3 sitehandling
362
     * @param array $rootPageRecord
363
     * @return LegacySite
364
     */
365 159
    protected function buildLegacySite($rootPageRecord): LegacySite
366
    {
367 159
        trigger_error('You are using EXT:solr without sitehandling. This setup is deprecated and will be removed in EXT:solr 11', E_USER_DEPRECATED);
368
369 159
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageRecord['uid']);
370 159
        $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

370
        $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...
371 159
        $siteHash = $this->getSiteHashForDomain($domain);
372 159
        $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

372
        $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...
373 159
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
374 159
        $availableLanguageIds = GeneralUtility::makeInstance(SystemLanguageRepository::class)->findSystemLanguages();
375
376 159
        return GeneralUtility::makeInstance(
377 159
            LegacySite::class,
378
            /** @scrutinizer ignore-type */
379 159
            $solrConfiguration,
380
            /** @scrutinizer ignore-type */
381 159
            $rootPageRecord,
382
            /** @scrutinizer ignore-type */
383 159
            $domain,
384
            /** @scrutinizer ignore-type */
385 159
            $siteHash,
386
            /** @scrutinizer ignore-type */
387 159
            $pageRepository,
388
            /** @scrutinizer ignore-type */
389 159
            $defaultLanguage,
390
            /** @scrutinizer ignore-type */
391 159
            $availableLanguageIds
392
        );
393
    }
394
395
    /**
396
     * @param array $rootPageRecord
397
     * @return Typo3ManagedSite
398
     */
399
    protected function buildTypo3ManagedSite(array $rootPageRecord): Typo3ManagedSite
400
    {
401
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageRecord['uid']);
402
        /** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
403
        $typo3Site = $this->siteFinder->getSiteByPageId($rootPageRecord['uid']);
404
        $domain = $typo3Site->getBase()->getHost();
405
406
        $siteHash = $this->getSiteHashForDomain($domain);
407
        $defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
408
        $pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
409
        $availableLanguageIds = array_map(function($language) {
410
            return $language->getLanguageId();
411
        }, $typo3Site->getAllLanguages());
412
413
        $solrConnectionConfigurations = [];
414
        foreach ($availableLanguageIds as $languageUid) {
415
            $solrConnectionConfigurations[$languageUid] = [
416
                'connectionKey' =>  $rootPageRecord['uid'] . '|' . $languageUid,
417
                'rootPageTitle' => $rootPageRecord['title'],
418
                'rootPageUid' => $rootPageRecord['uid'],
419
                'read' => [
420
                    'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
421
                    'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
422
                    'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
423
                    // @todo: transform core to path
424
                    'path' =>
425
                        SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
426
                        SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
427
                    'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
428
                    'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''),
429
                    'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'read', 0)
430
                ],
431
                'write' => [
432
                    'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
433
                    'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
434
                    'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
435
                    // @todo: transform core to path
436
                    'path' =>
437
                        SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
438
                        SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
439
                    'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
440
                    'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''),
441
                    'timeout' => SiteUtility::getConnectionProperty($typo3Site, 'timeout', $languageUid, 'write', 0)
442
                ],
443
444
                'language' => $languageUid
445
            ];
446
        }
447
448
        return GeneralUtility::makeInstance(
449
            Typo3ManagedSite::class,
450
            /** @scrutinizer ignore-type */
451
            $solrConfiguration,
452
            /** @scrutinizer ignore-type */
453
            $rootPageRecord,
454
            /** @scrutinizer ignore-type */
455
            $domain,
456
            /** @scrutinizer ignore-type */
457
            $siteHash,
458
            /** @scrutinizer ignore-type */
459
            $pageRepository,
460
            /** @scrutinizer ignore-type */
461
            $defaultLanguage,
462
            /** @scrutinizer ignore-type */
463
            $availableLanguageIds,
464
            /** @scrutinizer ignore-type */
465
            $solrConnectionConfigurations,
466
            /** @scrutinizer ignore-type */
467
            $typo3Site
468
        );
469
    }
470
471
}
472