2021-04-17 00:26:33 +02:00
< ? 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 );
}
/**
2021-04-17 21:20:54 +02:00
* Gets all available TYPO3 sites with Meilisearch configured .
2021-04-17 00:26:33 +02:00
*
* @ 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
{
2021-04-17 21:20:54 +02:00
$typo3ManagedMeilisearchSites = [];
2021-04-17 00:26:33 +02:00
$typo3Sites = $this -> siteFinder -> getAllSites ();
foreach ( $typo3Sites as $typo3Site ) {
try {
$rootPageId = $typo3Site -> getRootPageId ();
2021-04-17 21:20:54 +02:00
if ( isset ( $typo3ManagedMeilisearchSites [ $rootPageId ])) {
2021-04-17 00:26:33 +02:00
//get each site only once
continue ;
}
2021-04-17 21:20:54 +02:00
$typo3ManagedMeilisearchSite = $this -> buildSite ( $rootPageId );
if ( $typo3ManagedMeilisearchSite -> isEnabled ()) {
$typo3ManagedMeilisearchSites [ $rootPageId ] = $typo3ManagedMeilisearchSite ;
2021-04-17 00:26:33 +02:00
}
} catch ( \Exception $e ) {
if ( $stopOnInvalidSite ) {
throw $e ;
}
}
}
2021-04-17 21:20:54 +02:00
return $typo3ManagedMeilisearchSites ;
2021-04-17 00:26:33 +02:00
}
/**
* 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
{
2021-04-17 21:20:54 +02:00
$meilisearchConfiguration = $this -> frontendEnvironment -> getMeilisearchConfigurationFromPageId ( $rootPageRecord [ 'uid' ]);
2021-04-17 00:26:33 +02:00
/** @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 ());
2021-04-17 21:20:54 +02:00
$meilisearchConnectionConfigurations = [];
2021-04-17 00:26:33 +02:00
foreach ( $availableLanguageIds as $languageUid ) {
2021-04-17 21:20:54 +02:00
$meilisearchEnabled = SiteUtility :: getConnectionProperty ( $typo3Site , 'enabled' , $languageUid , 'read' , true );
if ( $meilisearchEnabled ) {
$meilisearchConnectionConfigurations [ $languageUid ] = [
2021-04-17 00:26:33 +02:00
'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' ),
2021-04-17 21:20:54 +02:00
'port' => ( int ) SiteUtility :: getConnectionProperty ( $typo3Site , 'port' , $languageUid , 'read' , 7700 ),
'apiKey' => SiteUtility :: getConnectionProperty ( $typo3Site , 'apiKey' , $languageUid , 'read' , '' ),
2021-04-17 00:26:33 +02:00
],
'write' => [
'scheme' => SiteUtility :: getConnectionProperty ( $typo3Site , 'scheme' , $languageUid , 'write' , 'http' ),
'host' => SiteUtility :: getConnectionProperty ( $typo3Site , 'host' , $languageUid , 'write' , 'localhost' ),
2021-04-17 21:20:54 +02:00
'port' => ( int ) SiteUtility :: getConnectionProperty ( $typo3Site , 'port' , $languageUid , 'write' , 7700 ),
'apiKey' => SiteUtility :: getConnectionProperty ( $typo3Site , 'apiKey' , $languageUid , 'write' , '' ),
2021-04-17 00:26:33 +02:00
],
'language' => $languageUid
];
}
}
return GeneralUtility :: makeInstance (
Typo3ManagedSite :: class ,
/** @scrutinizer ignore-type */
2021-04-17 21:20:54 +02:00
$meilisearchConfiguration ,
2021-04-17 00:26:33 +02:00
/** @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 */
2021-04-17 21:20:54 +02:00
$meilisearchConnectionConfigurations ,
2021-04-17 00:26:33 +02:00
/** @scrutinizer ignore-type */
$typo3Site
);
}
}