Commit 362b74f9 authored by Nikita Hovratov's avatar Nikita Hovratov Committed by Oliver Bartsch
Browse files

[BUGFIX] Add TCA migration for select authMode keywords

With the introduction of itemGroups, the index 3 of
the select items array has been shifted one position
to the right. Before that, the index 3 was used for
descriptions and index 4 for an optional keyword
EXPL_ALLOW or EXPL_DENY. These are used together
with authMode=individual to explicitly allow or deny
single items.

Since descriptions now occupy the index 4, the
former usage of this index needs to be shifted as
well to index 5.

For backwards compatibility reasons, a TCA migration
is added, which will check for these special
keywords and move them one index up.

Resolves: #96444
Related: #91008
Releases: main, 11.5, 10.4
Change-Id: I32a96f5c6377871551ab4ee60a402a585da7eaa0
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72820


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
parent 0b25b007
......@@ -652,8 +652,8 @@ class BackendUserAuthentication extends AbstractUserAuthentication
$items = $GLOBALS['TCA'][$table]['columns'][$field]['config']['items'];
if (is_array($items)) {
foreach ($items as $iCfg) {
if ((string)$iCfg[1] === (string)$value && $iCfg[4]) {
switch ((string)$iCfg[4]) {
if ((string)$iCfg[1] === (string)$value && ($iCfg[5] ?? '')) {
switch ((string)($iCfg[5] ?? '')) {
case 'EXPL_ALLOW':
if (!GeneralUtility::inList(
$this->groupData['explicit_allowdeny'],
......
......@@ -488,10 +488,10 @@ class TcaItemsProcessorFunctions
$allowDenyMode = 'DENY';
break;
case 'individual':
if ($item[4] ?? false) {
if ($item[4] === 'EXPL_ALLOW') {
if ($item[5] ?? false) {
if ($item[5] === 'EXPL_ALLOW') {
$allowDenyMode = 'ALLOW';
} elseif ($item[4] === 'EXPL_DENY') {
} elseif ($item[5] === 'EXPL_DENY') {
$allowDenyMode = 'DENY';
}
}
......
......@@ -63,6 +63,7 @@ class TcaMigration
$tca = $this->migrateFileFolderConfiguration($tca);
$tca = $this->migrateLevelLinksPosition($tca);
$tca = $this->migrateRootUidToStartingPoints($tca);
$tca = $this->migrateSelectAuthModeIndividualItemsKeywordToNewPosition($tca);
return $tca;
}
......@@ -514,4 +515,38 @@ class TcaMigration
return $tca;
}
/**
* If a column has authMode=individual and items with the corresponding key on position 5
* defined, migrate the key to position 6, since position 5 is used for the description.
*
* @param array $tca
* @return array
*/
protected function migrateSelectAuthModeIndividualItemsKeywordToNewPosition(array $tca): array
{
foreach ($tca as $table => $tableDefinition) {
if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
continue;
}
foreach ($tableDefinition['columns'] as $fieldName => $fieldConfig) {
if (($fieldConfig['config']['type'] ?? '') !== 'select' || ($fieldConfig['config']['authMode'] ?? '') !== 'individual') {
continue;
}
foreach ($fieldConfig['config']['items'] ?? [] as $index => $item) {
if (in_array($item[4] ?? '', ['EXPL_ALLOW', 'EXPL_DENY'], true)) {
$tca[$table]['columns'][$fieldName]['config']['items'][$index][5] = $item[4];
$tca[$table]['columns'][$fieldName]['config']['items'][$index][4] = '';
$this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' sets ' . $item[4]
. ' at position 5 of the items array. This option has been shifted to position 6 and should be adjusted accordingly.';
}
}
}
}
return $tca;
}
}
.. include:: ../../Includes.txt
=====================================================================
Deprecation: #96444 - authMode select items keywords moved to index 5
=====================================================================
See :issue:`96444`
Description
===========
With the introduction of itemGroups, the array index 3 of the select items array
has been shifted one position up. Before that, the index 3 was used for
descriptions and index 4 for an optional keyword `EXPL_ALLOW` or `EXPL_DENY`.
These are used together with :php:`'authMode' => 'individual'` to explicitly
allow or deny single items.
Since descriptions now occupy the array index 4, the former usage of this index
is now shifted as well one position up to index 5.
Impact
======
For backwards compatibility reasons, a TCA migration is in place, which will
check for these special keywords and move them one index up. This will log a
"TCA migration done" message in the admin tools upgrade module.
Affected Installations
======================
All installations, which use TCA type `select` with `authMode=individual`, while
defining the keywords `EXPL_ALLOW` or `EXPL_DENY` in the items array at index 4.
Migration
=========
Before:
.. code-block:: php
:emphasize-lines: 12
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
0 => 'Label 1',
1 => 'Value 1',
2 => null,
3 => null,
4 => 'EXPL_ALLOW',
],
],
],
],
],
After:
.. code-block:: php
:emphasize-lines: 12,13
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
0 => 'Label 1',
1 => 'Value 1',
2 => null,
3 => null,
4 => '', // This can be left empty
5 => 'EXPL_ALLOW',
],
],
],
],
],
.. index:: Backend, TCA, NotScanned, ext:backend
......@@ -546,6 +546,7 @@ class TcaItemsProcessorFunctionsTest extends UnitTestCase
'aItemValue',
null,
null,
'',
'EXPL_ALLOW',
],
// 1 is not selectable as allow and is always allowed
......@@ -558,6 +559,7 @@ class TcaItemsProcessorFunctionsTest extends UnitTestCase
'cItemValue',
null,
null,
'',
'EXPL_ALLOW',
],
],
......@@ -602,6 +604,7 @@ class TcaItemsProcessorFunctionsTest extends UnitTestCase
'aItemValue',
null,
null,
'',
'EXPL_DENY',
],
// 1 is not selectable as allow and is always allowed
......@@ -614,6 +617,7 @@ class TcaItemsProcessorFunctionsTest extends UnitTestCase
'cItemValue',
null,
null,
'',
'EXPL_DENY',
],
],
......
......@@ -1265,4 +1265,214 @@ class TcaMigrationTest extends UnitTestCase
$subject = new TcaMigration();
self::assertEquals($expected, $subject->migrate($input));
}
public function selectIndividualAllowDenyMigratedToNewPositionDataProvider(): iterable
{
yield 'authMode=individual with keyword EXPL_ALLOW in items array migrated to new position' => [
'tca' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'EXPL_ALLOW',
],
],
],
],
],
],
],
'expected' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'',
'EXPL_ALLOW',
],
],
],
],
],
],
],
];
yield 'authMode=individual with keyword EXPL_DENY in items array migrated to new position' => [
'tca' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'EXPL_DENY',
],
],
],
],
],
],
],
'expected' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'',
'EXPL_DENY',
],
],
],
],
],
],
],
];
yield 'authMode=individual without keyword in items array NOT migrated to new position' => [
'tca' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'EXPL_DENY',
],
[
'Label 2',
'Value 2',
null,
null,
'Description 2',
],
],
],
],
],
],
],
'expected' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'individual',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'',
'EXPL_DENY',
],
[
'Label 2',
'Value 2',
null,
null,
'Description 2',
],
],
],
],
],
],
],
];
yield 'items array NOT migrated to new position without authMode=individual set' => [
'tca' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'explicitAllow',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'Desription',
],
],
],
],
],
],
],
'expected' => [
'aTable' => [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'select',
'authMode' => 'explicitAllow',
'items' => [
[
'Label 1',
'Value 1',
null,
null,
'Desription',
],
],
],
],
],
],
],
];
}
/**
* @dataProvider selectIndividualAllowDenyMigratedToNewPositionDataProvider
* @test
*/
public function selectIndividualAllowDenyMigratedToNewPosition(array $input, array $expected): void
{
$subject = new TcaMigration();
self::assertEquals($expected, $subject->migrate($input));
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment