329 lines
12 KiB
PHP
329 lines
12 KiB
PHP
<?php
|
|
namespace WapplerSystems\Meilisearch\Controller\Backend\Search;
|
|
|
|
/***************************************************************
|
|
* Copyright notice
|
|
*
|
|
* (c) 2010-2017 dkd Internet Service GmbH <meilisearch-support@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\ConnectionManager;
|
|
use WapplerSystems\Meilisearch\Domain\Site\SiteRepository;
|
|
use WapplerSystems\Meilisearch\Domain\Site\Site;
|
|
use WapplerSystems\Meilisearch\System\Meilisearch\MeilisearchConnection as MeilisearchCoreConnection;
|
|
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;
|
|
|
|
/**
|
|
* @var MeilisearchCoreConnection
|
|
*/
|
|
protected $selectedMeilisearchCoreConnection;
|
|
|
|
/**
|
|
* @var Menu
|
|
*/
|
|
protected $coreSelectorMenu = null;
|
|
|
|
/**
|
|
* @var ConnectionManager
|
|
*/
|
|
protected $meilisearchConnectionManager = null;
|
|
|
|
/**
|
|
* @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();
|
|
$this->meilisearchConnectionManager = GeneralUtility::makeInstance(ConnectionManager::class);
|
|
$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) {
|
|
$this->initializeSelectedMeilisearchCoreConnection();
|
|
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();
|
|
}
|
|
|
|
$this->initializeSelectedMeilisearchCoreConnection();
|
|
$cores = $this->meilisearchConnectionManager->getConnectionsBySite($site);
|
|
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);
|
|
|
|
if ($coreAdmin->getCorePath() == $this->selectedMeilisearchCoreConnection->getAdminService()->getCorePath()) {
|
|
$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);
|
|
$message = LocalizationUtility::translate('coreselector_switched_successfully', 'meilisearch', [$corePath]);
|
|
$this->addFlashMessage($message);
|
|
$this->redirectToUri($uriToRedirectTo);
|
|
}
|
|
|
|
/**
|
|
* Initializes the meilisearch core connection considerately to the components state.
|
|
* Uses and persists default core connection if persisted core in Site does not exist.
|
|
*
|
|
*/
|
|
private function initializeSelectedMeilisearchCoreConnection()
|
|
{
|
|
$moduleData = $this->moduleDataStorageService->loadModuleData();
|
|
|
|
$meilisearchCoreConnections = $this->meilisearchConnectionManager->getConnectionsBySite($this->selectedSite);
|
|
$currentMeilisearchCorePath = $moduleData->getCore();
|
|
if (empty($currentMeilisearchCorePath)) {
|
|
$this->initializeFirstAvailableMeilisearchCoreConnection($meilisearchCoreConnections, $moduleData);
|
|
return;
|
|
}
|
|
foreach ($meilisearchCoreConnections as $meilisearchCoreConnection) {
|
|
if ($meilisearchCoreConnection->getAdminService()->getCorePath() == $currentMeilisearchCorePath) {
|
|
$this->selectedMeilisearchCoreConnection = $meilisearchCoreConnection;
|
|
}
|
|
}
|
|
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()]);
|
|
$this->addFlashMessage($message, '', AbstractMessage::NOTICE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param MeilisearchCoreConnection[] $meilisearchCoreConnections
|
|
*/
|
|
private function initializeFirstAvailableMeilisearchCoreConnection(array $meilisearchCoreConnections, $moduleData)
|
|
{
|
|
if (empty($meilisearchCoreConnections)) {
|
|
return;
|
|
}
|
|
$this->selectedMeilisearchCoreConnection = $meilisearchCoreConnections[0];
|
|
$moduleData->setCore($this->selectedMeilisearchCoreConnection->getAdminService()->getCorePath());
|
|
$this->moduleDataStorageService->persistModuleData($moduleData);
|
|
}
|
|
}
|