* 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\PingFailedException; use WapplerSystems\Meilisearch\System\Meilisearch\Service\MeilisearchAdminService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Reports\Status; use TYPO3\CMS\Reports\StatusProviderInterface; /** * Provides an status report about whether a connection to the Meilisearch server can * be established. * * @author Ingo Renner */ class MeilisearchStatus extends AbstractMeilisearchStatus { /** * Site Repository * * @var SiteRepository */ protected $siteRepository = null; /** * Connection Manager * * @var ConnectionManager */ protected $connectionManager = null; /** * Holds the response status * * @var int */ protected $responseStatus = Status::OK; /** * Holds the response message build by the checks * * @var string */ protected $responseMessage = ''; /** * MeilisearchStatus constructor. * @param SiteRepository|null $siteRepository * @param ConnectionManager|null $connectionManager */ public function __construct(SiteRepository $siteRepository = null, ConnectionManager $connectionManager = null) { $this->siteRepository = $siteRepository ?? GeneralUtility::makeInstance(SiteRepository::class); $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class); } /** * Compiles a collection of status checks against each configured Meilisearch server. * */ public function getStatus() { $reports = []; foreach ($this->siteRepository->getAvailableSites() as $site) { foreach ($site->getAllMeilisearchConnectionConfigurations() as $meilisearchConfiguration) { $reports[] = $this->getConnectionStatus($meilisearchConfiguration); } } return $reports; } /** * Checks whether a Meilisearch server is available and provides some information. * * @param array $meilisearchConnection Meilisearch connection parameters * @return Status Status of the Meilisearch connection */ protected function getConnectionStatus(array $meilisearchConnection) { $header = 'Your site has contacted the Meilisearch server.'; $this->responseStatus = Status::OK; $meilisearchAdmin = $this->connectionManager ->getMeilisearchConnectionForNodes($meilisearchConnection['read'], $meilisearchConnection['write']) ->getAdminService(); $meilisearchVersion = $this->checkMeilisearchVersion($meilisearchAdmin); $accessFilter = $this->checkAccessFilter($meilisearchAdmin); $pingTime = $this->checkPingTime($meilisearchAdmin); $configName = $this->checkMeilisearchConfigName($meilisearchAdmin); $schemaName = $this->checkMeilisearchSchemaName($meilisearchAdmin); if ($this->responseStatus !== Status::OK) { $header = 'Failed contacting the Meilisearch server.'; } $variables = [ 'header' => $header, 'connection' => $meilisearchConnection, 'meilisearch' => $meilisearchAdmin, 'meilisearchVersion' => $meilisearchVersion, 'pingTime' => $pingTime, 'configName' => $configName, 'schemaName' => $schemaName, 'accessFilter' => $accessFilter ]; $report = $this->getRenderedReport('MeilisearchStatus.html', $variables); return GeneralUtility::makeInstance( Status::class, /** @scrutinizer ignore-type */ 'Meilisearch', /** @scrutinizer ignore-type */ '', /** @scrutinizer ignore-type */ $report, /** @scrutinizer ignore-type */ $this->responseStatus ); } /** * Checks the meilisearch version and adds it to the report. * * @param MeilisearchAdminService $meilisearch * @return string meilisearch version */ protected function checkMeilisearchVersion(MeilisearchAdminService $meilisearch) { try { $meilisearchVersion = $this->formatMeilisearchVersion($meilisearch->getMeilisearchServerVersion()); } catch (\Exception $e) { $this->responseStatus = Status::ERROR; $meilisearchVersion = 'Error getting meilisearch version: ' . $e->getMessage(); } return $meilisearchVersion; } /** * Checks the access filter setup and adds it to the report. * * @param MeilisearchAdminService $meilisearchAdminService * @return string */ protected function checkAccessFilter(MeilisearchAdminService $meilisearchAdminService) { try { $accessFilterPluginStatus = GeneralUtility::makeInstance(AccessFilterPluginInstalledStatus::class); $accessFilterPluginVersion = $accessFilterPluginStatus->getInstalledPluginVersion($meilisearchAdminService); $accessFilterMessage = $accessFilterPluginVersion; } catch (\Exception $e) { $this->responseStatus = Status::ERROR; $accessFilterMessage = 'Error getting access filter: ' . $e->getMessage(); } return $accessFilterMessage; } /** * Checks the ping time and adds it to the report. * * @param MeilisearchAdminService $meilisearchAdminService * @return string */ protected function checkPingTime(MeilisearchAdminService $meilisearchAdminService) { try { $pingQueryTime = $meilisearchAdminService->getPingRoundTripRuntime(); $pingMessage = (int)$pingQueryTime . ' ms'; } catch (PingFailedException $e) { $this->responseStatus = Status::ERROR; $pingMessage = 'Ping error: ' . $e->getMessage(); } return $pingMessage; } /** * Checks the meilisearch config name and adds it to the report. * * @param MeilisearchAdminService $meilisearchAdminService * @return string */ protected function checkMeilisearchConfigName(MeilisearchAdminService $meilisearchAdminService) { try { $meilisearchConfigMessage = $meilisearchAdminService->getMeilisearchconfigName(); } catch (\Exception $e) { $this->responseStatus = Status::ERROR; $meilisearchConfigMessage = 'Error determining meilisearch config: ' . $e->getMessage(); } return $meilisearchConfigMessage; } /** * Checks the meilisearch schema name and adds it to the report. * * @param MeilisearchAdminService $meilisearchAdminService * @return string */ protected function checkMeilisearchSchemaName(MeilisearchAdminService $meilisearchAdminService) { try { $meilisearchSchemaMessage = $meilisearchAdminService->getSchema()->getName(); } catch (\Exception $e) { $this->responseStatus = Status::ERROR; $meilisearchSchemaMessage = 'Error determining schema name: ' . $e->getMessage(); } return $meilisearchSchemaMessage; } /** * Formats the Meilisearch server version number. By default this is going * to be the simple major.minor.patch-level version. Custom Builds provide * more information though, in case of custom builds, their complete * version will be added, too. * * @param string $meilisearchVersion Unformatted Meilisearch version number as provided by Meilisearch. * @return string formatted short version number, in case of custom builds followed by the complete version number */ protected function formatMeilisearchVersion($meilisearchVersion) { $explodedMeilisearchVersion = explode('.', $meilisearchVersion); $shortMeilisearchVersion = $explodedMeilisearchVersion[0] . '.' . $explodedMeilisearchVersion[1] . '.' . $explodedMeilisearchVersion[2]; $formattedMeilisearchVersion = $shortMeilisearchVersion; if ($meilisearchVersion != $shortMeilisearchVersion) { $formattedMeilisearchVersion .= ' (' . $meilisearchVersion . ')'; } return $formattedMeilisearchVersion; } }