Passed
Push — master ( 278bfb...0c15ec )
by Timo
04:00
created

SiteRepository::getSiteHashForDomain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
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 2 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\Site;
30
use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache;
31
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
32
use ApacheSolrForTypo3\Solr\System\Service\SiteService;
33
use ApacheSolrForTypo3\Solr\Util;
34
use TYPO3\CMS\Backend\Utility\BackendUtility;
35
use TYPO3\CMS\Core\Registry;
36
use TYPO3\CMS\Core\Utility\GeneralUtility;
37
use TYPO3\CMS\Frontend\Page\PageRepository;
38
39
/**
40
 * SiteRepository
41
 *
42
 * Responsible to retrieve instances of Site objects
43
 *
44
 * @author Thomas Hohn <[email protected]>
45
 */
46
class SiteRepository
47
{
48
    /**
49
     * Rootpage resolver
50
     *
51
     * @var RootPageResolver
52
     */
53
    protected $rootPageResolver;
54
55
    /**
56
     * @var TwoLevelCache
57
     */
58
    protected $runtimeCache;
59
60
    /**
61
     * @var Registry
62
     */
63
    protected $registry;
64
65
    /**
66
     * SiteRepository constructor.
67 140
     *
68
     * @param RootPageResolver|null $rootPageResolver
69 140
     * @param TwoLevelCache|null $twoLevelCache
70 140
     * @param Registry|null $registry
71 140
     */
72 140
    public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null)
73
    {
74
        $this->rootPageResolver = isset($rootPageResolver) ? $rootPageResolver : GeneralUtility::makeInstance(RootPageResolver::class);
75
        $this->runtimeCache = isset($twoLevelCache) ? $twoLevelCache : GeneralUtility::makeInstance(TwoLevelCache::class, 'cache_runtime');
76
        $this->registry = isset($registry) ? $registry : GeneralUtility::makeInstance(Registry::class);
77
    }
78
79
    /**
80
     * Gets the Site for a specific page Id.
81 83
     *
82
     * @param int $pageId The page Id to get a Site object for.
83 83
     * @param string $mountPointIdentifier
84 83
     * @return Site Site for the given page Id.
85
     */
86
    public function getSiteByPageId($pageId, $mountPointIdentifier = '')
87
    {
88
        $rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
89
        return $this->getSiteByRootPageId($rootPageId);
90
    }
91
92
    /**
93 92
     * Gets the Site for a specific root page Id.
94
     *
95 92
     * @param int $rootPageId Root page Id to get a Site object for.
96
     * @return Site Site for the given page Id.
97 92
     */
98 92
    public function getSiteByRootPageId($rootPageId)
99 75
    {
100
        $cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
101
102 92
        $methodResult = $this->runtimeCache->get($cacheId);
103 90
        if (!empty($methodResult)) {
104
            return $methodResult;
105 90
        }
106
107
        $methodResult = $this->buildSite($rootPageId);
108
        $this->runtimeCache->set($cacheId, $methodResult);
109
110
        return $methodResult;
111
    }
112
113
    /**
114 20
     * Returns the first available Site.
115
     *
116 20
     * @param bool $stopOnInvalidSite
117 20
     * @return Site
118
     */
119
    public function getFirstAvailableSite($stopOnInvalidSite = false)
120
    {
121
        $sites = $this->getAvailableSites($stopOnInvalidSite);
122
        return array_shift($sites);
123
    }
124
125
    /**
126 61
     * Gets all available TYPO3 sites with Solr configured.
127
     *
128 61
     * @param bool $stopOnInvalidSite
129 61
     * @return Site[] An array of available sites
130
     */
131 61
    public function getAvailableSites($stopOnInvalidSite = false)
