TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:33 +02:00
commit 1a6eae9988
124 changed files with 11393 additions and 0 deletions
+199
View File
@@ -0,0 +1,199 @@
<?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\Redirects\Controller;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Attribute\AsController;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
use TYPO3\CMS\Backend\Template\Components\MultiRecordSelection\Action;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Configuration\Features;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\IconSize;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Redirects\Event\ModifyRedirectManagementControllerViewDataEvent;
use TYPO3\CMS\Redirects\Repository\Demand;
use TYPO3\CMS\Redirects\Repository\RedirectRepository;
use TYPO3\CMS\Redirects\Service\ModulePaginationService;
use TYPO3\CMS\Redirects\Utility\RedirectConflict;
/**
* Lists all redirects in the TYPO3 Backend as a module.
*
* @internal This class is a specific TYPO3 Backend controller implementation and is not part of the Public TYPO3 API.
*/
#[AsController]
class ManagementController
{
public function __construct(
protected UriBuilder $uriBuilder,
protected IconFactory $iconFactory,
protected RedirectRepository $redirectRepository,
protected ModuleTemplateFactory $moduleTemplateFactory,
private EventDispatcherInterface $eventDispatcher,
protected ComponentFactory $componentFactory,
protected ModulePaginationService $modulePaginationService,
) {}
/**
* Injects the request object for the current request, and renders the overview of all redirects
*/
public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
$view = $this->moduleTemplateFactory->create($request);
$demand = Demand::fromRequest($request);
$redirectType = $demand->getRedirectType();
$view->setTitle(
$this->getLanguageService()->translate('title', 'redirects.modules.redirects')
);
$view->makeDocHeaderModuleMenu();
$this->registerDocHeaderButtons($view);
if (!$this->canListRedirects()) {
return $view->renderResponse('Management/Overview');
}
$event = $this->eventDispatcher->dispatch(
new ModifyRedirectManagementControllerViewDataEvent(
$demand,
$this->redirectRepository->findRedirectsByDemand($demand),
$this->redirectRepository->findHostsOfRedirects($redirectType),
$this->redirectRepository->findStatusCodesOfRedirects($redirectType),
$this->redirectRepository->findCreationTypes($redirectType),
GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount'),
$view,
$request,
$this->redirectRepository->findIntegrityStatusCodes($redirectType),
)
);
$requestUri = $request->getAttribute('normalizedParams')->getRequestUri();
$pagination = $this->modulePaginationService->preparePagination($demand);
$languageService = $this->getLanguageService();
$view = $event->getView();
$hasEditPermissions = $this->canEditRedirects();
$view->assignMultiple([
'redirects' => $event->getRedirects(),
'hosts' => $event->getHosts(),
'statusCodes' => $event->getStatusCodes(),
'creationTypes' => $event->getCreationTypes(),
'integrityStatusCodes' => $event->getIntegrityStatusCodes(),
'defaultIntegrityStatus' => RedirectConflict::NO_CONFLICT,
'demand' => $event->getDemand(),
'showHitCounter' => $event->getShowHitCounter(),
'pagination' => $pagination,
'canEditRedirects' => $hasEditPermissions,
'canListRedirects' => true,
'returnUrl' => $this->uriBuilder->buildUriFromRoute('redirects', [
'page' => $pagination['current'],
'demand' => $demand->getParameters(),
'orderField' => $demand->getOrderField(),
'orderDirection' => $demand->getOrderDirection(),
]),
'actions' => $hasEditPermissions ? [
new Action(
'edit',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'returnUrl' => $requestUri,
],
'actions-open',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.edit'
),
new Action(
'delete',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'title' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:labels.delete.title'),
'content' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:labels.delete.message'),
'ok' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'),
'cancel' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel'),
'returnUrl' => $requestUri,
],
'actions-edit-delete',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'
),
] : [],
]);
return $view->renderResponse('Management/Overview');
}
protected function canListRedirects(): bool
{
return $this->getBackendUser()->check('tables_select', 'sys_redirect');
}
protected function canEditRedirects(): bool
{
return $this->getBackendUser()->check('tables_modify', 'sys_redirect');
}
/**
* Create document header buttons
*/
protected function registerDocHeaderButtons(ModuleTemplate $view): void
{
$languageService = $this->getLanguageService();
// Create new
if ($this->canEditRedirects()) {
$newRecordButton = $this->componentFactory->createLinkButton()
->setHref((string)$this->uriBuilder->buildUriFromRoute(
'record_edit',
[
'edit' => ['sys_redirect' => ['new']],
'module' => 'redirects',
'defVals' => [
'sys_redirect' => [
'redirect_type' => Demand::DEFAULT_REDIRECT_TYPE,
],
],
'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute('redirects'),
]
))
->setTitle($languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:redirect_add_text'))
->setShowLabelText(true)
->setIcon($this->iconFactory->getIcon('actions-plus', IconSize::SMALL));
$view->getDocHeaderComponent()->getButtonBar()->addButton($newRecordButton);
}
// Shortcut
$view->getDocHeaderComponent()->setShortcutContext(
'redirects',
$languageService->translate('short_description', 'redirects.modules.redirects')
);
}
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}
@@ -0,0 +1,155 @@
<?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\Redirects\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Attribute\AsController;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
use TYPO3\CMS\Backend\Template\Components\MultiRecordSelection\Action;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Configuration\Features;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\IconSize;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Redirects\Repository\Demand;
use TYPO3\CMS\Redirects\Repository\RedirectRepository;
use TYPO3\CMS\Redirects\Service\ModulePaginationService;
use TYPO3\CMS\Redirects\Utility\RedirectConflict;
/**
* Lists all QR Codes in the TYPO3 Backend as a module.
*
* @internal This class is a specific TYPO3 Backend controller implementation and is not part of the Public TYPO3 API.
*/
#[AsController]
class QrCodeModuleController
{
public function __construct(
protected UriBuilder $uriBuilder,
protected IconFactory $iconFactory,
protected RedirectRepository $redirectRepository,
protected ModuleTemplateFactory $moduleTemplateFactory,
protected ComponentFactory $componentFactory,
protected ModulePaginationService $modulePaginationService,
) {}
/**
* Injects the request object for the current request, and renders the overview of all QR Codes
*/
public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
$view = $this->moduleTemplateFactory->create($request);
$demand = Demand::fromRequest($request);
$redirectType = $demand->getRedirectType();
$view->setTitle(
$this->getLanguageService()->translate('title', 'redirects.modules.qrcodes')
);
$view->makeDocHeaderModuleMenu();
$this->registerDocHeaderButtons($view);
$requestUri = $request->getAttribute('normalizedParams')->getRequestUri();
$languageService = $this->getLanguageService();
$pagination = $this->modulePaginationService->preparePagination($demand);
$view->assignMultiple([
'redirects' => $this->redirectRepository->findRedirectsByDemand($demand),
'hosts' => $this->redirectRepository->findHostsOfRedirects($redirectType),
'defaultIntegrityStatus' => RedirectConflict::NO_CONFLICT,
'demand' => $demand,
'showHitCounter' => GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount'),
'pagination' => $pagination,
'returnUrl' => $this->uriBuilder->buildUriFromRoute('qrcodes', [
'page' => $pagination['current'],
'demand' => $demand->getParameters(),
'orderField' => $demand->getOrderField(),
'orderDirection' => $demand->getOrderDirection(),
]),
'actions' => [
new Action(
'edit',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'returnUrl' => $requestUri,
],
'actions-open',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.edit'
),
new Action(
'delete',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'title' => $languageService->translate('delete.title', 'redirects.modules.qrcodes'),
'content' => $languageService->translate('delete.message', 'redirects.modules.qrcodes'),
'ok' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'),
'cancel' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel'),
'returnUrl' => $requestUri,
],
'actions-edit-delete',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'
),
],
]);
return $view->renderResponse('QrCode/Overview');
}
/**
* Create document header buttons for QR codes
*/
protected function registerDocHeaderButtons(ModuleTemplate $view): void
{
$languageService = $this->getLanguageService();
// Create new
$newRecordButton = $this->componentFactory->createLinkButton()
->setHref((string)$this->uriBuilder->buildUriFromRoute(
'record_edit',
[
'edit' => ['sys_redirect' => ['new']],
'module' => 'qrcodes',
'defVals' => [
'sys_redirect' => [
'redirect_type' => Demand::QRCODE_REDIRECT_TYPE,
],
],
'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute('qrcodes'),
]
))
->setTitle($languageService->translate('add_text', 'redirects.modules.qrcodes'))
->setShowLabelText(true)
->setIcon($this->iconFactory->getIcon('actions-plus', IconSize::SMALL));
$view->addButtonToButtonBar($newRecordButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
$view->getDocHeaderComponent()->setShortcutContext(
'qrcodes',
$languageService->translate('short_description', 'redirects.modules.qrcodes')
);
}
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,123 @@
<?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\Redirects\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Attribute\AsController;
use TYPO3\CMS\Backend\History\RecordHistory;
use TYPO3\CMS\Backend\History\RecordHistoryRollback;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\DataHandling\Model\CorrelationId;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Redirects\Service\TemporaryPermissionMutationService;
/**
* @internal
*/
#[AsController]
readonly class RecordHistoryRollbackController
{
public function __construct(
private LanguageServiceFactory $languageServiceFactory,
private RecordHistoryRollback $recordHistoryRollback,
private TemporaryPermissionMutationService $temporaryPermissionMutationService
) {}
public function revertCorrelation(ServerRequestInterface $request): ResponseInterface
{
$languageService = $this->languageServiceFactory->createFromUserPreferences($this->getBackendUser());
$revertedCorrelationTypes = [];
$correlationIds = $request->getParsedBody()['correlation_ids'] ?? [];
/** @var CorrelationId[] $correlationIds */
$correlationIds = array_map(
static function (string $correlationId) {
return CorrelationId::fromString($correlationId);
},
$correlationIds
);
foreach ($correlationIds as $correlationId) {
$type = $correlationId->getAspects()[1] ?? null;
if ($type !== null) {
$revertedCorrelationTypes[] = $type;
}
$this->rollBackCorrelation($correlationId);
}
$result = [
'status' => 'error',
'title' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:redirects_error_title'),
'message' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:redirects_error_message'),
];
if (in_array('redirect', $revertedCorrelationTypes, true)) {
$result = [
'status' => 'ok',
'title' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:revert_redirects_success_title'),
'message' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:revert_redirects_success_message'),
];
if (in_array('slug', $revertedCorrelationTypes, true)) {
$result = [
'status' => 'ok',
'title' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:revert_update_success_title'),
'message' => $languageService->sL('LLL:EXT:redirects/Resources/Private/Language/locallang_slug_service.xlf:revert_update_success_message'),
];
}
}
return new JsonResponse($result);
}
protected function rollBackCorrelation(CorrelationId $correlationId): void
{
$currentUserId = $this->getBackendUser()->getUserId();
$historyEntries = GeneralUtility::makeInstance(RecordHistory::class)->findEventsForCorrelation((string)$correlationId);
// Verify the correlation belongs to the current user before allowing rollback.
// All entries sharing a correlation_id are written by the same user, so checking
// any one entry is sufficient; we use the first (most recent) for the guard.
$firstEntry = reset($historyEntries);
if ($firstEntry === false || (int)$firstEntry['userid'] !== $currentUserId) {
return;
}
// Temporary add permissions to the user to perform the action.
// Store if we need to revert those changes after the actions.
$addedTableSelect = $this->temporaryPermissionMutationService->addTableSelect();
$addedTableModify = $this->temporaryPermissionMutationService->addTableModify();
foreach ($historyEntries as $recordHistoryEntry) {
$element = $recordHistoryEntry['tablename'] . ':' . $recordHistoryEntry['recuid'];
$tempRecordHistory = GeneralUtility::makeInstance(RecordHistory::class, $element);
$tempRecordHistory->setLastHistoryEntryNumber((int)$recordHistoryEntry['uid']);
$this->recordHistoryRollback->performRollback('ALL', $tempRecordHistory->getDiff($tempRecordHistory->getChangeLog()));
}
// Revert temporary permissions
if ($addedTableSelect) {
$this->temporaryPermissionMutationService->removeTableSelect();
}
if ($addedTableModify) {
$this->temporaryPermissionMutationService->removeTableModify();
}
}
private function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}
@@ -0,0 +1,94 @@
<?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\Redirects\Controller;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Redirects\Service\ShortUrlService;
/**
* @internal Only to be used within TYPO3. Might change in the future.
*/
#[Autoconfigure(public: true)]
readonly class ShortUrlGeneratorController
{
public function __construct(
protected ShortUrlService $shortUrlService,
protected ResponseFactoryInterface $responseFactory,
protected StreamFactoryInterface $streamFactory,
) {}
public function generate(ServerRequestInterface $request): ResponseInterface
{
$parsedBody = $request->getParsedBody();
$sourceHost = (string)($parsedBody['source_host'] ?? '');
$shortUrl = $this->shortUrlService->generateUniqueShortUrlPath($sourceHost);
if ($shortUrl === null) {
return $this->createResponse([
'success' => false,
'message' => 'Could not generate a unique short URL after multiple attempts.',
]);
}
return $this->createResponse([
'success' => true,
'shortUrl' => $shortUrl,
]);
}
public function validate(ServerRequestInterface $request): ResponseInterface
{
$parsedBody = $request->getParsedBody();
$sourceHost = (string)($parsedBody['source_host'] ?? '');
$sourcePath = (string)($parsedBody['source_path'] ?? '');
if ($sourcePath === '') {
return $this->createResponse(['isUnique' => true]);
}
// Ensure leading slash
if ($sourcePath[0] !== '/') {
$sourcePath = '/' . $sourcePath;
}
$isUnique = $this->shortUrlService->isUniqueShortUrl($sourceHost, $sourcePath);
$response = ['isUnique' => $isUnique];
if (!$isUnique) {
$response['message'] = $this->getLanguageService()
->sL('redirects.modules.short_urls:validation.duplicate_short_url');
}
return $this->createResponse($response);
}
private function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
private function createResponse(array $data): ResponseInterface
{
return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($this->streamFactory->createStream((string)json_encode($data)));
}
}
@@ -0,0 +1,156 @@
<?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\Redirects\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Attribute\AsController;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
use TYPO3\CMS\Backend\Template\Components\MultiRecordSelection\Action;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Configuration\Features;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\IconSize;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Redirects\Repository\Demand;
use TYPO3\CMS\Redirects\Repository\RedirectRepository;
use TYPO3\CMS\Redirects\Service\ModulePaginationService;
use TYPO3\CMS\Redirects\Utility\RedirectConflict;
/**
* Lists all Short URLs in the TYPO3 Backend as a module.
*
* @internal This class is a specific TYPO3 Backend controller implementation and is not part of the Public TYPO3 API.
*/
#[AsController]
readonly class ShortUrlModuleController
{
public function __construct(
protected UriBuilder $uriBuilder,
protected IconFactory $iconFactory,
protected RedirectRepository $redirectRepository,
protected ModuleTemplateFactory $moduleTemplateFactory,
protected ComponentFactory $componentFactory,
protected ModulePaginationService $modulePaginationService,
) {}
/**
* Injects the request object for the current request and renders the overview of all Short URLs.
*/
public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
$view = $this->moduleTemplateFactory->create($request);
$demand = Demand::fromRequest($request);
$redirectType = $demand->getRedirectType();
$view->setTitle(
$this->getLanguageService()->translate('title', 'redirects.modules.short_urls')
);
$view->makeDocHeaderModuleMenu();
$this->registerDocHeaderButtons($view);
$requestUri = $request->getAttribute('normalizedParams')->getRequestUri();
$languageService = $this->getLanguageService();
$pagination = $this->modulePaginationService->preparePagination($demand);
$view->assignMultiple([
'redirects' => $this->redirectRepository->findRedirectsByDemand($demand),
'hosts' => $this->redirectRepository->findHostsOfRedirects($redirectType),
'protocol' => $request->getUri()->getScheme(),
'defaultIntegrityStatus' => RedirectConflict::NO_CONFLICT,
'demand' => $demand,
'showHitCounter' => GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount'),
'pagination' => $pagination,
'returnUrl' => $this->uriBuilder->buildUriFromRoute('short_urls', [
'page' => $pagination['current'],
'demand' => $demand->getParameters(),
'orderField' => $demand->getOrderField(),
'orderDirection' => $demand->getOrderDirection(),
]),
'actions' => [
new Action(
'edit',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'returnUrl' => $requestUri,
],
'actions-open',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.edit'
),
new Action(
'delete',
[
'idField' => 'uid',
'tableName' => 'sys_redirect',
'title' => $languageService->translate('delete.title', 'redirects.modules.short_urls'),
'content' => $languageService->translate('delete.message', 'redirects.modules.short_urls'),
'ok' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'),
'cancel' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.cancel'),
'returnUrl' => $requestUri,
],
'actions-edit-delete',
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete'
),
],
]);
return $view->renderResponse('ShortUrl/Overview');
}
/**
* Create document header buttons for Short URLs
*/
protected function registerDocHeaderButtons(ModuleTemplate $view): void
{
$languageService = $this->getLanguageService();
// Create new
$newRecordButton = $this->componentFactory->createLinkButton()
->setHref((string)$this->uriBuilder->buildUriFromRoute(
'record_edit',
[
'edit' => ['sys_redirect' => ['new']],
'module' => 'short_urls',
'defVals' => [
'sys_redirect' => [
'redirect_type' => Demand::SHORT_URL_REDIRECT_TYPE,
],
],
'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute('short_urls'),
]
))
->setTitle($languageService->translate('add_text', 'redirects.modules.short_urls'))
->setShowLabelText(true)
->setIcon($this->iconFactory->getIcon('actions-plus', IconSize::SMALL));
$view->addButtonToButtonBar($newRecordButton, ButtonBar::BUTTON_POSITION_LEFT, 10);
$view->getDocHeaderComponent()->setShortcutContext(
'short_urls',
$languageService->translate('short_description', 'redirects.modules.short_urls')
);
}
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}