IchHabRecht / content_defender

Define allowed or denied content element types in your backend layouts
GNU General Public License v2.0
85 stars 38 forks source link

Empty $result['databaseRow']['colPos'] array gets interpreted as 0 #92

Open kosimas opened 3 years ago

kosimas commented 3 years ago

https://github.com/IchHabRecht/content_defender/blob/8258b80ca442315511ad04df2dfb1a29c7d3e315/Classes/Form/FormDataProvider/TcaCTypeItems.php#L39

This line causes issues with new IRRE inline elements that have for example a non existing colPos of 999. If a inline child element is created, it will load all allowed CType values for colPos 0.

Before setting $colPos to 0, it should be checked if $result["processedTca"]["columns"]["colPos"]["config"]["default"] exists and if so, $colPos should get the value.

A solution could look like this(this is probably doable with less code)

if (gettype($result['databaseRow']['colPos']) == 'array')
    $hasColPos = array_key_exists(0, $result['databaseRow']['colPos']);
else if (gettype($result['databaseRow']['colPos']) == 'int')
    $hasColPos = true;
else
    $hasColPos = false;

if (!$hasColPos) {
    $processedTcaTypeColPos = $result["processedTca"]["columns"]["colPos"]["config"]["default"] ?? false;
}

if (gettype($processedTcaTypeColPos) == 'string')
    $colPos = (int)$processedTcaTypeColPos;
else if (gettype($processedTcaTypeColPos) == 'integer')
    $colPos = $processedTcaTypeColPos;
else
    $colPos = (int)($result['databaseRow']['colPos'][0] ?? ($result['databaseRow']['colPos'] ?? 0));

Edit: Steps to reproduce This problem can be reproduced by creating an TCA inline element like this:

$GLOBALS['TCA']['tt_content']['columns']['text_tab_text_elements'] = [
    'config' => [
        'appearance' => [
            'collapseAll' => '1',
            'enabledControls' => [
                'dragdrop' => '1',
            ],
            'levelLinksPosition' => 'top',
            'showAllLocalizationLink' => '1',
            'showPossibleLocalizationRecords' => '1',
            'showSynchronizationLink' => '1',
            'useSortable' => '1',
        ],
        'foreign_sortby' => 'sorting',
        'foreign_table' => 'tt_content',
        'overrideChildTca' => [
            'columns' => [
                'colPos' => [
                    'config' => [
                        'default' => '999',
                    ],
                ],
                'CType' => [
                    'config' => [
                        'default' => 'text',
                    ],
                ],
            ],
        ],
        'type' => 'inline',
        'foreign_field' => 'text_tab_text_elements_parent',
    ],
    'exclude' => '1',
    'label' => 'LLL:EXT:sitepackage/Resources/Private/Language/Backend.xlf:text_tab_text_elements.label',
];

Then create a content element that is using this element. After that try to add this content element to a page that has text elements disallowed on colPos 0. Now creating child text elements inside the inline element is not working properly.

Typo3: ^10.4, ^11.5 Content Defender: ^3.2

IchHabRecht commented 3 years ago

Hi @kosimas,

Would you mind to share your actual problem and how to reproduce it. I can't copy&paste any code to solve a problem I cannot reproduce. Thank you very much.

kosimas commented 3 years ago

Hey @IchHabRecht, thanks for the quick reply. I edited the issue. Let me know if you need more information.

IchHabRecht commented 2 years ago

Hi @kosimas,

I tried to reproduce the problem, but was unable to do so. For an IRRE child element the correct colPos configured in overrideChildTca -> columns -> colPos -> config -> default is taken into account. if this colPos isn't configured in the backendLayout configuration there shouldn't be any overlapping. Are you using any other extension that handles colPos configuration on it's own and maybe has strange site effects with content_defender?

kosimas commented 2 years ago

Hey @IchHabRecht, I created a sitepackage extension for reproducing this bug. https://github.com/kosimas/content_defender_bug_sitepackage

I have added some information and instructions to the readme file https://github.com/kosimas/content_defender_bug_sitepackage/blob/master/README.md

I hope this will help to understand the problem. Let me know if something is still unclear :relaxed:

kosimas commented 2 years ago

https://github.com/IchHabRecht/content_defender/pull/75 This can be considered as related.

liayn commented 2 years ago

This also happens if you have "unused content elements". E.g. when upgrading a website and using new backend layouts, with different colPos numbers. Trying to edit such a content element yields an empty colPos array in the databaseRow.

liayn commented 2 years ago

$isCurrentColPos = $colPos === (int)($result['databaseRow']['colPos'][0] ?? 0); is sufficient for us to fix it

liayn commented 2 years ago

see https://github.com/IchHabRecht/content_defender/pull/109