Skip to content

Commit

Permalink
[FEATURE] Disallow content elements in all containers
Browse files Browse the repository at this point in the history
A new method "Registry::addDisallowedCType" is added
that allows excluding content elements from all
containers per default (if Ext:content_defender is installed).

However, content elements excluded in such a way can still be explicitly allowed via "allowed" setting in column configuration.

Note: In order to take effect on the whole TYPO3 system, the method needs to be called in ext_localconf.php.

Resolves: #507
  • Loading branch information
saitho committed Jun 11, 2024
1 parent e187b1a commit 0a05690
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
35 changes: 35 additions & 0 deletions Classes/Tca/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@

class Registry implements SingletonInterface
{
/**
* This list is populated by "addDisallowedCType" and allows defining CTypes that are disallowed
* in all containers, when they are not explicitly allowed by configuration.
* Note that the disallow functionality requires Ext:content_defender.
*/
protected array $disallowedCTypes = [];

/**
* @param ContainerConfiguration $containerConfiguration
*/
Expand Down Expand Up @@ -103,6 +110,23 @@ public function configureContainer(ContainerConfiguration $containerConfiguratio
$GLOBALS['TCA']['tt_content']['containerConfiguration'][$containerConfiguration->getCType()] = $containerConfiguration->toArray();
}

/**
* Add a CType and exclude it from all containers per default.
* It may be explicitly enabled using the "allowed" configuration.
*
* NOTE: In order for this to correctly take effect, call this method
* in your extension's ext_localconf.php, not in TCA.
*
* @see getContentDefenderConfiguration
*/
public function addDisallowedCType(string $cType): void
{
if (in_array($cType, $this->disallowedCTypes)) {
return;
}
$this->disallowedCTypes[] = $cType;
}

public function getContentDefenderConfiguration(string $cType, int $colPos): array
{
$contentDefenderConfiguration = [];
Expand All @@ -113,9 +137,20 @@ public function getContentDefenderConfiguration(string $cType, int $colPos): arr
$contentDefenderConfiguration['allowed.'] = $column['allowed'] ?? [];
$contentDefenderConfiguration['disallowed.'] = $column['disallowed'] ?? [];
$contentDefenderConfiguration['maxitems'] = $column['maxitems'] ?? 0;
break 2;
}
}
}
// Add globally disallowed CTypes when they are not explicitly allowed and not already disallowed
$addDisallowedCTypes = array_diff(
$this->disallowedCTypes,
GeneralUtility::trimExplode(',', $contentDefenderConfiguration['allowed.']['CType'] ?? '', true)
);
if ($addDisallowedCTypes !== []) {
$allDisallowedCTypes = GeneralUtility::trimExplode(',', $contentDefenderConfiguration['disallowed.']['CType'] ?? '', true);
array_push($allDisallowedCTypes, ...$addDisallowedCTypes);
$contentDefenderConfiguration['disallowed.']['CType'] = implode(',', $allDisallowedCTypes);
}
return $contentDefenderConfiguration;
}

Expand Down
67 changes: 67 additions & 0 deletions Tests/Functional/Tca/RegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,71 @@ public function originalPageTsIsNotOverriden(): void
$expected = 'LLL:EXT:backend/Resources/Private/Language/locallang_db_new_content_el.xlf:special';
self::assertSame($expected, $specialHeader);
}

/**
* @test
* @dataProvider contentDefenderData
*/
public function getContentDefenderConfiguration(int $colPos, array $disallowedCTypes, array $expectedConfiguration)
{
$registry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Registry::class);
$registry->configureContainer(
(
new ContainerConfiguration(
'b13-container', // CType
'foo', // label
'bar', // description
[
[
['name' => 'foo', 'colPos' => 1],
['name' => 'foo2', 'colPos' => 2, 'allowed' => ['CType' => 'ce1'], 'disallowed' => ['CType' => 'ce2']],
['name' => 'foo3', 'colPos' => 3, 'maxitems' => 3],
['name' => 'foo4', 'colPos' => 4, 'allowed' => ['CType' => 'ce1']],
],
] // grid configuration
)
)->setGroup('special')
);
if ($disallowedCTypes !== []) {
foreach ($disallowedCTypes as $cType) {
$registry->addDisallowedCType($cType);
}
}
$configuration = $registry->getContentDefenderConfiguration('b13-container', $colPos);
self::assertEquals($expectedConfiguration, $configuration);
}

public static function contentDefenderData(): \Traversable
{
yield 'no column' => [
'colPos' => 999,
'disallowedCTypes' => [],
'expectedConfiguration' => [],
];
yield 'default configuration' => [
'colPos' => 1,
'disallowedCTypes' => [],
'expectedConfiguration' => ['allowed.' => [], 'disallowed.' => [], 'maxitems' => 0],
];
yield 'maxitems' => [
'colPos' => 3,
'disallowedCTypes' => [],
'expectedConfiguration' => ['allowed.' => [], 'disallowed.' => [], 'maxitems' => 3],
];
yield 'allowed and disallowed' => [
'colPos' => 2,
'disallowedCTypes' => [],
'expectedConfiguration' => ['allowed.' => ['CType' => 'ce1'], 'disallowed.' => ['CType' => 'ce2'], 'maxitems' => 0],
];
yield 'globally disallowed CType' => [
'colPos' => 4,
'disallowedCTypes' => ['ce3'],
'expectedConfiguration' => ['allowed.' => ['CType' => 'ce1'], 'disallowed.' => ['CType' => 'ce3'], 'maxitems' => 0],
];
yield 'globally disallowed CType explicity allowed' => [
'colPos' => 4,
'disallowedCTypes' => ['ce1'],
'expectedConfiguration' => ['allowed.' => ['CType' => 'ce1'], 'disallowed.' => [], 'maxitems' => 0],
];
}
}

0 comments on commit 0a05690

Please sign in to comment.