Skip to content

Commit

Permalink
[BUGFIX] content-defender maxitems
Browse files Browse the repository at this point in the history
disable content_defender checks
in our xclassed datamaphook
for datahandler cmdMap operations

Fixes: #471
Fixes: #444
Fixes: #383
  • Loading branch information
achimfritz committed Nov 8, 2024
1 parent bfe3db7 commit f27fdaf
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 168 deletions.
54 changes: 17 additions & 37 deletions Classes/ContentDefender/ContainerColumnConfigurationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ class ContainerColumnConfigurationService implements SingletonInterface

protected $copyMapping = [];

protected $contentDefenderContainerDataHandlerHookIsLocked = false;

public function startCmdMap(): void
{
$this->contentDefenderContainerDataHandlerHookIsLocked = true;
}

public function endCmdMap(): void
{
$this->contentDefenderContainerDataHandlerHookIsLocked = false;
}

public function isContentDefenderContainerDataHandlerHookLooked(): bool
{
return $this->contentDefenderContainerDataHandlerHookIsLocked;
}

public function __construct(ContainerFactory $containerFactory, Registry $tcaRegistry)
{
$this->containerFactory = $containerFactory;
Expand All @@ -57,40 +74,6 @@ public function addCopyMapping(int $sourceContentId, int $containerId, int $targ
];
}

public function getCopyMappingBySourceContainerIdAndTargetColPos(int $containerId, int $targetColpos): ?array
{
if (isset($this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $targetColpos])) {
return $this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $targetColpos];
}
return null;
}

public function setContainerIsCopied($containerId): void
{
try {
$this->containerFactory->buildContainer($containerId);
$this->copyMapping[$containerId] = true;
} catch (Exception $e) {
// not a container, do not set mapping
}
}

public function getTargetColPosForNew(int $containerId, int $colPos): ?int
{
if (isset($this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $colPos])) {
return $this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $colPos]['targetColPos'];
}
return null;
}

public function getContainerIdForNew(int $containerId, int $colPos): ?int
{
if (isset($this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $colPos])) {
return $this->copyMapping[$containerId . ContainerGridColumn::CONTAINER_COL_POS_DELIMITER . $colPos]['containerId'];
}
return null;
}

