first commit

This commit is contained in:
salam committed 2026-10-19 08:18:39 +02:00
commit 1218dd1517
12716 files changed
+989233

No files matched your search

@@ -0,0 +1,74 @@
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Frontend\Hooks;
/*
* 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!
*/
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* Uses frontend hooks to show preview information
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class FrontendHooks
{
/**
* Include the preview block in case we're looking at a hidden page
* in the LIVE workspace
*
* @param array $params
* @param TypoScriptFrontendController $controller
*/
public function displayPreviewInfoMessage($params, TypoScriptFrontendController $controller)
{
if (!$controller->fePreview || $controller->doWorkspacePreview() || ($controller->config['config']['disablePreviewNotification'] ?? false)) {
return;
}
if ($controller->config['config']['message_preview']) {
$message = $controller->config['config']['message_preview'];
} else {
$label = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tsfe.xlf:preview');
$styles = [];
$styles[] = 'position: fixed';
$styles[] = 'top: 15px';
$styles[] = 'right: 15px';
$styles[] = 'padding: 8px 18px';
$styles[] = 'background: #fff3cd';
$styles[] = 'border: 1px solid #ffeeba';
$styles[] = 'font-family: sans-serif';
$styles[] = 'font-size: 14px';
$styles[] = 'font-weight: bold';
$styles[] = 'color: #856404';
$styles[] = 'z-index: 20000';
$styles[] = 'user-select: none';
$styles[] = 'pointer-events: none';
$styles[] = 'text-align: center';
$styles[] = 'border-radius: 2px';
$message = '<div id="typo3-preview-info" style="' . implode(';', $styles) . '">' . htmlspecialchars($label) . '</div>';
}
if (!empty($message)) {
$controller->content = str_ireplace('</body>', $message . '</body>', $controller->content);
}
}
/**
* @return LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,52 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks;
/*
* 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!
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Adds extra fields into 'media' flexform
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class MediaItemHooks implements \TYPO3\CMS\Core\SingletonInterface
{
/**
* Load extra render types if they exist
*
* @param array $params Existing types by reference
* @param array $conf Config array
*/
public function customMediaRenderTypes(&$params, $conf)
{
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/hooks/class.tx_cms_mediaitems.php']['customMediaRenderTypes'] ?? [] as $className) {
$hookObj = GeneralUtility::makeInstance($className);
$hookObj->customMediaRenderTypes($params, $conf);
}
}
/**
* Load extra predefined media params if they exist
*
* @param array $params Existing types by reference
* @param array $conf Config array
*/
public function customMediaParams(&$params, $conf)
{
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/hooks/class.tx_cms_mediaitems.php']['customMediaParams'] ?? [] as $className) {
$hookObj = GeneralUtility::makeInstance($className);
$hookObj->customMediaParams($params, $conf);
}
}
}
@@ -0,0 +1,64 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks\PageLayoutView;
/*
* 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!
*/
/**
* Contains a preview rendering for the page module of CType="image"
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class ImagePreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface
{
/**
* Preprocesses the preview rendering of the content element "image".
*
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionalities
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
*/
public function preProcess(
\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
) {
if ($row['CType'] === 'image') {
if ($row['image']) {
$itemContent .= $parentObject->linkEditContent($parentObject->getThumbCodeUnlinked($row, 'tt_content', 'image'), $row);
$fileReferences = \TYPO3\CMS\Backend\Utility\BackendUtility::resolveFileReferences('tt_content', 'image', $row);
if (!empty($fileReferences)) {
$linkedContent = '';
foreach ($fileReferences as $fileReference) {
$description = $fileReference->getDescription();
if ($description !== null && $description !== '') {
$linkedContent .= htmlspecialchars($description) . '<br />';
}
}
$itemContent .= $parentObject->linkEditContent($linkedContent, $row);
unset($linkedContent);
}
}
$drawItem = false;
}
}
}
@@ -0,0 +1,47 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks\PageLayoutView;
/*
* 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!
*/
/**
* Contains a preview rendering for the page module of CType="text"
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class TextPreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface
{
/**
* Preprocesses the preview rendering of the content element "text".
*
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionalities
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
*/
public function preProcess(
\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
) {
if ($row['CType'] === 'text') {
if ($row['bodytext']) {
$itemContent .= $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
}
$drawItem = false;
}
}
}
@@ -0,0 +1,72 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks\PageLayoutView;
/*
* 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!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\PageLayoutView;
use TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
/**
* Contains a preview rendering for the page module of CType="textmedia"
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class TextmediaPreviewRenderer implements PageLayoutViewDrawItemHookInterface
{
/**
* Preprocesses the preview rendering of a content element of type "textmedia"
*
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionality
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
*/
public function preProcess(
PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
) {
if ($row['CType'] === 'textmedia') {
if ($row['bodytext']) {
$itemContent .= $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
}
if ($row['assets']) {
$itemContent .= $parentObject->linkEditContent($parentObject->getThumbCodeUnlinked($row, 'tt_content', 'assets'), $row) . '<br />';
$fileReferences = BackendUtility::resolveFileReferences('tt_content', 'assets', $row);
if (!empty($fileReferences)) {
$linkedContent = '';
foreach ($fileReferences as $fileReference) {
$description = $fileReference->getDescription();
if ($description !== null && $description !== '') {
$linkedContent .= htmlspecialchars($description) . '<br />';
}
}
$itemContent .= $parentObject->linkEditContent($linkedContent, $row);
unset($linkedContent);
}
}
$drawItem = false;
}
}
}
@@ -0,0 +1,68 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks\PageLayoutView;
/*
* 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!
*/
/**
* Contains a preview rendering for the page module of CType="textpic"
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class TextpicPreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface
{
/**
* Preprocesses the preview rendering of the content element "textpic".
*
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionalities
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
*/
public function preProcess(
\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
) {
if ($row['CType'] === 'textpic') {
if ($row['bodytext']) {
$itemContent .= $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
}
if ($row['image']) {
$itemContent .= $parentObject->linkEditContent($parentObject->getThumbCodeUnlinked($row, 'tt_content', 'image'), $row);
$fileReferences = \TYPO3\CMS\Backend\Utility\BackendUtility::resolveFileReferences('tt_content', 'image', $row);
if (!empty($fileReferences)) {
$linkedContent = '';
foreach ($fileReferences as $fileReference) {
$description = $fileReference->getDescription();
if ($description !== null && $description !== '') {
$linkedContent .= htmlspecialchars($description) . '<br />';
}
}
$itemContent .= $parentObject->linkEditContent($linkedContent, $row);
unset($linkedContent);
}
}
$drawItem = false;
}
}
}
@@ -0,0 +1,46 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks;
/*
* 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!
*/
/**
* Hooks / manipulation data for TCA columns e.g. to sort items within itemsProcFunc
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class TableColumnHooks
{
/**
* sort list items (used for plugins, list_type) by name
* @param array $parameters
*/
public function sortPluginList(array &$parameters)
{
@usort(
$parameters['items'],
function ($item1, $item2) {
return strcasecmp($this->getLanguageService()->sL($item1[0]), $this->getLanguageService()->sL($item2[0]));
}
);
}
/**
* Returns LanguageService
*
* @return \TYPO3\CMS\Core\Localization\LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,377 @@
<?php
namespace TYPO3\CMS\Frontend\Hooks;
/*
* 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!
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class that hooks into DataHandler and listens for updates to pages to update the
* treelist cache
* @internal this is a concrete TYPO3 hook implementation and solely used for EXT:frontend and not part of TYPO3's Core API.
*/
class TreelistCacheUpdateHooks
{
/**
* Should not be manipulated from others except through the
* configuration provided @see __construct()
*
* @var array
*/
private $updateRequiringFields = [
'pid',
'php_tree_stop',
'extendToSubpages'
];
/**
* Constructor, adds update requiring fields to the default ones
*/
public function __construct()
{
// As enableFields can be set dynamically we add them here
$pagesEnableFields = $GLOBALS['TCA']['pages']['ctrl']['enablecolumns'];
foreach ($pagesEnableFields as $pagesEnableField) {
$this->updateRequiringFields[] = $pagesEnableField;
}
$this->updateRequiringFields[] = $GLOBALS['TCA']['pages']['ctrl']['delete'];
// Extension can add fields to the pages table that require an
// update of the treelist cache, too; so we also add those
// example: $TYPO3_CONF_VARS['BE']['additionalTreelistUpdateFields'] .= ',my_field';
if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['additionalTreelistUpdateFields'])) {
$additionalTreelistUpdateFields = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['BE']['additionalTreelistUpdateFields'], true);
$this->updateRequiringFields = array_merge($this->updateRequiringFields, $additionalTreelistUpdateFields);
}
}
/**
* waits for DataHandler commands and looks for changed pages, if found further
* changes take place to determine whether the cache needs to be updated
*
* @param string $status DataHandler operation status, either 'new' or 'update'
* @param string $table The DB table the operation was carried out on
* @param mixed $recordId The record's uid for update records, a string to look the record's uid up after it has been created
* @param array $updatedFields Array of changed fields and their new values
* @param DataHandler $dataHandler DataHandler parent object
*/
public function processDatamap_afterDatabaseOperations($status, $table, $recordId, array $updatedFields, DataHandler $dataHandler)
{
if ($table === 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPagePid = 0;
$affectedPageUid = 0;
if ($status === 'new') {
// Detect new pages
// Resolve the uid
$affectedPageUid = $dataHandler->substNEWwithIDs[$recordId];
$affectedPagePid = $updatedFields['pid'];
} elseif ($status === 'update') {
// Detect updated pages
$affectedPageUid = $recordId;
// When updating a page the pid is not directly available so we
// need to retrieve it ourselves.
$fullPageRecord = BackendUtility::getRecord($table, $recordId);
$affectedPagePid = $fullPageRecord['pid'];
}
$clearCacheActions = $this->determineClearCacheActions($status, $updatedFields);
$this->processClearCacheActions($affectedPageUid, $affectedPagePid, $updatedFields, $clearCacheActions);
}
}
/**
* Waits for DataHandler commands and looks for deleted pages or swapped pages, if found
* further changes take place to determine whether the cache needs to be updated
*
* @param string $command The TCE command
* @param string $table The record's table
* @param int $recordId The record's uid
* @param array $commandValue The commands value, typically an array with more detailed command information
* @param DataHandler $dataHandler The DataHandler parent object
*/
public function processCmdmap_postProcess($command, $table, $recordId, $commandValue, DataHandler $dataHandler)
{
$action = (is_array($commandValue) && isset($commandValue['action'])) ? (string)$commandValue['action'] : '';
if ($table === 'pages' && ($command === 'delete' || ($command === 'version' && $action === 'swap'))) {
$affectedRecord = BackendUtility::getRecord($table, $recordId, '*', '', false);
$affectedPageUid = $affectedRecord['uid'];
$affectedPagePid = $affectedRecord['pid'];
// Faking the updated fields
$updatedFields = [];
if ($command === 'delete') {
$updatedFields['deleted'] = 1;
} else {
// page was published to live (swapped)
$updatedFields['t3ver_wsid'] = 0;
}
$clearCacheActions = $this->determineClearCacheActions(
'update',
$updatedFields
);
$this->processClearCacheActions($affectedPageUid, $affectedPagePid, $updatedFields, $clearCacheActions);
}
}
/**
* waits for DataHandler commands and looks for moved pages, if found further
* changes take place to determine whether the cache needs to be updated
*
* @param string $table Table name of the moved record
* @param int $recordId The record's uid
* @param int $destinationPid The record's destination page id
* @param array $movedRecord The record that moved
* @param array $updatedFields Array of changed fields
* @param DataHandler $dataHandler DataHandler parent object
*/
public function moveRecord_firstElementPostProcess($table, $recordId, $destinationPid, array $movedRecord, array $updatedFields, DataHandler $dataHandler)
{
if ($table === 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPageUid = $recordId;
$affectedPageOldPid = $movedRecord['pid'];
$affectedPageNewPid = $updatedFields['pid'];
$clearCacheActions = $this->determineClearCacheActions('update', $updatedFields);
// Clear treelist entries for old parent page
$this->processClearCacheActions($affectedPageUid, $affectedPageOldPid, $updatedFields, $clearCacheActions);
// Clear treelist entries for new parent page
$this->processClearCacheActions($affectedPageUid, $affectedPageNewPid, $updatedFields, $clearCacheActions);
}
}
/**
* Waits for DataHandler commands and looks for moved pages, if found further
* changes take place to determine whether the cache needs to be updated
*
* @param string $table Table name of the moved record
* @param int $recordId The record's uid
* @param int $destinationPid The record's destination page id
* @param int $originalDestinationPid (negative) page id th page has been moved after
* @param array $movedRecord The record that moved
* @param array $updatedFields Array of changed fields
* @param DataHandler $dataHandler DataHandler parent object
*/
public function moveRecord_afterAnotherElementPostProcess($table, $recordId, $destinationPid, $originalDestinationPid, array $movedRecord, array $updatedFields, DataHandler $dataHandler)
{
if ($table === 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPageUid = $recordId;
$affectedPageOldPid = $movedRecord['pid'];
$affectedPageNewPid = $updatedFields['pid'];
$clearCacheActions = $this->determineClearCacheActions('update', $updatedFields);
// Clear treelist entries for old parent page
$this->processClearCacheActions($affectedPageUid, $affectedPageOldPid, $updatedFields, $clearCacheActions);
// Clear treelist entries for new parent page
$this->processClearCacheActions($affectedPageUid, $affectedPageNewPid, $updatedFields, $clearCacheActions);
}
}
/**
* Checks whether the change requires an update of the treelist cache
*
* @param array $updatedFields Array of changed fields
* @return bool TRUE if the treelist cache needs to be updated, FALSE if no update to the cache is required
*/
protected function requiresUpdate(array $updatedFields)
{
$requiresUpdate = false;
$updatedFieldNames = array_keys($updatedFields);
foreach ($updatedFieldNames as $updatedFieldName) {
if (in_array($updatedFieldName, $this->updateRequiringFields, true)) {
$requiresUpdate = true;
break;
}
}
return $requiresUpdate;
}
/**
* Calls the cache maintenance functions according to the determined actions
*
* @param int $affectedPage uid of the affected page
* @param int $affectedParentPage parent uid of the affected page
* @param array $updatedFields Array of updated fields and their new values
* @param array $actions Array of actions to carry out
*/
protected function processClearCacheActions($affectedPage, $affectedParentPage, $updatedFields, array $actions)
{
$actionNames = array_keys($actions);
foreach ($actionNames as $actionName) {
switch ($actionName) {
case 'allParents':
$this->clearCacheForAllParents($affectedParentPage);
break;
case 'setExpiration':
// Only used when setting an end time for a page
$expirationTime = $updatedFields['endtime'];
$this->setCacheExpiration($affectedPage, $expirationTime);
break;
case 'uidInTreelist':
$this->clearCacheWhereUidInTreelist($affectedPage);
break;
}
}
// From time to time clean the cache from expired entries
// (theoretically every 1000 calls)
$randomNumber = rand(1, 1000);
if ($randomNumber === 500) {
$this->removeExpiredCacheEntries();
}
}
/**
* Clears the treelist cache for all parents of a changed page.
* gets called after creating a new page and after moving a page
*
* @param int $affectedParentPage Parent page id of the changed page, the page to start clearing from
*/
protected function clearCacheForAllParents($affectedParentPage)
{
$rootLine = BackendUtility::BEgetRootLine($affectedParentPage);
$rootLineIds = [];
foreach ($rootLine as $page) {
if ($page['uid'] != 0) {
$rootLineIds[] = $page['uid'];
}
}
if (!empty($rootLineIds)) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('cache_treelist');
$queryBuilder
->delete('cache_treelist')
->where(
$queryBuilder->expr()->in(
'pid',
$queryBuilder->createNamedParameter($rootLineIds, Connection::PARAM_INT_ARRAY)
)
)
->execute();
}
}
/**
* Clears the treelist cache for all pages where the affected page is found
* in the treelist
*
* @param int $affectedPage ID of the changed page
*/
protected function clearCacheWhereUidInTreelist($affectedPage)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('cache_treelist');
$queryBuilder
->delete('cache_treelist')
->where(
$queryBuilder->expr()->inSet('treelist', $queryBuilder->quote($affectedPage))
)
->execute();
}
/**
* Sets an expiration time for all cache entries having the changed page in
* the treelist.
*
* @param int $affectedPage Uid of the changed page
* @param int $expirationTime
*/
protected function setCacheExpiration($affectedPage, $expirationTime)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('cache_treelist');
$queryBuilder
->update('cache_treelist')
->where(
$queryBuilder->expr()->inSet('treelist', $queryBuilder->quote($affectedPage))
)
->set('expires', $expirationTime)
->execute();
}
/**
* Removes all expired treelist cache entries
*/
protected function removeExpiredCacheEntries()
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('cache_treelist');
$queryBuilder
->delete('cache_treelist')
->where(
$queryBuilder->expr()->lte(
'expires',
$queryBuilder->createNamedParameter($GLOBALS['EXEC_TIME'], \PDO::PARAM_INT)
)
)
->execute();
}
/**
* Determines what happened to the page record, this is necessary to clear
* as less cache entries as needed later
*
* @param string $status DataHandler operation status, either 'new' or 'update'
* @param array $updatedFields Array of updated fields
* @return array List of actions that happened to the page record
*/
protected function determineClearCacheActions($status, $updatedFields): array
{
$actions = [];
if ($status === 'new') {
// New page
$actions['allParents'] = true;
} elseif ($status === 'update') {
$updatedFieldNames = array_keys($updatedFields);
foreach ($updatedFieldNames as $updatedFieldName) {
switch ($updatedFieldName) {
case 'pid':
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['disabled']:
case $GLOBALS['TCA']['pages']['ctrl']['delete']:
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['starttime']:
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['fe_group']:
case 'extendToSubpages':
case 't3ver_wsid':
case 'php_tree_stop':
// php_tree_stop
$actions['allParents'] = true;
$actions['uidInTreelist'] = true;
break;
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['endtime']:
// end time set/unset
// When setting an end time the cache entry needs an
// expiration time. When unsetting the end time the
// page must become listed in the treelist again.
if ($updatedFields['endtime'] > 0) {
$actions['setExpiration'] = true;
} else {
$actions['uidInTreelist'] = true;
}
break;
default:
if (in_array($updatedFieldName, $this->updateRequiringFields, true)) {
$actions['uidInTreelist'] = true;
}
}
}
}
return $actions;
}
}