132 61
    {
133 16
        $sites = [];
134
        $cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
135
136 61
        $methodResult = $this->runtimeCache->get($cacheId);
137 61
        if (!empty($methodResult)) {
138 61
            return $methodResult;
139
        }
140 8
141
        $servers = $this->getSolrServersFromRegistry();
142
        foreach ($servers as $server) {
143
            if (isset($sites[$server['rootPageUid']])) {
144 61
                //get each site only once
145
                continue;
146
            }
147 61
148
            try {
149
                $sites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']);
150
            } catch (\InvalidArgumentException $e) {
151
                if ($stopOnInvalidSite) {
152 61
                    throw $e;
153 61
                }
154
            }
155 61
        }
156
157
        $methodResult = $sites;
158
        $this->runtimeCache->set($cacheId, $methodResult);
159
160
        return $methodResult;
161
    }
162
163
    /**
164 1
     * Gets the system languages (IDs) for which Solr connections have been
165
     * configured.
166 1
     *
167 1
     * @return array Array of system language IDs for which connections have been configured on this site.
168
     */
169 1
    public function getAllLanguages(Site $site)
170 1
    {
171
        $siteLanguages = [];
172 1
        $servers = $this->getSolrServersFromRegistry();
173 1
174
        foreach ($servers as $connectionKey => $solrConnection) {
175
            list($siteRootPageId, $systemLanguageId) = explode('|', $connectionKey);
176
177 1
            if ($siteRootPageId == $site->getRootPageId()) {
178
                $siteLanguages[] = $systemLanguageId;
179
            }
180
        }
181
182
        return $siteLanguages;
183
    }
184
185
    /**
186 120
     * Creates an instance of the Site object.
187
     *
188 120
     * @param integer $rootPageId
189
     * @throws \InvalidArgumentException
190
     * @return Site
191
     */
192
    protected function buildSite($rootPageId)
193
    {
194
        $rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
195
196 61
        $this->validateRootPageRecord($rootPageId, $rootPageRecord);
197
        $solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageId);
198 61
        $domain = $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId);
199 61
        $siteHash = $this->getSiteHashForDomain($domain);
200
201
        return GeneralUtility::makeInstance(Site::class, $solrConfiguration, $rootPageRecord, $domain, $siteHash);
202
    }
203
204
    /**
205
     * Retrieves the configured solr servers from the registry.
206
     *
207
     * @return array
208
     */
209
    protected function getSolrServersFromRegistry()
210
    {
211
        $servers = (array)$this->registry->get('tx_solr', 'servers', []);
212
        return $servers;
213
    }
214
215
    /**
216
     * @param $rootPageId
217
     * @return NULL|string
218
     */
219
    protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId)
220
    {
221
            /** @var $siteService SiteService */
222
        $siteService = GeneralUtility::makeInstance(SiteService::class);
223
        $domain = $siteService->getFirstDomainForRootPage($rootPageId);
224
        if ($domain === '') {
225
            $pageSelect = GeneralUtility::makeInstance(PageRepository::class);
226
            $rootLine = $pageSelect->getRootLine($rootPageId);
227
            $domain = BackendUtility::firstDomainRecord($rootLine);
228
            return (string)$domain;
229
        }
230
231
        return $domain;
232
    }
233
234
    /**
235
     * @param string $domain
236
     * @return string
237
     */
238
    protected function getSiteHashForDomain($domain)
239
    {
240
        /** @var $siteHashService SiteHashService */
241
        $siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
242
        $siteHash = $siteHashService->getSiteHashForDomain($domain);
243
        return $siteHash;
244
    }
245
246
    /**
247
     * @param int $rootPageId
248
     * @param array $rootPageRecord
249
     * @throws \InvalidArgumentException
250
     */
251
    protected function validateRootPageRecord($rootPageId, $rootPageRecord)
252
    {
253
        if (empty($rootPageRecord)) {
254
            throw new \InvalidArgumentException(
255
                '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.',
256
                1487326416
257
            );
258
        }
259
260
        if (!Site::isRootPage($rootPageRecord)) {
261
            throw new \InvalidArgumentException(
262
                'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
263
                1309272922
264
            );
265
        }
266
    }
267
}
268