public function override(array $columnConfiguration, int $containerId, int $colPos): array
{
try {
Expand Down Expand Up @@ -122,9 +105,6 @@ public function isMaxitemsReachedByContainenrId(int $containerId, int $colPos, ?

public function isMaxitemsReached(Container $container, int $colPos, ?int $childUid = null): bool
{
if (isset($this->copyMapping[$container->getUid()])) {
return false;
}
$columnConfiguration = $this->getColumnConfigurationForContainer($container, $colPos);
if (!isset($columnConfiguration['maxitems']) || (int)$columnConfiguration['maxitems'] === 0) {
return false;
Expand Down
13 changes: 10 additions & 3 deletions Classes/ContentDefender/Xclasses/CommandMapHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ public function __construct(

public function processCmdmap_beforeStart(DataHandler $dataHandler): void
{
if (isset($dataHandler->cmdmap['pages']))
{
$this->containerColumnConfigurationService->startCmdMap();
}
if (!empty($dataHandler->cmdmap['tt_content'])) {
$this->containerColumnConfigurationService->startCmdMap();
foreach ($dataHandler->cmdmap['tt_content'] as $id => $cmds) {
foreach ($cmds as $cmd => $data) {
if ($cmd === 'copy') {
$this->containerColumnConfigurationService->setContainerIsCopied($id);
}
if (
($cmd === 'copy' || $cmd === 'move') &&
(!empty($data['update'])) &&
Expand Down Expand Up @@ -87,6 +89,11 @@ public function processCmdmap_beforeStart(DataHandler $dataHandler): void
parent::processCmdmap_beforeStart($dataHandler);
}

public function processCmdmap_postProcess(string $command, string $table, $id, $value, DataHandler $dataHandler, $pasteUpdate, $pasteDatamap): void
{
$this->containerColumnConfigurationService->endCmdMap();
}

protected function isRecordAllowedByRestriction(array $columnConfiguration, array $record): bool
{
if (isset($record['tx_container_parent']) &&
Expand Down
95 changes: 9 additions & 86 deletions Classes/ContentDefender/Xclasses/DatamapHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,12 @@ class DatamapHook extends DatamapDataHandlerHook
*/
protected $containerColumnConfigurationService;

/**
* @var Database
*/
protected $database;

protected $mapping = [];

public function __construct(
?ContentRepository $contentRepository = null,
?ContainerColumnConfigurationService $containerColumnConfigurationService = null,
?Database $database = null
?ContainerColumnConfigurationService $containerColumnConfigurationService = null
) {
$this->containerColumnConfigurationService = $containerColumnConfigurationService ?? GeneralUtility::makeInstance(ContainerColumnConfigurationService::class);
$this->database = $database ?? GeneralUtility::makeInstance(Database::class);
parent::__construct($contentRepository);
}

Expand All @@ -50,57 +42,23 @@ public function __construct(
*/
public function processDatamap_beforeStart(DataHandler $dataHandler): void
{
if (is_array($dataHandler->datamap['tt_content'] ?? null)) {
if (is_array($dataHandler->datamap['tt_content'] ?? null) &&
!$this->containerColumnConfigurationService->isContentDefenderContainerDataHandlerHookLooked()
) {
foreach ($dataHandler->datamap['tt_content'] as $id => $values) {
if (
isset($values['tx_container_parent']) &&
$values['tx_container_parent'] > 0 &&
isset($values['colPos']) &&
$values['colPos'] > 0
) {
// no maxitems check for localized records
if (isset($values['l18n_parent'])) {
if ((int)$values['l18n_parent'] !== 0) {
continue;
}
} elseif (MathUtility::canBeInterpretedAsInteger($id)) {
$record = $this->database->fetchOneRecord((int)$id);
if (isset($record['l18n_parent']) && (int)$record['l18n_parent'] !== 0) {
continue;
}
}
$containerId = (int)$values['tx_container_parent'];
// copyToLanguage case
if ((int)($values['l18n_parent'] ?? 1) === 0 &&
(int)($values['l10n_source'] ?? 0) > 0 &&
(int)($values['sys_language_uid'] ?? 0) > 0
) {
// free mode language CE used, we have to consider free mode container
$containerRecord = $this->database->fetchContainerRecordLocalizedFreeMode($containerId, (int)$values['sys_language_uid']);
if ($containerRecord !== null) {
$containerId = (int)$containerRecord['uid'];
}
}
$useChildId = null;
$colPos = (int)$values['colPos'];
if (MathUtility::canBeInterpretedAsInteger($id)) {
$this->mapping[(int)$id] = [
'containerId' => (int)$values['tx_container_parent'],
'colPos' => (int)$values['colPos'],
];
$useChildId = $id;
} else {
// new elements (first created in origin container/colPos, so we check the real target)
$targetColPos = $this->containerColumnConfigurationService->getTargetColPosForNew($containerId, (int)$values['colPos']);
if ($targetColPos !== null) {
$colPos = $targetColPos;
}
$containerIdTarget = $this->containerColumnConfigurationService->getContainerIdForNew($containerId, (int)$values['colPos']);
if ($containerIdTarget !== null) {
$containerId = $containerIdTarget;
}
// edit
continue;
}
if ($this->containerColumnConfigurationService->isMaxitemsReachedByContainenrId($containerId, $colPos, $useChildId)) {
$containerId = (int)$values['tx_container_parent'];

if ($this->containerColumnConfigurationService->isMaxitemsReachedByContainenrId($containerId, (int)$values['colPos'])) {
unset($dataHandler->datamap['tt_content'][$id]);
$dataHandler->log(
'tt_content',
Expand All @@ -127,41 +85,6 @@ protected function isRecordAllowedByRestriction(array $columnConfiguration, arra
) {
return true;
}
if (isset($this->mapping[$record['uid']])) {
$columnConfiguration = $this->containerColumnConfigurationService->override(
$columnConfiguration,
$this->mapping[$record['uid']]['containerId'],
$this->mapping[$record['uid']]['colPos']
);
} elseif (isset($record['tx_container_parent']) && $record['tx_container_parent'] > 0) {
$copyMapping = $this->containerColumnConfigurationService->getCopyMappingBySourceContainerIdAndTargetColPos((int)$record['tx_container_parent'], (int)$record['colPos']);
if ($copyMapping !== null) {
$columnConfiguration = $this->containerColumnConfigurationService->override(
$columnConfiguration,
$copyMapping['containerId'],
$copyMapping['targetColPos']
);
} else {
$columnConfiguration = $this->containerColumnConfigurationService->override(
$columnConfiguration,
(int)$record['tx_container_parent'],
(int)$record['colPos']
);
}
}
return parent::isRecordAllowedByRestriction($columnConfiguration, $record);
}

protected function isRecordAllowedByItemsCount(array $columnConfiguration, array $record): bool
{
if (isset($record['tx_container_parent']) &&
$record['tx_container_parent'] > 0 &&
(GeneralUtility::makeInstance(DatahandlerProcess::class))->isContainerInProcess((int)$record['tx_container_parent'])) {
return true;
}
if (isset($this->mapping[$record['uid']])) {
return true;
}
return parent::isRecordAllowedByItemsCount($columnConfiguration, $record);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected function newElementAfterContainer(array $incomingFieldArray): array
return $incomingFieldArray;
}
if ((int)($incomingFieldArray['tx_container_parent'] ?? 0) > 0 &&
(GeneralUtility::makeInstance(DatahandlerProcess::class))->isContainerInProcess((int)$incomingFieldArray['tx_container_parent'])
(GeneralUtility::makeInstance(DatahandlerProcess::class))->isContainerInProcess((int)$incomingFieldArray['tx_container_parent'])
) {
return $incomingFieldArray;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"pages"
,"uid","title","pid"
,1,"page-1",0
"tt_content"
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols",0,"container"
,2,1,200,text,1,"child-in-200"
,3,1,201,text,1,"child-in-201"
,4,1,0,text,0,"child-in-200 (copy 1)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"pages"
,"uid","title","pid"
,1,"page-1",0
,2,"page-1 (copy 1)",0
"tt_content"
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols",0,"container"
,2,1,200,text,1,"child-in-200"
,3,1,201,text,1,"child-in-201"
,4,2,0,"b13-2cols",0,"container"
,5,2,200,text,4,"child-in-200"
,6,2,201,text,4,"child-in-201"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"pages"
,"uid","title","pid"
,1,"page-1",0
"tt_content"
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols",0,"container"
,2,1,200,text,1,"child-in-200"
,3,1,201,text,1,"child-in-201"
,4,1,0,"b13-2cols",0,"container (copy 1)"
,5,1,200,text,4,"child-in-200 (copy 1)"
,6,1,201,text,4,"child-in-201 (copy 1)"
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
"pages"
,"uid","pid","title"
,1,0,""
"tt_content"
,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","l18n_parent","l10n_source"
,1,1,"b13-2cols-with-header-container","",0,0,0,0,0,0
,3,1,"","",0,0,202,1,0,0
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols-with-header-container",0,"container"
,3,1,202,"header",1,"content-element"
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"pages"
,"uid","pid"
,1,0
,"uid","pid","title"
,1,0,"page-1"
"tt_content"
,"uid","pid","colPos","CType","tx_container_parent"
,1,1,0,"b13-2cols-with-header-container",
,3,1,202,,1
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols-with-header-container",0,"container"
,3,1,202,"header",1,"content-element"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"pages"
,"uid","title","pid"
,1,"page-1",0
"tt_content"
,"uid","pid","colPos","CType","tx_container_parent","header"
,1,1,0,"b13-2cols",0,"container"
,2,1,200,text,1,"child-in-200"
,3,1,201,text,1,"child-in-201"
Loading

0 comments on commit f27fdaf

Please sign in to comment.