2021-04-17 00:26:33 +02:00
< ? php
namespace WapplerSystems\Meilisearch\Controller\Backend\Search ;
/***************************************************************
* Copyright notice
*
2021-04-17 21:20:54 +02:00
* ( c ) 2010 - 2017 dkd Internet Service GmbH < meilisearch - support @ dkd . de >
2021-04-17 00:26:33 +02:00
* 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\ConnectionManager ;
use WapplerSystems\Meilisearch\Domain\Site\SiteRepository ;
use WapplerSystems\Meilisearch\Domain\Site\Site ;
2021-04-17 21:20:54 +02:00
use WapplerSystems\Meilisearch\System\Meilisearch\MeilisearchConnection as MeilisearchCoreConnection ;
2021-04-17 00:26:33 +02:00
use WapplerSystems\Meilisearch\System\Mvc\Backend\Component\Exception\InvalidViewObjectNameException ;
use WapplerSystems\Meilisearch\System\Mvc\Backend\Service\ModuleDataStorageService ;
use TYPO3\CMS\Backend\Template\Components\Menu\Menu ;
use TYPO3\CMS\Backend\Utility\BackendUtility ;
use TYPO3\CMS\Backend\View\BackendTemplateView ;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication ;
use TYPO3\CMS\Core\Messaging\AbstractMessage ;
use TYPO3\CMS\Core\Utility\GeneralUtility ;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController ;
use TYPO3\CMS\Extbase\Mvc\View\NotFoundView ;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface ;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility ;
/**
* Abstract Module
*
* @ property BackendTemplateView $view
*/
abstract class AbstractModuleController extends ActionController
{
/**
* Backend Template Container
*
* @ var string
*/
protected $defaultViewObjectName = BackendTemplateView :: class ;
/**
* In the pagetree selected page UID
*
* @ var int
*/
protected $selectedPageUID ;
/**
* Holds the requested page UID because the selected page uid ,
* might be overwritten by the automatic site selection .
*
* @ var int
*/
protected $requestedPageUID ;
/**
* @ var Site
*/
protected $selectedSite ;
/**
* @ var SiteRepository
*/
protected $siteRepository ;
/**
2021-04-17 21:20:54 +02:00
* @ var MeilisearchCoreConnection
2021-04-17 00:26:33 +02:00
*/
2021-04-17 21:20:54 +02:00
protected $selectedMeilisearchCoreConnection ;
2021-04-17 00:26:33 +02:00
/**
* @ var Menu
*/
protected $coreSelectorMenu = null ;
/**
* @ var ConnectionManager
*/
2021-04-17 21:20:54 +02:00
protected $meilisearchConnectionManager = null ;
2021-04-17 00:26:33 +02:00
/**
* @ var ModuleDataStorageService
*/
protected $moduleDataStorageService = null ;
/**
* @ param Site $selectedSite
*/
public function setSelectedSite ( Site $selectedSite )
{
$this -> selectedSite = $selectedSite ;
}
/**
* @ param SiteRepository $siteRepository
*/
public function injectSiteRepository ( SiteRepository $siteRepository )
{
$this -> siteRepository = $siteRepository ;
}
/**
* Initializes the controller and sets needed vars .
*/
protected function initializeAction ()
{
parent :: initializeAction ();
2021-04-17 21:20:54 +02:00
$this -> meilisearchConnectionManager = GeneralUtility :: makeInstance ( ConnectionManager :: class );
2021-04-17 00:26:33 +02:00
$this -> moduleDataStorageService = GeneralUtility :: makeInstance ( ModuleDataStorageService :: class );
$this -> selectedPageUID = ( int ) GeneralUtility :: _GP ( 'id' );
if ( $this -> request -> hasArgument ( 'id' )) {
$this -> selectedPageUID = ( int ) $this -> request -> getArgument ( 'id' );
}
$this -> requestedPageUID = $this -> selectedPageUID ;
if ( $this -> autoSelectFirstSiteAndRootPageWhenOnlyOneSiteIsAvailable ()) {
return ;
}
if ( $this -> selectedPageUID < 1 ) {
return ;
}
try {
$this -> selectedSite = $this -> siteRepository -> getSiteByPageId ( $this -> selectedPageUID );
} catch ( \InvalidArgumentException $exception ) {
return ;
}
}
/**
* @ return bool
* @ throws \Exception
*/
protected function autoSelectFirstSiteAndRootPageWhenOnlyOneSiteIsAvailable () : bool
{
if ( count ( $this -> siteRepository -> getAvailableSites ()) == 1 ) {
$this -> selectedSite = $this -> siteRepository -> getFirstAvailableSite ();
// we only overwrite the selected pageUid when no id was passed
if ( $this -> selectedPageUID === 0 ) {
$this -> selectedPageUID = $this -> selectedSite -> getRootPageId ();
}
return true ;
}
return false ;
}
/**
* Set up the doc header properly here
*
* @ param ViewInterface $view
* @ return void
*/
protected function initializeView ( ViewInterface $view )
{
parent :: initializeView ( $view );
$sites = $this -> siteRepository -> getAvailableSites ();
$selectOtherPage = count ( $sites ) > 0 || $this -> selectedPageUID < 1 ;
$this -> view -> assign ( 'showSelectOtherPage' , $selectOtherPage );
$this -> view -> assign ( 'pageUID' , $this -> selectedPageUID );
if ( $view instanceof NotFoundView || $this -> selectedPageUID < 1 ) {
return ;
}
$this -> view -> getModuleTemplate () -> addJavaScriptCode ( 'mainJsFunctions' , '
top . fsMod . recentIds [ " searchbackend " ] = ' . (int)$this->selectedPageUID . ' ; '
);
if ( null === $this -> selectedSite ) {
return ;
}
/* @var BackendUserAuthentication $beUser */
$beUser = $GLOBALS [ 'BE_USER' ];
$permissionClause = $beUser -> getPagePermsClause ( 1 );
$pageRecord = BackendUtility :: readPageAccess ( $this -> selectedSite -> getRootPageId (), $permissionClause );
if ( false === $pageRecord ) {
throw new \InvalidArgumentException ( vsprintf ( 'There is something wrong with permissions for page "%s" for backend user "%s".' , [ $this -> selectedSite -> getRootPageId (), $beUser -> user [ 'username' ]]), 1496146317 );
}
$this -> view -> getModuleTemplate () -> getDocHeaderComponent () -> setMetaInformation ( $pageRecord );
}
/**
* Generates selector menu in backends doc header using selected page from page tree .
*
* @ param string | null $uriToRedirectTo
*/
public function generateCoreSelectorMenuUsingPageTree ( string $uriToRedirectTo = null )
{
if ( $this -> selectedPageUID < 1 || null === $this -> selectedSite ) {
return ;
}
if ( $this -> view instanceof NotFoundView ) {
2021-04-17 21:20:54 +02:00
$this -> initializeSelectedMeilisearchCoreConnection ();
2021-04-17 00:26:33 +02:00
return ;
}
$this -> generateCoreSelectorMenu ( $this -> selectedSite , $uriToRedirectTo );
}
/**
* Generates Core selector Menu for given Site .
*
* @ param Site $site
* @ param string | null $uriToRedirectTo
* @ throws InvalidViewObjectNameException
*/
protected function generateCoreSelectorMenu ( Site $site , string $uriToRedirectTo = null )
{
if ( ! $this -> view instanceof BackendTemplateView ) {
throw new InvalidViewObjectNameException ( vsprintf (
' The controller " %s " must use BackendTemplateView to be able to generate menu for backends docheader . \
Please set `protected $defaultViewObjectName = BackendTemplateView::class;` field in your controller . ' ,
[ static :: class ]), 1493804179 );
}
$this -> view -> getModuleTemplate () -> setFlashMessageQueue ( $this -> controllerContext -> getFlashMessageQueue ());
$this -> coreSelectorMenu = $this -> view -> getModuleTemplate () -> getDocHeaderComponent () -> getMenuRegistry () -> makeMenu ();
$this -> coreSelectorMenu -> setIdentifier ( 'component_core_selector_menu' );
if ( ! isset ( $uriToRedirectTo )) {
$uriToRedirectTo = $this -> uriBuilder -> reset () -> uriFor ();
}
2021-04-17 21:20:54 +02:00
$this -> initializeSelectedMeilisearchCoreConnection ();
$cores = $this -> meilisearchConnectionManager -> getConnectionsBySite ( $site );
2021-04-17 00:26:33 +02:00
foreach ( $cores as $core ) {
$coreAdmin = $core -> getAdminService ();
$menuItem = $this -> coreSelectorMenu -> makeMenuItem ();
$menuItem -> setTitle ( $coreAdmin -> getCorePath ());
$uri = $this -> uriBuilder -> reset () -> uriFor ( 'switchCore' ,
[
'corePath' => $coreAdmin -> getCorePath (),
'uriToRedirectTo' => $uriToRedirectTo
]
);
$menuItem -> setHref ( $uri );
2021-04-17 21:20:54 +02:00
if ( $coreAdmin -> getCorePath () == $this -> selectedMeilisearchCoreConnection -> getAdminService () -> getCorePath ()) {
2021-04-17 00:26:33 +02:00
$menuItem -> setActive ( true );
}
$this -> coreSelectorMenu -> addMenuItem ( $menuItem );
}
$this -> view -> getModuleTemplate () -> getDocHeaderComponent () -> getMenuRegistry () -> addMenu ( $this -> coreSelectorMenu );
}
/**
* Switches used core .
*
* Note : Does not check availability of core in site . All this stuff is done in the generation step .
*
* @ param string $corePath
* @ param string $uriToRedirectTo
*/
public function switchCoreAction ( string $corePath , string $uriToRedirectTo )
{
$moduleData = $this -> moduleDataStorageService -> loadModuleData ();
$moduleData -> setCore ( $corePath );
$this -> moduleDataStorageService -> persistModuleData ( $moduleData );
2021-04-17 21:20:54 +02:00
$message = LocalizationUtility :: translate ( 'coreselector_switched_successfully' , 'meilisearch' , [ $corePath ]);
2021-04-17 00:26:33 +02:00
$this -> addFlashMessage ( $message );
$this -> redirectToUri ( $uriToRedirectTo );
}
/**
2021-04-17 21:20:54 +02:00
* Initializes the meilisearch core connection considerately to the components state .
2021-04-17 00:26:33 +02:00
* Uses and persists default core connection if persisted core in Site does not exist .
*
*/
2021-04-17 21:20:54 +02:00
private function initializeSelectedMeilisearchCoreConnection ()
2021-04-17 00:26:33 +02:00
{
$moduleData = $this -> moduleDataStorageService -> loadModuleData ();
2021-04-17 21:20:54 +02:00
$meilisearchCoreConnections = $this -> meilisearchConnectionManager -> getConnectionsBySite ( $this -> selectedSite );
$currentMeilisearchCorePath = $moduleData -> getCore ();
if ( empty ( $currentMeilisearchCorePath )) {
$this -> initializeFirstAvailableMeilisearchCoreConnection ( $meilisearchCoreConnections , $moduleData );
2021-04-17 00:26:33 +02:00
return ;
}
2021-04-17 21:20:54 +02:00
foreach ( $meilisearchCoreConnections as $meilisearchCoreConnection ) {
if ( $meilisearchCoreConnection -> getAdminService () -> getCorePath () == $currentMeilisearchCorePath ) {
$this -> selectedMeilisearchCoreConnection = $meilisearchCoreConnection ;
2021-04-17 00:26:33 +02:00
}
}
2021-04-17 21:20:54 +02:00
if ( ! $this -> selectedMeilisearchCoreConnection instanceof MeilisearchCoreConnection && count ( $meilisearchCoreConnections ) > 0 ) {
$this -> initializeFirstAvailableMeilisearchCoreConnection ( $meilisearchCoreConnections , $moduleData );
$message = LocalizationUtility :: translate ( 'coreselector_switched_to_default_core' , 'meilisearch' , [ $currentMeilisearchCorePath , $this -> selectedSite -> getLabel (), $this -> selectedMeilisearchCoreConnection -> getAdminService () -> getCorePath ()]);
2021-04-17 00:26:33 +02:00
$this -> addFlashMessage ( $message , '' , AbstractMessage :: NOTICE );
}
}
/**
2021-04-17 21:20:54 +02:00
* @ param MeilisearchCoreConnection [] $meilisearchCoreConnections
2021-04-17 00:26:33 +02:00
*/
2021-04-17 21:20:54 +02:00
private function initializeFirstAvailableMeilisearchCoreConnection ( array $meilisearchCoreConnections , $moduleData )
2021-04-17 00:26:33 +02:00
{
2021-04-17 21:20:54 +02:00
if ( empty ( $meilisearchCoreConnections )) {
2021-04-17 00:26:33 +02:00
return ;
}
2021-04-17 21:20:54 +02:00
$this -> selectedMeilisearchCoreConnection = $meilisearchCoreConnections [ 0 ];
$moduleData -> setCore ( $this -> selectedMeilisearchCoreConnection -> getAdminService () -> getCorePath ());
2021-04-17 00:26:33 +02:00
$this -> moduleDataStorageService -> persistModuleData ( $moduleData );
}
}