158 lines
5.9 KiB
PHP
158 lines
5.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* This file is part of the TYPO3 CMS project.
|
|
*
|
|
* It is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*
|
|
* The TYPO3 project - inspiring people to share!
|
|
*/
|
|
|
|
namespace TYPO3\CMS\Core\Hooks;
|
|
|
|
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
|
use TYPO3\CMS\Core\Configuration\Exception\SiteConfigurationWriteException;
|
|
use TYPO3\CMS\Core\Configuration\SiteWriter;
|
|
use TYPO3\CMS\Core\Core\Environment;
|
|
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
|
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
|
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
|
|
use TYPO3\CMS\Core\Http\NormalizedParams;
|
|
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
|
use TYPO3\CMS\Core\Messaging\FlashMessageService;
|
|
use TYPO3\CMS\Core\Site\SiteFinder;
|
|
use TYPO3\CMS\Core\SysLog\Action\Site as SiteAction;
|
|
use TYPO3\CMS\Core\SysLog\Error as SystemLogErrorClassification;
|
|
use TYPO3\CMS\Core\SysLog\Type;
|
|
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
|
|
/**
|
|
* Hook for creating a basic site configuration for new pages on root level.
|
|
*
|
|
* @internal This class is a hook implementation and is not part of the TYPO3 Core API.
|
|
*/
|
|
class CreateSiteConfiguration
|
|
{
|
|
/**
|
|
* @var int[]
|
|
*/
|
|
protected $allowedPageTypes = [
|
|
PageRepository::DOKTYPE_DEFAULT,
|
|
PageRepository::DOKTYPE_LINK,
|
|
PageRepository::DOKTYPE_SHORTCUT,
|
|
];
|
|
|
|
public function processDatamap_afterDatabaseOperations(string $status, string $table, $id, array $fieldValues, DataHandler $dataHandler): void
|
|
{
|
|
/**
|
|
* Take action only on
|
|
* - new records
|
|
* - pages table
|
|
* - live workspace
|
|
* - resolved uids
|
|
* - pages on root level OR with is_siteroot set
|
|
* - pages in default language
|
|
* - non-versioned records
|
|
* - allowed doktypes
|
|
* - not bulk importing things via CLI
|
|
*/
|
|
if ($status !== 'new'
|
|
|| $table !== 'pages'
|
|
|| $dataHandler->BE_USER->workspace > 0
|
|
|| !isset($dataHandler->substNEWwithIDs[$id])
|
|
|| (int)($fieldValues['l10n_parent'] ?? 0) !== 0
|
|
|| ((int)$fieldValues['pid'] !== 0 && !($fieldValues['is_siteroot'] ?? false))
|
|
|| (isset($fieldValues['t3ver_oid']) && (int)$fieldValues['t3ver_oid'] > 0)
|
|
|| !in_array((int)$fieldValues['doktype'], $this->allowedPageTypes, true)
|
|
|| $dataHandler->isImporting
|
|
) {
|
|
return;
|
|
}
|
|
|
|
$uid = (int)$dataHandler->substNEWwithIDs[$id];
|
|
$this->generateSiteConfigurationForRootPage($uid, $dataHandler->BE_USER);
|
|
}
|
|
|
|
protected function generateSiteConfigurationForRootPage(int $pageId, BackendUserAuthentication $backendUser): void
|
|
{
|
|
$entryPoint = 'autogenerated-' . $pageId;
|
|
$siteIdentifier = $entryPoint . '-' . md5((string)$pageId);
|
|
|
|
if (!$this->siteExistsByRootPageId($pageId)) {
|
|
$siteWriter = GeneralUtility::makeInstance(SiteWriter::class);
|
|
$normalizedParams = $this->getNormalizedParams();
|
|
$basePrefix = Environment::isCli() ? $normalizedParams->getSitePath() : $normalizedParams->getSiteUrl();
|
|
try {
|
|
$siteWriter->createNewBasicSite(
|
|
$siteIdentifier,
|
|
$pageId,
|
|
$basePrefix . $entryPoint
|
|
);
|
|
$backendUser->writelog(Type::SITE, SiteAction::CREATE, SystemLogErrorClassification::MESSAGE, null, 'Site configuration \'%s\' was automatically created for new root page (%s).', [$siteIdentifier, $pageId], 'site');
|
|
$this->updateSlugForPage($pageId);
|
|
} catch (SiteConfigurationWriteException $e) {
|
|
$flashMessage = new FlashMessage($e->getMessage(), '', ContextualFeedbackSeverity::WARNING, true);
|
|
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
|
|
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
|
|
$defaultFlashMessageQueue->enqueue($flashMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function getNormalizedParams(): NormalizedParams
|
|
{
|
|
$normalizedParams = null;
|
|
$serverParams = Environment::isCli() ? ['HTTP_HOST' => 'localhost'] : $_SERVER;
|
|
if (isset($GLOBALS['TYPO3_REQUEST'])) {
|
|
$normalizedParams = $GLOBALS['TYPO3_REQUEST']->getAttribute('normalizedParams');
|
|
$serverParams = $GLOBALS['TYPO3_REQUEST']->getServerParams();
|
|
}
|
|
|
|
if (!$normalizedParams instanceof NormalizedParams) {
|
|
$normalizedParams = NormalizedParams::createFromServerParams($serverParams);
|
|
}
|
|
|
|
return $normalizedParams;
|
|
}
|
|
|
|
/**
|
|
* Updates the slug of the given pageId by spinning up a new DataHandler instance.
|
|
*/
|
|
protected function updateSlugForPage(int $pageId): void
|
|
{
|
|
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
|
|
$dataMap = [
|
|
'pages' => [
|
|
$pageId => [
|
|
'slug' => '',
|
|
],
|
|
],
|
|
];
|
|
$dataHandler->start($dataMap, []);
|
|
$dataHandler->process_datamap();
|
|
}
|
|
|
|
/**
|
|
* Checks whether a site exists by its root page. Sets up a new SiteFinder instance
|
|
*
|
|
* @param int $rootPageId the page ID (default language)
|
|
*/
|
|
protected function siteExistsByRootPageId(int $rootPageId): bool
|
|
{
|
|
try {
|
|
GeneralUtility::makeInstance(SiteFinder::class)->getSiteByRootPageId($rootPageId);
|
|
} catch (SiteNotFoundException $e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|