meilisearch/Classes/Controller/Backend/Search/AbstractModuleController.php

329 lines
12 KiB
PHP
Raw Normal View History

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);
}
}