first commit
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site\Exception;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2019- dkd Internet Services GmbH (info@dkd.de)
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
|
||||
class InvalidSiteConfigurationCombinationException extends \Exception {}
|
266
Classes/Domain/Site/Site.php
Normal file
266
Classes/Domain/Site/Site.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011-2015 Ingo Renner <ingo@typo3.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use WapplerSystems\Meilisearch\Domain\Index\Queue\RecordMonitor\Helper\ConfigurationAwareRecordService;
|
||||
use WapplerSystems\Meilisearch\NoSolrConnectionFoundException;
|
||||
use WapplerSystems\Meilisearch\System\Configuration\TypoScriptConfiguration;
|
||||
use WapplerSystems\Meilisearch\System\Records\Pages\PagesRepository;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Base Clas for Typo3ManagedSite and LegacySite
|
||||
*/
|
||||
abstract class Site implements SiteInterface
|
||||
{
|
||||
/**
|
||||
* @var TypoScriptConfiguration
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* Root page record.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rootPage = [];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $siteHash;
|
||||
|
||||
/**
|
||||
* @var PagesRepository
|
||||
*/
|
||||
protected $pagesRepository;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $defaultLanguageId = 0;
|
||||
|
||||
/**
|
||||
* @var int[] Available language ids
|
||||
*/
|
||||
protected $availableLanguageIds = [];
|
||||
|
||||
/**
|
||||
* Takes an pagerecord and checks whether the page is marked as root page.
|
||||
*
|
||||
* @param array $page pagerecord
|
||||
* @return bool true if the page is marked as root page, false otherwise
|
||||
* @todo: move to SiteUtility?
|
||||
*/
|
||||
public static function isRootPage($page)
|
||||
{
|
||||
if ($page['is_siteroot']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's root page ID (uid).
|
||||
*
|
||||
* @return int The site's root page ID.
|
||||
*/
|
||||
public function getRootPageId()
|
||||
{
|
||||
return (int)$this->rootPage['uid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets available language id's for this site
|
||||
*
|
||||
* @return int[] array or language id's
|
||||
*/
|
||||
public function getAvailableLanguageIds(): array {
|
||||
return $this->availableLanguageIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's label. The label is build from the the site title and root
|
||||
* page ID (uid).
|
||||
*
|
||||
* @return string The site's label.
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
$rootlineTitles = [];
|
||||
$rootLine = BackendUtility::BEgetRootLine($this->rootPage['uid']);
|
||||
// Remove last
|
||||
array_pop($rootLine);
|
||||
$rootLine = array_reverse($rootLine);
|
||||
foreach ($rootLine as $rootLineItem) {
|
||||
$rootlineTitles[] = $rootLineItem['title'];
|
||||
}
|
||||
return implode(' - ', $rootlineTitles) . ', Root Page ID: ' . $this->rootPage['uid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's Solr TypoScript configuration (plugin.tx_meilisearch.*)
|
||||
*
|
||||
* @return \WapplerSystems\Meilisearch\System\Configuration\TypoScriptConfiguration The Solr TypoScript configuration
|
||||
*/
|
||||
public function getSolrConfiguration()
|
||||
{
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's default language as configured in
|
||||
* config.sys_language_uid. If sys_language_uid is not set, 0 is assumed to
|
||||
* be the default.
|
||||
*
|
||||
* @return int The site's default language.
|
||||
*/
|
||||
public function getDefaultLanguage()
|
||||
{
|
||||
return $this->defaultLanguageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of page IDs in this site. Attention, this includes
|
||||
* all page types! Deleted pages are not included.
|
||||
*
|
||||
* @param int|string $rootPageId Page ID from where to start collection sub pages
|
||||
* @param int $maxDepth Maximum depth to descend into the site tree
|
||||
* @return array Array of pages (IDs) in this site
|
||||
*/
|
||||
public function getPages($rootPageId = 'SITE_ROOT', $maxDepth = 999)
|
||||
{
|
||||
$pageIds = [];
|
||||
if ($rootPageId === 'SITE_ROOT') {
|
||||
$rootPageId = (int)$this->rootPage['uid'];
|
||||
$pageIds[] = $rootPageId;
|
||||
}
|
||||
|
||||
$configurationAwareRecordService = GeneralUtility::makeInstance(ConfigurationAwareRecordService::class);
|
||||
// Fetch configuration in order to be able to read initialPagesAdditionalWhereClause
|
||||
$solrConfiguration = $this->getSolrConfiguration();
|
||||
$indexQueueConfigurationName = $configurationAwareRecordService->getIndexingConfigurationName('pages', $this->rootPage['uid'], $solrConfiguration);
|
||||
if ($indexQueueConfigurationName === null) {
|
||||
return $pageIds;
|
||||
}
|
||||
$initialPagesAdditionalWhereClause = $solrConfiguration->getInitialPagesAdditionalWhereClause($indexQueueConfigurationName);
|
||||
return array_merge($pageIds, $this->pagesRepository->findAllSubPageIdsByRootPage($rootPageId, $maxDepth, $initialPagesAdditionalWhereClause));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the site's unique Site Hash.
|
||||
*
|
||||
* The Site Hash is build from the site's main domain, the system encryption
|
||||
* key, and the extension "tx_meilisearch". These components are concatenated and
|
||||
* sha1-hashed.
|
||||
*
|
||||
* @return string Site Hash.
|
||||
*/
|
||||
public function getSiteHash()
|
||||
{
|
||||
return $this->siteHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's main domain. More specifically the first domain record in
|
||||
* the site tree.
|
||||
*
|
||||
* @return string The site's main domain.
|
||||
*/
|
||||
public function getDomain()
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's root page.
|
||||
*
|
||||
* @return array The site's root page.
|
||||
*/
|
||||
public function getRootPage()
|
||||
{
|
||||
return $this->rootPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site's root page's title.
|
||||
*
|
||||
* @return string The site's root page's title
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->rootPage['title'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the rootPageIds as an array from a set of sites.
|
||||
*
|
||||
* @param array $sites
|
||||
* @return array
|
||||
* @todo: move to SiteUtility?
|
||||
*/
|
||||
public static function getRootPageIdsFromSites(array $sites): array
|
||||
{
|
||||
$rootPageIds = [];
|
||||
foreach ($sites as $site) {
|
||||
$rootPageIds[] = (int)$site->getRootPageId();
|
||||
}
|
||||
|
||||
return $rootPageIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws NoSolrConnectionFoundException
|
||||
*/
|
||||
public function getAllSolrConnectionConfigurations(): array {
|
||||
$configs = [];
|
||||
foreach ($this->getAvailableLanguageIds() as $languageId) {
|
||||
try {
|
||||
$configs[$languageId] = $this->getSolrConnectionConfiguration($languageId);
|
||||
} catch (NoSolrConnectionFoundException $e) {}
|
||||
}
|
||||
return $configs;
|
||||
}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return !empty($this->getAllSolrConnectionConfigurations());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $languageId
|
||||
* @return array
|
||||
*/
|
||||
abstract function getSolrConnectionConfiguration(int $language = 0): array;
|
||||
}
|
141
Classes/Domain/Site/SiteHashService.php
Normal file
141
Classes/Domain/Site/SiteHashService.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2017- Timo Hund <timo.hund@dkd.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* SiteHashService
|
||||
*
|
||||
* Responsible to provide sitehash related service methods.
|
||||
*
|
||||
* @author Timo Hund <timo.hund@dkd.de>
|
||||
*/
|
||||
class SiteHashService
|
||||
{
|
||||
|
||||
/**
|
||||
* Resolves magic keywords in allowed sites configuration.
|
||||
* Supported keywords:
|
||||
* __solr_current_site - The domain of the site the query has been started from
|
||||
* __current_site - Same as __solr_current_site
|
||||
* __all - Adds all domains as allowed sites
|
||||
* * - Means all sites are allowed, same as no siteHash
|
||||
*
|
||||
* @param integer $pageId A page ID that is then resolved to the site it belongs to
|
||||
* @param string $allowedSitesConfiguration TypoScript setting for allowed sites
|
||||
* @return string List of allowed sites/domains, magic keywords resolved
|
||||
*/
|
||||
public function getAllowedSitesForPageIdAndAllowedSitesConfiguration($pageId, $allowedSitesConfiguration)
|
||||
{
|
||||
if ($allowedSitesConfiguration === '__all') {
|
||||
return $this->getDomainListOfAllSites();
|
||||
} elseif ($allowedSitesConfiguration === '*') {
|
||||
return '*';
|
||||
} else {
|
||||
// we thread empty allowed site configurations as __solr_current_site since this is the default behaviour
|
||||
$allowedSitesConfiguration = empty($allowedSitesConfiguration) ? '__solr_current_site' : $allowedSitesConfiguration;
|
||||
return $this->getDomainByPageIdAndReplaceMarkers($pageId, $allowedSitesConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site hash for a domain
|
||||
*
|
||||
* @param string $domain Domain to calculate the site hash for.
|
||||
* @return string site hash for $domain
|
||||
*/
|
||||
public function getSiteHashForDomain($domain)
|
||||
{
|
||||
static $siteHashes = [];
|
||||
if (isset($siteHashes[$domain])) {
|
||||
return $siteHashes[$domain];
|
||||
}
|
||||
|
||||
$siteHashes[$domain] = sha1($domain . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . 'tx_meilisearch');
|
||||
return $siteHashes[$domain];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a comma separated list of all domains from all sites.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDomainListOfAllSites()
|
||||
{
|
||||
$sites = $this->getAvailableSites();
|
||||
$domains = [];
|
||||
foreach ($sites as $site) {
|
||||
$domains[] = $site->getDomain();
|
||||
}
|
||||
|
||||
$allowedSites = implode(',', $domains);
|
||||
return $allowedSites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the domain of the site that belongs to the passed pageId and replaces their markers __solr_current_site
|
||||
* and __current_site.
|
||||
*
|
||||
* @param integer $pageId
|
||||
* @param string $allowedSitesConfiguration
|
||||
* @return string
|
||||
*/
|
||||
protected function getDomainByPageIdAndReplaceMarkers($pageId, $allowedSitesConfiguration)
|
||||
{
|
||||
$domainOfPage = $this->getSiteByPageId($pageId)->getDomain();
|
||||
$allowedSites = str_replace(['__solr_current_site', '__current_site'], $domainOfPage, $allowedSitesConfiguration);
|
||||
return (string)$allowedSites;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Site[]
|
||||
*/
|
||||
protected function getAvailableSites()
|
||||
{
|
||||
return $this->getSiteRepository()->getAvailableSites();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pageId
|
||||
* @return SiteInterface
|
||||
*/
|
||||
protected function getSiteByPageId($pageId)
|
||||
{
|
||||
return $this->getSiteRepository()->getSiteByPageId($pageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to SiteRepository
|
||||
*
|
||||
* @return SiteRepository
|
||||
*/
|
||||
protected function getSiteRepository()
|
||||
{
|
||||
return GeneralUtility::makeInstance(SiteRepository::class);
|
||||
}
|
||||
}
|
128
Classes/Domain/Site/SiteInterface.php
Normal file
128
Classes/Domain/Site/SiteInterface.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2019 Frans Saris <frans.saris@beech.it> & Timo Hund <timo.hund@dkd.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use WapplerSystems\Meilisearch\NoSolrConnectionFoundException;
|
||||
|
||||
interface SiteInterface
|
||||
{
|
||||
/**
|
||||
* Gets the site's root page ID (uid).
|
||||
*
|
||||
* @return int The site's root page ID.
|
||||
*/
|
||||
public function getRootPageId();
|
||||
|
||||
/**
|
||||
* Gets available language id's for this site
|
||||
*
|
||||
* @return int[] array or language id's
|
||||
*/
|
||||
public function getAvailableLanguageIds(): array;
|
||||
|
||||
/**
|
||||
* Gets the site's label. The label is build from the the site title and root
|
||||
* page ID (uid).
|
||||
*
|
||||
* @return string The site's label.
|
||||
*/
|
||||
public function getLabel();
|
||||
|
||||
/**
|
||||
* Gets the site's Solr TypoScript configuration (plugin.tx_meilisearch.*)
|
||||
*
|
||||
* @return \WapplerSystems\Meilisearch\System\Configuration\TypoScriptConfiguration The Solr TypoScript configuration
|
||||
*/
|
||||
public function getSolrConfiguration();
|
||||
|
||||
/**
|
||||
* Gets the site's default language as configured in
|
||||
* config.sys_language_uid. If sys_language_uid is not set, 0 is assumed to
|
||||
* be the default.
|
||||
*
|
||||
* @return int The site's default language.
|
||||
*/
|
||||
public function getDefaultLanguage();
|
||||
|
||||
/**
|
||||
* Generates a list of page IDs in this site. Attention, this includes
|
||||
* all page types! Deleted pages are not included.
|
||||
*
|
||||
* @param int|string $rootPageId Page ID from where to start collection sub pages
|
||||
* @param int $maxDepth Maximum depth to descend into the site tree
|
||||
* @return array Array of pages (IDs) in this site
|
||||
*/
|
||||
public function getPages($rootPageId = 'SITE_ROOT', $maxDepth = 999);
|
||||
|
||||
/**
|
||||
* Generates the site's unique Site Hash.
|
||||
*
|
||||
* The Site Hash is build from the site's main domain, the system encryption
|
||||
* key, and the extension "tx_meilisearch". These components are concatenated and
|
||||
* sha1-hashed.
|
||||
*
|
||||
* @return string Site Hash.
|
||||
*/
|
||||
public function getSiteHash();
|
||||
|
||||
/**
|
||||
* Gets the site's main domain. More specifically the first domain record in
|
||||
* the site tree.
|
||||
*
|
||||
* @return string The site's main domain.
|
||||
*/
|
||||
public function getDomain();
|
||||
|
||||
/**
|
||||
* Gets the site's root page.
|
||||
*
|
||||
* @return array The site's root page.
|
||||
*/
|
||||
public function getRootPage();
|
||||
|
||||
/**
|
||||
* Gets the site's root page's title.
|
||||
*
|
||||
* @return string The site's root page's title
|
||||
*/
|
||||
public function getTitle();
|
||||
|
||||
|
||||
/**
|
||||
* @param int $language
|
||||
* @return array
|
||||
* @throws NoSolrConnectionFoundException
|
||||
*/
|
||||
public function getSolrConnectionConfiguration(int $language = 0): array;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws NoSolrConnectionFoundException
|
||||
*/
|
||||
public function getAllSolrConnectionConfigurations(): array;
|
||||
|
||||
public function isEnabled(): bool;
|
||||
}
|
341
Classes/Domain/Site/SiteRepository.php
Normal file
341
Classes/Domain/Site/SiteRepository.php
Normal file
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2017 - Thomas Hohn <tho@systime.dk>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use WapplerSystems\Meilisearch\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver;
|
||||
use WapplerSystems\Meilisearch\FrontendEnvironment;
|
||||
use WapplerSystems\Meilisearch\System\Cache\TwoLevelCache;
|
||||
use WapplerSystems\Meilisearch\System\Configuration\ExtensionConfiguration;
|
||||
use WapplerSystems\Meilisearch\System\Records\Pages\PagesRepository;
|
||||
use WapplerSystems\Meilisearch\System\Util\SiteUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
|
||||
use TYPO3\CMS\Core\Registry;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* SiteRepository
|
||||
*
|
||||
* Responsible to retrieve instances of Site objects
|
||||
*
|
||||
* @author Thomas Hohn <tho@systime.dk>
|
||||
*/
|
||||
class SiteRepository
|
||||
{
|
||||
/**
|
||||
* Rootpage resolver
|
||||
*
|
||||
* @var RootPageResolver
|
||||
*/
|
||||
protected $rootPageResolver;
|
||||
|
||||
/**
|
||||
* @var TwoLevelCache
|
||||
*/
|
||||
protected $runtimeCache;
|
||||
|
||||
/**
|
||||
* @var Registry
|
||||
*/
|
||||
protected $registry;
|
||||
|
||||
/**
|
||||
* @var SiteFinder
|
||||
*/
|
||||
protected $siteFinder;
|
||||
|
||||
/**
|
||||
* @var ExtensionConfiguration
|
||||
*/
|
||||
protected $extensionConfiguration;
|
||||
|
||||
/**
|
||||
* @var FrontendEnvironment
|
||||
*/
|
||||
protected $frontendEnvironment = null;
|
||||
|
||||
/**
|
||||
* SiteRepository constructor.
|
||||
*
|
||||
* @param RootPageResolver|null $rootPageResolver
|
||||
* @param TwoLevelCache|null $twoLevelCache
|
||||
* @param Registry|null $registry
|
||||
* @param SiteFinder|null $siteFinder
|
||||
* @param ExtensionConfiguration| null
|
||||
*/
|
||||
public function __construct(
|
||||
RootPageResolver $rootPageResolver = null,
|
||||
TwoLevelCache $twoLevelCache = null,
|
||||
Registry $registry = null,
|
||||
SiteFinder $siteFinder = null,
|
||||
ExtensionConfiguration $extensionConfiguration = null,
|
||||
FrontendEnvironment $frontendEnvironment = null
|
||||
)
|
||||
{
|
||||
$this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
|
||||
$this->runtimeCache = $twoLevelCache ?? GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */'cache_runtime');
|
||||
$this->registry = $registry ?? GeneralUtility::makeInstance(Registry::class);
|
||||
$this->siteFinder = $siteFinder ?? GeneralUtility::makeInstance(SiteFinder::class);
|
||||
$this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class);
|
||||
$this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Site for a specific page Id.
|
||||
*
|
||||
* @param int $pageId The page Id to get a Site object for.
|
||||
* @param string $mountPointIdentifier
|
||||
* @return SiteInterface Site for the given page Id.
|
||||
*/
|
||||
public function getSiteByPageId($pageId, $mountPointIdentifier = '')
|
||||
{
|
||||
$rootPageId = $this->rootPageResolver->getRootPageId($pageId, false, $mountPointIdentifier);
|
||||
return $this->getSiteByRootPageId($rootPageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Site for a specific root page Id.
|
||||
*
|
||||
* @param int $rootPageId Root page Id to get a Site object for.
|
||||
* @return SiteInterface Site for the given page Id.
|
||||
*/
|
||||
public function getSiteByRootPageId($rootPageId)
|
||||
{
|
||||
$cacheId = 'SiteRepository' . '_' . 'getSiteByPageId' . '_' . $rootPageId;
|
||||
|
||||
$methodResult = $this->runtimeCache->get($cacheId);
|
||||
if (!empty($methodResult)) {
|
||||
return $methodResult;
|
||||
}
|
||||
|
||||
$methodResult = $this->buildSite($rootPageId);
|
||||
$this->runtimeCache->set($cacheId, $methodResult);
|
||||
|
||||
return $methodResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first available Site.
|
||||
*
|
||||
* @param bool $stopOnInvalidSite
|
||||
* @throws \Exception
|
||||
* @return Site
|
||||
*/
|
||||
public function getFirstAvailableSite($stopOnInvalidSite = false)
|
||||
{
|
||||
$sites = $this->getAvailableSites($stopOnInvalidSite);
|
||||
return array_shift($sites);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all available TYPO3 sites with Solr configured.
|
||||
*
|
||||
* @param bool $stopOnInvalidSite
|
||||
* @throws \Exception
|
||||
* @return Site[] An array of availablesites
|
||||
*/
|
||||
public function getAvailableSites($stopOnInvalidSite = false)
|
||||
{
|
||||
$cacheId = 'SiteRepository' . '_' . 'getAvailableSites';
|
||||
|
||||
$sites = $this->runtimeCache->get($cacheId);
|
||||
if (!empty($sites)) {
|
||||
return $sites;
|
||||
}
|
||||
|
||||
$sites = $this->getAvailableTYPO3ManagedSites($stopOnInvalidSite);
|
||||
$this->runtimeCache->set($cacheId, $sites);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $stopOnInvalidSite
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getAvailableTYPO3ManagedSites(bool $stopOnInvalidSite): array
|
||||
{
|
||||
$typo3ManagedSolrSites = [];
|
||||
$typo3Sites = $this->siteFinder->getAllSites();
|
||||
foreach ($typo3Sites as $typo3Site) {
|
||||
try {
|
||||
$rootPageId = $typo3Site->getRootPageId();
|
||||
if (isset($typo3ManagedSolrSites[$rootPageId])) {
|
||||
//get each site only once
|
||||
continue;
|
||||
}
|
||||
$typo3ManagedSolrSite = $this->buildSite($rootPageId);
|
||||
if ($typo3ManagedSolrSite->isEnabled()) {
|
||||
$typo3ManagedSolrSites[$rootPageId] = $typo3ManagedSolrSite;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
if ($stopOnInvalidSite) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $typo3ManagedSolrSites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the Site object.
|
||||
*
|
||||
* @param integer $rootPageId
|
||||
* @throws \InvalidArgumentException
|
||||
* @return SiteInterface
|
||||
*/
|
||||
protected function buildSite($rootPageId)
|
||||
{
|
||||
if (empty($rootPageId)) {
|
||||
throw new \InvalidArgumentException('Root page id can not be empty');
|
||||
}
|
||||
$rootPageRecord = (array)BackendUtility::getRecord('pages', $rootPageId);
|
||||
|
||||
$this->validateRootPageRecord($rootPageId, $rootPageRecord);
|
||||
|
||||
return $this->buildTypo3ManagedSite($rootPageRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
* @return string
|
||||
*/
|
||||
protected function getSiteHashForDomain($domain)
|
||||
{
|
||||
/** @var $siteHashService SiteHashService */
|
||||
$siteHashService = GeneralUtility::makeInstance(SiteHashService::class);
|
||||
$siteHash = $siteHashService->getSiteHashForDomain($domain);
|
||||
return $siteHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $rootPageId
|
||||
* @param array $rootPageRecord
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function validateRootPageRecord($rootPageId, $rootPageRecord)
|
||||
{
|
||||
if (empty($rootPageRecord)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'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.',
|
||||
1487326416
|
||||
);
|
||||
}
|
||||
|
||||
if (!Site::isRootPage($rootPageRecord)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'The rootPageRecord for the given rootPageRecord ID \'' . $rootPageId . '\' is not marked as root rootPageRecord and can therefore not be used as site root rootPageRecord.',
|
||||
1309272922
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $rootPageRecord
|
||||
* @return Typo3ManagedSite
|
||||
*/
|
||||
protected function buildTypo3ManagedSite(array $rootPageRecord): ?Typo3ManagedSite
|
||||
{
|
||||
$solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($rootPageRecord['uid']);
|
||||
/** @var \TYPO3\CMS\Core\Site\Entity\Site $typo3Site */
|
||||
try {
|
||||
$typo3Site = $this->siteFinder->getSiteByPageId($rootPageRecord['uid']);
|
||||
} catch (SiteNotFoundException $e) {
|
||||
return null;
|
||||
}
|
||||
$domain = $typo3Site->getBase()->getHost();
|
||||
|
||||
$siteHash = $this->getSiteHashForDomain($domain);
|
||||
$defaultLanguage = $typo3Site->getDefaultLanguage()->getLanguageId();
|
||||
$pageRepository = GeneralUtility::makeInstance(PagesRepository::class);
|
||||
$availableLanguageIds = array_map(function($language) {
|
||||
return $language->getLanguageId();
|
||||
}, $typo3Site->getLanguages());
|
||||
|
||||
$solrConnectionConfigurations = [];
|
||||
|
||||
foreach ($availableLanguageIds as $languageUid) {
|
||||
$solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true);
|
||||
if ($solrEnabled) {
|
||||
$solrConnectionConfigurations[$languageUid] = [
|
||||
'connectionKey' => $rootPageRecord['uid'] . '|' . $languageUid,
|
||||
'rootPageTitle' => $rootPageRecord['title'],
|
||||
'rootPageUid' => $rootPageRecord['uid'],
|
||||
'read' => [
|
||||
'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'),
|
||||
'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'),
|
||||
'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983),
|
||||
// @todo: transform core to path
|
||||
'path' =>
|
||||
SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
|
||||
SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
|
||||
'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''),
|
||||
'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', '')
|
||||
],
|
||||
'write' => [
|
||||
'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'),
|
||||
'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'),
|
||||
'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983),
|
||||
// @todo: transform core to path
|
||||
'path' =>
|
||||
SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') .
|
||||
SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read', 'core_en') . '/' ,
|
||||
'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''),
|
||||
'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', '')
|
||||
],
|
||||
|
||||
'language' => $languageUid
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return GeneralUtility::makeInstance(
|
||||
Typo3ManagedSite::class,
|
||||
/** @scrutinizer ignore-type */
|
||||
$solrConfiguration,
|
||||
/** @scrutinizer ignore-type */
|
||||
$rootPageRecord,
|
||||
/** @scrutinizer ignore-type */
|
||||
$domain,
|
||||
/** @scrutinizer ignore-type */
|
||||
$siteHash,
|
||||
/** @scrutinizer ignore-type */
|
||||
$pageRepository,
|
||||
/** @scrutinizer ignore-type */
|
||||
$defaultLanguage,
|
||||
/** @scrutinizer ignore-type */
|
||||
$availableLanguageIds,
|
||||
/** @scrutinizer ignore-type */
|
||||
$solrConnectionConfigurations,
|
||||
/** @scrutinizer ignore-type */
|
||||
$typo3Site
|
||||
);
|
||||
}
|
||||
|
||||
}
|
100
Classes/Domain/Site/Typo3ManagedSite.php
Normal file
100
Classes/Domain/Site/Typo3ManagedSite.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace WapplerSystems\Meilisearch\Domain\Site;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2019 Frans Saris <frans.saris@beech.it> & Timo Hund <timo.hund@dkd.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use WapplerSystems\Meilisearch\NoSolrConnectionFoundException;
|
||||
use WapplerSystems\Meilisearch\System\Configuration\TypoScriptConfiguration;
|
||||
use WapplerSystems\Meilisearch\System\Records\Pages\PagesRepository;
|
||||
use TYPO3\CMS\Core\Context\LanguageAspectFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Site\Entity\Site as Typo3Site;
|
||||
|
||||
|
||||
/**
|
||||
* Class Typo3ManagedSite
|
||||
*/
|
||||
class Typo3ManagedSite extends Site
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Typo3Site
|
||||
*/
|
||||
protected $typo3SiteObject;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $solrConnectionConfigurations;
|
||||
|
||||
|
||||
public function __construct(
|
||||
TypoScriptConfiguration $configuration,
|
||||
array $page, $domain, $siteHash, PagesRepository $pagesRepository = null, $defaultLanguageId = 0, $availableLanguageIds = [], array $solrConnectionConfigurations = [], Typo3Site $typo3SiteObject = null)
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
$this->rootPage = $page;
|
||||
$this->domain = $domain;
|
||||
$this->siteHash = $siteHash;
|
||||
$this->pagesRepository = $pagesRepository ?? GeneralUtility::makeInstance(PagesRepository::class);
|
||||
$this->defaultLanguageId = $defaultLanguageId;
|
||||
$this->availableLanguageIds = $availableLanguageIds;
|
||||
$this->solrConnectionConfigurations = $solrConnectionConfigurations;
|
||||
$this->typo3SiteObject = $typo3SiteObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $language
|
||||
* @return array
|
||||
* @throws NoSolrConnectionFoundException
|
||||
*/
|
||||
public function getSolrConnectionConfiguration(int $language = 0): array
|
||||
{
|
||||
if (!is_array($this->solrConnectionConfigurations[$language])) {
|
||||
/* @var $noSolrConnectionException NoSolrConnectionFoundException */
|
||||
$noSolrConnectionException = GeneralUtility::makeInstance(
|
||||
NoSolrConnectionFoundException::class,
|
||||
/** @scrutinizer ignore-type */ 'Could not find a Solr connection for root page [' . $this->getRootPageId() . '] and language [' . $language . '].',
|
||||
/** @scrutinizer ignore-type */ 1552491117
|
||||
);
|
||||
$noSolrConnectionException->setRootPageId($this->getRootPageId());
|
||||
$noSolrConnectionException->setLanguageId($language);
|
||||
|
||||
throw $noSolrConnectionException;
|
||||
}
|
||||
|
||||
return $this->solrConnectionConfigurations[$language];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns \TYPO3\CMS\Core\Site\Entity\Site
|
||||
*
|
||||
* @return Typo3Site
|
||||
*/
|
||||
public function getTypo3SiteObject(): Typo3Site
|
||||
{
|
||||
return $this->typo3SiteObject;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user