TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
<?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\Backend\Controller\ContentElement;
|
||||
|
||||
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\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
|
||||
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
|
||||
use TYPO3\CMS\Backend\Template\ModuleTemplate;
|
||||
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Backend\View\ValueFormatter\FlexFormValueFormatter;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\DataHandling\History\RecordHistoryStore;
|
||||
use TYPO3\CMS\Core\DataHandling\TableColumnType;
|
||||
use TYPO3\CMS\Core\Domain\DateTimeFactory;
|
||||
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Imaging\IconSize;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Schema\Capability\TcaSchemaCapability;
|
||||
use TYPO3\CMS\Core\Schema\TcaSchemaFactory;
|
||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\DiffGranularity;
|
||||
use TYPO3\CMS\Core\Utility\DiffUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Controller for showing the history module of TYPO3s backend.
|
||||
*
|
||||
* @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
|
||||
*/
|
||||
#[AsController]
|
||||
class ElementHistoryController
|
||||
{
|
||||
protected RecordHistory $historyObject;
|
||||
|
||||
/**
|
||||
* Display inline differences or not
|
||||
*/
|
||||
protected bool $showDiff = true;
|
||||
protected array $recordCache = [];
|
||||
|
||||
protected ModuleTemplate $view;
|
||||
|
||||
protected string $returnUrl = '';
|
||||
|
||||
public function __construct(
|
||||
protected readonly IconFactory $iconFactory,
|
||||
protected readonly UriBuilder $uriBuilder,
|
||||
protected readonly ModuleTemplateFactory $moduleTemplateFactory,
|
||||
private readonly DiffUtility $diffUtility,
|
||||
private readonly FlexFormValueFormatter $flexFormValueFormatter,
|
||||
private readonly TcaSchemaFactory $tcaSchemaFactory,
|
||||
private readonly ComponentFactory $componentFactory,
|
||||
private readonly SiteFinder $siteFinder,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Injects the request object for the current request or sub request
|
||||
* As this controller goes only through the main() method, it is rather simple for now
|
||||
*/
|
||||
public function mainAction(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$this->view = $this->moduleTemplateFactory->create($request);
|
||||
$backendUser = $this->getBackendUser();
|
||||
$this->view->getDocHeaderComponent()->setPageBreadcrumb([]);
|
||||
|
||||
$parsedBody = $request->getParsedBody();
|
||||
$queryParams = $request->getQueryParams();
|
||||
|
||||
$this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '', $request);
|
||||
|
||||
$lastHistoryEntry = (int)($parsedBody['historyEntry'] ?? $queryParams['historyEntry'] ?? 0);
|
||||
$rollbackFields = $parsedBody['rollbackFields'] ?? $queryParams['rollbackFields'] ?? null;
|
||||
$element = $parsedBody['element'] ?? $queryParams['element'] ?? null;
|
||||
$moduleSettings = $this->processSettings($request);
|
||||
$this->view->assign('isUserInWorkspace', $backendUser->workspace > 0);
|
||||
|
||||
$this->showDiff = (bool)$moduleSettings['showDiff'];
|
||||
|
||||
// Start history object
|
||||
$this->historyObject = GeneralUtility::makeInstance(RecordHistory::class, $element);
|
||||
$this->historyObject->setShowSubElements((bool)$moduleSettings['showSubElements']);
|
||||
$this->historyObject->setLastHistoryEntryNumber($lastHistoryEntry);
|
||||
if ($moduleSettings['maxSteps']) {
|
||||
$this->historyObject->setMaxSteps((int)$moduleSettings['maxSteps']);
|
||||
}
|
||||
|
||||
// Do the actual logic now (rollback, show a diff for certain changes,
|
||||
// or show the full history of a page or a specific record)
|
||||
$changeLog = $this->historyObject->getChangeLog();
|
||||
if (!empty($changeLog)) {
|
||||
if ($rollbackFields !== null) {
|
||||
$diff = $this->historyObject->getDiff($changeLog);
|
||||
GeneralUtility::makeInstance(RecordHistoryRollback::class)->performRollback($rollbackFields, $diff);
|
||||
} elseif ($lastHistoryEntry) {
|
||||
$completeDiff = $this->historyObject->getDiff($changeLog);
|
||||
$this->displayMultipleDiff($completeDiff);
|
||||
$button = $this->componentFactory->createLinkButton()
|
||||
->setHref($this->buildUrl(['historyEntry' => '']))
|
||||
->setIcon($this->iconFactory->getIcon('actions-view-go-back', IconSize::SMALL))
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_show_rechis.xlf:fullView'))
|
||||
->setShowLabelText(true);
|
||||
$this->view->addButtonToButtonBar($button);
|
||||
}
|
||||
if ($this->historyObject->getElementString() !== '') {
|
||||
$this->displayHistory($changeLog);
|
||||
}
|
||||
}
|
||||
|
||||
$elementData = $this->historyObject->getElementInformation();
|
||||
$editLock = false;
|
||||
if (!empty($elementData)) {
|
||||
[$elementTable, $elementUid] = $elementData;
|
||||
$elementUid = (int)$elementUid;
|
||||
$this->setPagePath($elementTable, $elementUid);
|
||||
$editLock = $this->getEditLockFromElement($elementTable, $elementUid);
|
||||
// Get link to page history if the element history is shown
|
||||
if ($elementTable !== 'pages') {
|
||||
$parentPage = BackendUtility::getRecord($elementTable, $elementUid, '*', '', false);
|
||||
if ($parentPage['pid'] > 0 && BackendUtility::readPageAccess($parentPage['pid'], $backendUser->getPagePermsClause(Permission::PAGE_SHOW))) {
|
||||
$button = $this->componentFactory->createLinkButton()
|
||||
->setHref($this->buildUrl([
|
||||
'element' => 'pages:' . $parentPage['pid'],
|
||||
'historyEntry' => '',
|
||||
]))
|
||||
->setIcon($this->iconFactory->getIcon('apps-pagetree-page-default', IconSize::SMALL))
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_show_rechis.xlf:elementHistory_link'))
|
||||
->setShowLabelText(true);
|
||||
$this->view->addButtonToButtonBar($button, ButtonBar::BUTTON_POSITION_LEFT, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($element !== null) {
|
||||
$this->addLanguageSwitcher($request, $backendUser, $element);
|
||||
}
|
||||
|
||||
$this->view->assign('editLock', $editLock);
|
||||
$this->view->assign('moduleSettings', $moduleSettings);
|
||||
$this->view->assign('settingsFormUrl', $this->buildUrl());
|
||||
|
||||
// Setting up the buttons and markers for docheader
|
||||
$this->getButtons();
|
||||
|
||||
return $this->view->renderResponse('RecordHistory/Main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the correct path to the current record
|
||||
*/
|
||||
protected function setPagePath(string $table, int $uid): void
|
||||
{
|
||||
$record = BackendUtility::getRecord($table, $uid, '*', '', false);
|
||||
if ($table === 'pages') {
|
||||
$pageId = $uid;
|
||||
} else {
|
||||
$pageId = $record['pid'];
|
||||
}
|
||||
|
||||
$pageAccess = BackendUtility::readPageAccess($pageId, $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW));
|
||||
if (is_array($pageAccess)) {
|
||||
$this->view->getDocHeaderComponent()->setPageBreadcrumb($pageAccess);
|
||||
}
|
||||
|
||||
$schema = $this->tcaSchemaFactory->get($table);
|
||||
$this->view->assignMultiple([
|
||||
'recordTable' => $table,
|
||||
'recordTableReadable' => $schema->getTitle($this->getLanguageService()->sL(...)),
|
||||
'recordUid' => $uid,
|
||||
'recordTitle' => $this->generateTitle($table, (string)$uid),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getButtons(): void
|
||||
{
|
||||
if ($this->returnUrl) {
|
||||
$backButton = $this->componentFactory->createLinkButton()
|
||||
->setHref($this->returnUrl)
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
|
||||
->setShowLabelText(true)
|
||||
->setIcon($this->iconFactory->getIcon('actions-close', IconSize::SMALL));
|
||||
$this->view->addButtonToButtonBar($backButton);
|
||||
}
|
||||
}
|
||||
|
||||
protected function processSettings(ServerRequestInterface $request): array
|
||||
{
|
||||
// Get current selection from UC, merge data, write it back to UC
|
||||
$currentSelection = $this->getBackendUser()->getModuleData('history');
|
||||
if (!is_array($currentSelection)) {
|
||||
$currentSelection = ['maxSteps' => '', 'showDiff' => 1, 'showSubElements' => 1];
|
||||
}
|
||||
$currentSelectionOverride = $request->getParsedBody()['settings'] ?? null;
|
||||
if (is_array($currentSelectionOverride) && !empty($currentSelectionOverride)) {
|
||||
$currentSelection = array_merge($currentSelection, $currentSelectionOverride);
|
||||
$this->getBackendUser()->pushModuleData('history', $currentSelection);
|
||||
}
|
||||
return $currentSelection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a translation selection dropdown if the record is language aware.
|
||||
*/
|
||||
protected function addLanguageSwitcher(
|
||||
ServerRequestInterface $request,
|
||||
BackendUserAuthentication $backendUser,
|
||||
string $element,
|
||||
): void {
|
||||
$translations = $this->historyObject->getTranslations($element);
|
||||
if ($translations === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$languageDropDownButton = $this->componentFactory->createDropDownButton()
|
||||
->setLabel($this->getLanguageService()->sL('core.core:labels.language'))
|
||||
->setShowLabelText(true);
|
||||
|
||||
try {
|
||||
$site = $this->siteFinder->getSiteByPageId($translations['page']);
|
||||
} catch (SiteNotFoundException) {
|
||||
$site = $request->getAttribute('site');
|
||||
}
|
||||
|
||||
$availableLanguages = $site->getAvailableLanguages($backendUser, false, $translations['page']);
|
||||
|
||||
foreach ($translations['elements'] as $translation) {
|
||||
$siteLanguage = $availableLanguages[$translation['language']] ?? null;
|
||||
if (!$siteLanguage instanceof SiteLanguage) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$languageItem = $this->componentFactory->createDropDownRadio()
|
||||
->setActive($translation['element'] === $element)
|
||||
->setIcon($this->iconFactory->getIcon($siteLanguage->getFlagIdentifier()))
|
||||
->setHref((string)$this->uriBuilder->buildUriFromRoute('record_history', [
|
||||
'element' => $translation['element'],
|
||||
'returnUrl' => $this->returnUrl,
|
||||
]))
|
||||
->setLabel($siteLanguage->getTitle());
|
||||
$languageDropDownButton->addItem($languageItem);
|
||||
|
||||
if ($languageItem->isActive()) {
|
||||
$languageDropDownButton->setLabel($siteLanguage->getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->getDocHeaderComponent()->setLanguageSelector($languageDropDownButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a diff over multiple fields including rollback links
|
||||
*
|
||||
* @param array $diff Difference array
|
||||
*/
|
||||
protected function displayMultipleDiff(array $diff): void
|
||||
{
|
||||
$languageService = $this->getLanguageService();
|
||||
|
||||
// Get all array keys needed
|
||||
/** @var string[] $arrayKeys */
|
||||
$arrayKeys = array_merge(array_keys($diff['newData']), array_keys($diff['insertsDeletes']), array_keys($diff['oldData']));
|
||||
$arrayKeys = array_unique($arrayKeys);
|
||||
if (!empty($arrayKeys)) {
|
||||
$lines = [];
|
||||
foreach ($arrayKeys as $key) {
|
||||
$singleLine = [];
|
||||
$elParts = explode(':', $key);
|
||||
// Turn around diff because it should be a "rollback preview"
|
||||
if ((int)($diff['insertsDeletes'][$key] ?? 0) === 1) {
|
||||
// insert
|
||||
$singleLine['insertDelete'] = 'delete';
|
||||
} elseif ((int)($diff['insertsDeletes'][$key] ?? 0) === -1) {
|
||||
$singleLine['insertDelete'] = 'insert';
|
||||
}
|
||||
// Build up temporary diff array
|
||||
// turn around diff because it should be a "rollback preview"
|
||||
if ($diff['newData'][$key] ?? false) {
|
||||
$tmpArr = [
|
||||
'newRecord' => $diff['oldData'][$key],
|
||||
'oldRecord' => $diff['newData'][$key],
|
||||
];
|
||||
|
||||
// show changes
|
||||
if (!$this->showDiff) {
|
||||
// Display field names instead of full diff
|
||||
// Re-write field names with labels
|
||||
/** @var string[] $tmpFieldList */
|
||||
$tmpFieldList = array_keys($tmpArr['newRecord']);
|
||||
foreach ($tmpFieldList as $fieldKey => $value) {
|
||||
$itemLabel = '';
|
||||
if ($this->tcaSchemaFactory->has($elParts[0]) && ($schema = $this->tcaSchemaFactory->get($elParts[0]))->hasField($value)) {
|
||||
$itemLabel = $schema->getField($value)->getLabel();
|
||||
}
|
||||
$tmp = str_replace(':', '', $languageService->sL($itemLabel));
|
||||
if ($tmp) {
|
||||
$tmpFieldList[$fieldKey] = $tmp;
|
||||
} else {
|
||||
// remove fields if no label available
|
||||
unset($tmpFieldList[$fieldKey]);
|
||||
}
|
||||
}
|
||||
$singleLine['fieldNames'] = implode(',', $tmpFieldList);
|
||||
} else {
|
||||
// Display diff
|
||||
$singleLine['differences'] = $this->renderDiff($tmpArr, $elParts[0], (int)$elParts[1], true);
|
||||
}
|
||||
}
|
||||
$elParts = explode(':', $key);
|
||||
$singleLine['revertRecordUrl'] = $this->buildUrl(['rollbackFields' => $key]);
|
||||
$singleLine['title'] = $this->generateTitle($elParts[0], $elParts[1]);
|
||||
$singleLine['recordTable'] = $elParts[0];
|
||||
$singleLine['recordUid'] = $elParts[1];
|
||||
$lines[] = $singleLine;
|
||||
}
|
||||
$this->view->assign('revertAllUrl', $this->buildUrl(['rollbackFields' => 'ALL']));
|
||||
$this->view->assign('multipleDiff', $lines);
|
||||
}
|
||||
$this->view->assign('showDifferences', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the full change log
|
||||
*/
|
||||
protected function displayHistory(array $historyEntries): void
|
||||
{
|
||||
if ($historyEntries === []) {
|
||||
return;
|
||||
}
|
||||
$languageService = $this->getLanguageService();
|
||||
$lines = [];
|
||||
$beUserArray = BackendUtility::getUserNames('username,realName,usergroup,uid');
|
||||
|
||||
// Traverse changeLog array:
|
||||
foreach ($historyEntries as $entry) {
|
||||
// Build up single line
|
||||
$singleLine = [];
|
||||
|
||||
// Get user names
|
||||
$singleLine['backendUserUid'] = $entry['userid'];
|
||||
$singleLine['backendUserName'] = $beUserArray[$entry['userid']]['username'] ?? '';
|
||||
$singleLine['backendUserRealName'] = $beUserArray[$entry['userid']]['realName'] ?? '';
|
||||
// Executed by switch user
|
||||
if (!empty($entry['originaluserid'])) {
|
||||
$singleLine['originalBackendUserUid'] = $entry['originaluserid'];
|
||||
$singleLine['originalBackendUserName'] = $beUserArray[$entry['originaluserid']]['username'] ?? '';
|
||||
$singleLine['originalBackendRealName'] = $beUserArray[$entry['originaluserid']]['realName'] ?? '';
|
||||
}
|
||||
|
||||
// Is a change in a workspace?
|
||||
$singleLine['isChangedInWorkspace'] = (int)$entry['workspace'] > 0;
|
||||
|
||||
// Diff link
|
||||
$singleLine['diffUrl'] = $this->buildUrl(['historyEntry' => $entry['uid']]);
|
||||
// Add time
|
||||
$singleLine['day'] = BackendUtility::date($entry['tstamp']);
|
||||
$singleLine['timestamp'] = DateTimeFactory::createFromTimestamp($entry['tstamp']);
|
||||
|
||||
$singleLine['title'] = $this->generateTitle($entry['tablename'], (string)$entry['recuid']);
|
||||
$singleLine['recordTable'] = $entry['tablename'];
|
||||
$singleLine['recordUid'] = $entry['recuid'];
|
||||
|
||||
$singleLine['elementUrl'] = $this->buildUrl(['element' => $entry['tablename'] . ':' . $entry['recuid']]);
|
||||
$singleLine['actiontype'] = $entry['actiontype'];
|
||||
if ((int)$entry['actiontype'] === RecordHistoryStore::ACTION_MODIFY || (int)$entry['actiontype'] === RecordHistoryStore::ACTION_PUBLISH) {
|
||||
// show changes
|
||||
if (!$this->showDiff) {
|
||||
// Display field names instead of full diff
|
||||
// Re-write field names with labels
|
||||
/** @var string[] $tmpFieldList */
|
||||
$tmpFieldList = array_keys($entry['newRecord']);
|
||||
foreach ($tmpFieldList as $key => $value) {
|
||||
$itemLabel = '';
|
||||
if ($this->tcaSchemaFactory->has($entry['tablename']) && ($schema = $this->tcaSchemaFactory->get($entry['tablename']))->hasField($value)) {
|
||||
$itemLabel = $schema->getField($value)->getLabel();
|
||||
}
|
||||
$tmp = str_replace(':', '', $languageService->sL($itemLabel));
|
||||
if ($tmp) {
|
||||
$tmpFieldList[$key] = $tmp;
|
||||
} else {
|
||||
// remove fields if no label available
|
||||
unset($tmpFieldList[$key]);
|
||||
}
|
||||
}
|
||||
$singleLine['fieldNames'] = implode(',', $tmpFieldList);
|
||||
} else {
|
||||
// Display diff
|
||||
$singleLine['differences'] = $this->renderDiff($entry, $entry['tablename'], (int)$entry['recuid']);
|
||||
}
|
||||
}
|
||||
// put line together
|
||||
$lines[] = $singleLine;
|
||||
}
|
||||
$this->view->assign('history', $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders HTML table-rows with the comparison information of a sys_history entry record
|
||||
*
|
||||
* @param array $entry sys_history entry record.
|
||||
* @param string $table The table name
|
||||
* @param int $rollbackUid The UID of the record
|
||||
* @param bool $showRollbackLink Whether a rollback link should be shown for each changed field
|
||||
* @return array array of records
|
||||
*/
|
||||
protected function renderDiff(array $entry, string $table, int $rollbackUid, bool $showRollbackLink = false): array
|
||||
{
|
||||
if (!$this->tcaSchemaFactory->has($table)) {
|
||||
return [];
|
||||
}
|
||||
$lines = [];
|
||||
if (is_array($entry['newRecord'] ?? null)) {
|
||||
$fieldsToDisplay = array_keys($entry['newRecord']);
|
||||
$languageService = $this->getLanguageService();
|
||||
$schema = $this->tcaSchemaFactory->get($table);
|
||||
foreach ($fieldsToDisplay as $fN) {
|
||||
if (!$schema->hasField($fN)) {
|
||||
continue;
|
||||
}
|
||||
$fieldInformation = $schema->getField($fN);
|
||||
if (!$fieldInformation->isType(TableColumnType::PASSTHROUGH)) {
|
||||
if ($fieldInformation->isType(TableColumnType::FLEX)) {
|
||||
$colConfig = $fieldInformation->getConfiguration();
|
||||
$old = $this->flexFormValueFormatter->format($table, $fN, ($entry['oldRecord'][$fN] ?? ''), $rollbackUid, $colConfig);
|
||||
$new = $this->flexFormValueFormatter->format($table, $fN, ($entry['newRecord'][$fN] ?? ''), $rollbackUid, $colConfig);
|
||||
$diffResult = $this->diffUtility->diff(strip_tags($old), strip_tags($new), DiffGranularity::CHARACTER);
|
||||
} else {
|
||||
$old = (string)BackendUtility::getProcessedValue($table, $fN, ($entry['oldRecord'][$fN] ?? ''), 0, true, false, $rollbackUid);
|
||||
$new = (string)BackendUtility::getProcessedValue($table, $fN, ($entry['newRecord'][$fN] ?? ''), 0, true, false, $rollbackUid);
|
||||
$diffResult = $this->diffUtility->diff(strip_tags($old), strip_tags($new));
|
||||
}
|
||||
$rollbackUrl = '';
|
||||
if ($rollbackUid && $showRollbackLink) {
|
||||
$rollbackUrl = $this->buildUrl(['rollbackFields' => $table . ':' . $rollbackUid . ':' . $fN]);
|
||||
}
|
||||
$lines[] = [
|
||||
'title' => $languageService->sL($fieldInformation->getLabel()),
|
||||
'rollbackUrl' => $rollbackUrl,
|
||||
'result' => str_replace('\n', PHP_EOL, str_replace('\r\n', '\n', $diffResult)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the URL for a link to the current page
|
||||
*/
|
||||
protected function buildUrl(array $overrideParameters = []): string
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// Setting default values based on GET parameters:
|
||||
$elementString = $this->historyObject->getElementString();
|
||||
if ($elementString !== '') {
|
||||
$params['element'] = $elementString;
|
||||
}
|
||||
$params['historyEntry'] = $this->historyObject->getLastHistoryEntryNumber();
|
||||
|
||||
if (!empty($this->returnUrl)) {
|
||||
$params['returnUrl'] = $this->returnUrl;
|
||||
}
|
||||
|
||||
// Merging overriding values:
|
||||
$params = array_merge($params, $overrideParameters);
|
||||
|
||||
// Make the link:
|
||||
return (string)$this->uriBuilder->buildUriFromRoute('record_history', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the title and puts the record title behind
|
||||
*/
|
||||
protected function generateTitle(string $table, string $uid): string
|
||||
{
|
||||
if ($this->tcaSchemaFactory->get($table)->hasCapability(TcaSchemaCapability::Label)) {
|
||||
$record = $this->getRecord($table, (int)$uid) ?? [];
|
||||
return BackendUtility::getRecordTitle($table, $record);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a database record (cached).
|
||||
*/
|
||||
protected function getRecord(string $table, int $uid): ?array
|
||||
{
|
||||
if (!isset($this->recordCache[$table][$uid])) {
|
||||
$this->recordCache[$table][$uid] = BackendUtility::getRecord($table, $uid, '*', '', false);
|
||||
}
|
||||
return $this->recordCache[$table][$uid];
|
||||
}
|
||||
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the editlock value from page of a history element
|
||||
*/
|
||||
protected function getEditLockFromElement(string $tableName, int $elementUid): bool
|
||||
{
|
||||
// If the user is admin, then he may always edit the page.
|
||||
if ($this->getBackendUser()->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$schema = $this->tcaSchemaFactory->get($tableName);
|
||||
|
||||
// Early return if $elementUid is zero
|
||||
if ($elementUid === 0) {
|
||||
return !$schema->getCapability(TcaSchemaCapability::RestrictionRootLevel)->shallIgnoreRootLevelRestriction();
|
||||
}
|
||||
|
||||
$record = BackendUtility::getRecord($tableName, $elementUid, '*', '', false);
|
||||
// we need the parent page record for the editlock info if element isn't a page
|
||||
if ($tableName !== 'pages') {
|
||||
$pageId = $record['pid'];
|
||||
$record = BackendUtility::getRecord('pages', $pageId, '*', '', false);
|
||||
}
|
||||
|
||||
return $schema->hasCapability(TcaSchemaCapability::EditLock)
|
||||
&& ($record[$schema->getCapability(TcaSchemaCapability::EditLock)->getFieldName()] ?? false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user