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
|
|
|
* @param RootPageResolver|null $rootPageResolver |
72
|
|
|
* @param TwoLevelCache|null $twoLevelCache |
73
|
|
|
* @param Registry|null $registry |
74
|
|
|
*/ |
75
|
195 |
|
public function __construct(RootPageResolver $rootPageResolver = null, TwoLevelCache $twoLevelCache = null, Registry $registry = null) |
76
|
|
|
{ |
77
|
195 |
|
$this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class); |
78
|
195 |
|
$this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'cache_runtime'); |
79
|
195 |
|
$this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class); |
80
|
195 |
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Gets the Site for a specific page Id. |
84
|
|
|
* |
85
|
|
|
* @param int $pageId The page Id to get a Site object for. |
86
|
|
|
* @param string $mountPointIdentifier |
87
|
|
|
* @return SiteInterface Site for the given page Id. |
88
|
|
|
*/ |
89
|
118 |
|
public function getSiteByPageId($pageId, $mountPointIdentifier = '') |
90
|
|
|
{ |
91
|
118 |
|
$rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier); |
92
|
118 |
|
return $this->getSiteByRootPageId($rootPageId); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Gets the Site for a specific root page Id. |
97
|
|
|
* |
98
|
|
|
* @param int $rootPageId Root page Id to get a Site object for. |
99
|
|
|
* @return SiteInterface Site for the given page Id. |
100
|
|
|
*/ |
101
|
134 |
|
public function getSiteByRootPageId($rootPageId) |
102
|
|
|
{ |
103
|
134 |
|
$cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId; |
104
|
|
|
|
105
|
134 |
|
$methodResult = $this->runtimeCache->get($cacheId); |
106
|
134 |
|
if (!empty($methodResult)) { |
107
|
97 |
|
return $methodResult; |
108
|
|
|
} |
109
|
|
|
|
110
|
134 |
|
$methodResult = $this->buildSite($rootPageId); |
111
|
127 |
|
$this->runtimeCache->set($cacheId, $methodResult); |
112
|
|
|
|
113
|
127 |
|
return $methodResult; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Returns the first available Site. |
118
|
|
|
* |
119
|
|
|
* @param bool $stopOnInvalidSite |
120
|
|
|
* @return Site |
121
|
|
|
*/ |
122
|
24 |
|
public function getFirstAvailableSite($stopOnInvalidSite = false) |
123
|
|
|
{ |
124
|
24 |
|
$sites = $this->getAvailableSites($stopOnInvalidSite); |
125
|
24 |
|
return array_shift($sites); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Gets all available TYPO3 sites with Solr configured. |
130
|
|
|
* |
131
|
|
|
* @param bool $stopOnInvalidSite |
132
|
|
|
* @return Site[] An array of available sites |
133
|
|
|
*/ |
134
|
79 |
|
public function getAvailableSites($stopOnInvalidSite = false) |
135
|
|
|
{ |
136
|
79 |
|
$sites = []; |
137
|
79 |
|
$cacheId = 'SiteRepository' . '_' . 'getAvailableSites'; |
138
|
|
|
|
139
|
79 |
|
$methodResult = $this->runtimeCache->get($cacheId); |
140
|
79 |
|
if (!empty($methodResult)) { |
141
|
16 |
|
return $methodResult; |
142
|
|
|
} |
143
|
|
|
|
144
|
79 |
|
$servers = $this->getSolrServersFromRegistry(); |
|
|
|
|
145
|
79 |
|
foreach ($servers as $server) { |
146
|
79 |
|
if (isset($sites[$server['rootPageUid']])) { |
147
|
|
|
//get each site only once |
148
|
9 |
|
continue; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
try { |
152
|
79 |
|
$sites[$server['rootPageUid']] = $this->buildSite($server['rootPageUid']); |
153
|
4 |
|
} catch (\InvalidArgumentException $e) { |
154
|
4 |
|
if ($stopOnInvalidSite) { |
155
|
|
|
throw $e; |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
|
160
|
79 |
|
$methodResult = $sites; |
161
|
79 |
|
$this->runtimeCache->set($cacheId, $methodResult); |
162
|
|
|
|
163
|
79 |
|
return $methodResult; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Gets the system languages (IDs) for which Solr connections have been |
168
|
|
|
* configured. |
169
|
|
|
* |
170
|
|
|
* @param Site $site |
171
|
|
|
* @return array |
172
|
|
|
* @throws \ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException |
173
|
|
|
* @deprecated use $site->getConnectionConfig |
174
|
|
|
* @todo check if method is still needed |
175
|
|
|
*/ |
176
|
1 |
|
public function getAllLanguages(Site $site) |
177
|
|
|
{ |
178
|
1 |
|
$siteLanguages = []; |
179
|
1 |
|
foreach ($site->getAllSolrConnectionConfigurations() as $solrConnectionConfiguration) { |
180
|
1 |
|
$siteLanguages[] = $solrConnectionConfiguration['language']; |
181
|
|
|
} |
182
|
|
|
|
183
|
1 |
|
return $siteLanguages; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Creates an instance of the Site object. |
188
|
|
|
* |
189
|
|
|
* @param integer $rootPageId |
190
|
|
|
* @throws \InvalidArgumentException |
191
|
|
|
* @return SiteInterface |
192
|
|
|
*/ |
193
|
170 |
|
protected function buildSite($rootPageId) |
194
|
|
|
{ |
195
|
170 |
|
if (empty($rootPageId)) { |
196
|
|
|
throw new \InvalidArgumentException('Root page id can not be empty'); |
197
|
|
|
} |
198
|
170 |
|
$rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId); |
199
|
|
|
|
200
|
170 |
|
$this->validateRootPageRecord($rootPageId, $rootPageRecord); |
201
|
|
|
|
202
|
|
|
//@todo The handling of the legacy site can be removed in EXT:solr 11 |
203
|
159 |
|
if (!SiteUtility::getIsSiteManagedSite($rootPageId)) { |
204
|
159 |
|
return $this->buildLegacySite($rootPageRecord); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
return $this->buildTypo3ManagedSite($rootPageRecord); |
208
|
|
|
} |
209
|
|
|
|
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
|
159 |
|
protected function getDefaultLanguage($rootPageId) |
218
|
|
|
{ |
219
|
159 |
|
$siteDefaultLanguage = 0; |
220
|
|
|
|
221
|
159 |
|
$configuration = Util::getConfigurationFromPageId($rootPageId, 'config'); |
222
|
|
|
|
223
|
159 |
|
$siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('sys_language_uid', $siteDefaultLanguage); |
224
|
|
|
// default language is set through default L GET parameter -> overruling config.sys_language_uid |
225
|
159 |
|
$siteDefaultLanguage = $configuration->getValueByPathOrDefaultValue('defaultGetVars.L', $siteDefaultLanguage); |
226
|
|
|
|
227
|
159 |
|
return $siteDefaultLanguage; |
228
|
|
|
} |
229
|
|
|
|
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
|
79 |
|
protected function getSolrServersFromRegistry() |
237
|
|
|
{ |
238
|
79 |
|
$servers = (array)$this->registry->get('tx_solr', 'servers', []); |
239
|
79 |
|
return $servers; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @param $rootPageId |
244
|
|
|
* @deprecated This method is only required for old solr based sites. |
245
|
|
|
* @return NULL|string |
246
|
|
|
*/ |
247
|
159 |
|
protected function getDomainFromConfigurationOrFallbackToDomainRecord($rootPageId) |
248
|
|
|
{ |
249
|
|
|
/** @var $siteService SiteService */ |
250
|
159 |
|
$siteService = GeneralUtility::makeInstance(SiteService::class); |
251
|
159 |
|
$domain = $siteService->getFirstDomainForRootPage($rootPageId); |
252
|
159 |
|
if ($domain === '') { |
253
|
158 |
|
$pageSelect = GeneralUtility::makeInstance(PageRepository::class); |
254
|
158 |
|
$rootLine = $pageSelect->getRootLine($rootPageId); |
255
|
158 |
|
$domain = BackendUtility::firstDomainRecord($rootLine); |
|
|
|
|
256
|
158 |
|
return (string)$domain; |
257
|
|
|
} |
258
|
|
|
|
259
|
1 |
|
return $domain; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param string $domain |
264
|
|
|
* @return string |
265
|
|
|
*/ |
266
|
159 |
|
protected function getSiteHashForDomain($domain) |
267
|
|
|
{ |
268
|
|
|
/** @var $siteHashService SiteHashService */ |
269
|
159 |
|
$siteHashService = GeneralUtility::makeInstance(SiteHashService::class); |
270
|
159 |
|
$siteHash = $siteHashService->getSiteHashForDomain($domain); |
271
|
159 |
|
return $siteHash; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param int $rootPageId |
276
|
|
|
* @param array $rootPageRecord |
277
|
|
|
* @throws \InvalidArgumentException |
278
|
|
|
*/ |
279
|
170 |
|
protected function validateRootPageRecord($rootPageId, $rootPageRecord) |
280
|
|
|
{ |
281
|
170 |
|
if (empty($rootPageRecord)) { |
282
|
10 |
|
throw new \InvalidArgumentException( |
283
|
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.', |
284
|
10 |
|
1487326416 |
285
|
|
|
); |
286
|
|
|
} |
287
|
|
|
|
288
|
160 |
|
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
|
159 |
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* @param array $rootPageRecord |
298
|
|
|
* @return LegacySite |
299
|
|
|
*/ |
300
|
159 |
|
protected function buildLegacySite($rootPageRecord): LegacySite |
301
|
|
|
{ |
302
|
159 |
|
$solrConfiguration = Util::getSolrConfigurationFromPageId($rootPageRecord['uid']); |
303
|
159 |
|
$domain = $this->getDomainFromConfigurationOrFallbackToDomainRecord($rootPageRecord['uid']); |
|
|
|
|
304
|
159 |
|
$siteHash = $this->getSiteHashForDomain($domain); |
305
|
159 |
|
$defaultLanguage = $this->getDefaultLanguage($rootPageRecord['uid']); |
|
|
|
|
306
|
159 |
|
$pageRepository = GeneralUtility::makeInstance(PagesRepository::class); |
307
|
159 |
|
$availableLanguageIds = GeneralUtility::makeInstance(SystemLanguageRepository::class)->findSystemLanguages(); |
308
|
|
|
|
309
|
159 |
|
return GeneralUtility::makeInstance( |
310
|
159 |
|
LegacySite::class, |
311
|
|
|
/** @scrutinizer ignore-type */ |
312
|
159 |
|
$solrConfiguration, |
313
|
|
|
/** @scrutinizer ignore-type */ |
314
|
159 |
|
$rootPageRecord, |
315
|
|
|
/** @scrutinizer ignore-type */ |
316
|
159 |
|
$domain, |
317
|
|
|
/** @scrutinizer ignore-type */ |
318
|
159 |
|
$siteHash, |
319
|
|
|
/** @scrutinizer ignore-type */ |
320
|
159 |
|
$pageRepository, |
321
|
|
|
/** @scrutinizer ignore-type */ |
322
|
159 |
|
$defaultLanguage, |
323
|
|
|
/** @scrutinizer ignore-type */ |
324
|
159 |
|
$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
|
|
|
|
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.