Project

General

Profile

Actions

Bug #100849

open

ContentContentObject::render has wrong condition

Added by David Bruchmann 12 months ago. Updated 4 months ago.

Status:
Needs Feedback
Priority:
Should have
Assignee:
-
Category:
Frontend
Target version:
-
Start date:
2023-05-10
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
10
PHP Version:
Tags:
TypoScript Extension Plugin ContentElement
Complexity:
Is Regression:
Sprint Focus:

Description

The method

TYPO3\CMS\Frontend\ContentObject::render()
has the condition
if (!($frontendController->recordRegister[$registerField] ?? false)) {
.
The code inside the condition therefore is executed if the register never has an entry yet with the key $registerField.
In some special cases though, this register is already existing, but without content, so the rendered output stays empty.
In my opinion the check is wrong here, rather should just be checked if the required variable $registerField exists with a value:
if ($registerField) {

So, what are the special cases where this existing condition fails?
Creating a simple plugin with own CType, and adding it as [typoscript]: CONTENT element with required render instructions.

plugin.tx_mysitepackage_hero = CONTENT
plugin.tx_mysitepackage_hero {
    table = tt_content
    select {
        where = AND {#CType}="tx_mysitepackage_hero" 
        orderBy = sorting desc
    }
    renderObj = COA
    renderObj {
        20 = TEXT
        20.stdWrap.field = header
        20.stdWrap.noTrimWrap =  |<h1>THIS IS MY RENDERED CONTENT HEADER: |</h1>|
    }
}

This element is not rendered but I'd expect it to.

Files

ContentContentObject.patch (832 Bytes) ContentContentObject.patch David Bruchmann, 2023-05-10 09:19
Actions #1

Updated by David Bruchmann 12 months ago

  • File ContentContentObject.patch added
Actions #2

Updated by David Bruchmann 12 months ago

  • File deleted (ContentContentObject.patch)
Actions #4

Updated by Markus Klein 11 months ago

  • Related to Task #93640: Fix PHP 8 compatibility issues part 2/x added
Actions #5

Updated by Markus Klein 11 months ago

  • Target version deleted (12 LTS)

This condition was last touched here: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68175/6/typo3/sysext/frontend/Classes/ContentObject/ContentContentObject.php#90

I think the conversion was done correctly. So the problem should have existed before v12, right?

Actions #6

Updated by David Bruchmann 11 months ago

Markus, indeed I didn't check all versions, where this fault haapens.
Also I never know why this condition was introduced and if there might be a more sophisticated condition required.

Actions #7

Updated by Christophe Duhamel 4 months ago

Hello,

I confirm that the bug exists since TYPO3 11.5.

I have tested 10.4 and 11.5. No issues with 10.4.

This patch is very useful for TYPO3 11.5. It would be nice if this could be added in the next 11.5 release! :)

Thanks!

Actions #8

Updated by Markus Klein 4 months ago · Edited

  • Status changed from New to Needs Feedback
  • TYPO3 Version changed from 12 to 11

I'm still not sure how this happened.

The code conversion was:

if (!$frontendController->recordRegister[$conf['table'] . ':' . $row['uid']]) {
// to
$registerField = $conf['table'] . ':' . ($row['uid'] ?? 0);
if (!($frontendController->recordRegister[$registerField] ?? false)) {

In some special cases though, this register is already existing, but without content, so the rendered output stays empty.

This would mean the ?? operator would return the register's value, which is "no content" (so either empty string or null?). Consequently the negation would still cause the same effect as in the original line in v10.

So I wonder if we actually seeing a side-effect of some other change?
Or am I overlooking something crucial?

Actions #9

Updated by David Bruchmann 4 months ago

  • TYPO3 Version changed from 11 to 10

Markus, indeed the whole logic is somehow flawed or broken.

But first: I tried it in v10, there it's neither working (possible that Christophe applied my patch there and forgot about it).

Furthermore if I add 2 elements on the same page, only the first get's rendered (currently in v10, and disabling the condition).
Text CEs between are all rendered.

Having 4 CEs on a page like this:
- Hero [rendered]
- Text [rendered]
- Hero [NOT rendered]
- Text [rendered]
the render method is only called 3 times, but the last element get's rendered.
The 2nd Hero-CE is not getting the right config-array even it's given correctly to the method as argument, therefore it stays empty.

There might be differences between versions too, primarily then if ContentObjectRenderer differs perhaps, as you verified already that this class didn't change much.

At least it's quite some work and it's not enough to apply my simple patch.

Actions #10

Updated by Christophe Duhamel 4 months ago

I can confirm, in my case it's working on 10.4 without the patch but not in 11.5.

Actions #11

Updated by David Bruchmann 4 months ago

Christophe,
thanks for the feedback, I assume your use case is slightly different then.
But perhaps you can try to add several of your individual elements on a page (same colPos)?

Actions #12

Updated by Markus Klein 4 months ago

  • Related to deleted (Task #93640: Fix PHP 8 compatibility issues part 2/x)
Actions #13

Updated by David Bruchmann 4 months ago · Edited

In the mentioned scenario (CEs: Hero, Text, Hero, Text) it turned out that the seemingly required TypoScript (of my own code) is the the reason that the 2nd Hero-CE is not displayed (currently TYPO3 v10).

I changed it like this, but this is of course only to show what's wrong and no general solution.


        if (isset($conf['select.']['begin.']['dataWrap'])
            && $conf['select.']['begin.']['dataWrap'] == '{cObj : parentRecordNumber} - 1'
        ) {
            $conf['select.']['begin.']['dataWrap'] = '{cObj : parentRecordNumber} - 2';
        }

Actions #14

Updated by David Bruchmann 4 months ago · Edited

Concerning several custom CEs, the problem is SOLVED and was the following:

The parentRecordNumber is based on a general query to tt_content with colPos 0 like in styles.content.get.
This lists all 4 elements, including the HERO CEs. This is shown by debugging the first call of the render method.
Then the following queries depend on the select statement for the Hero CEs, where the parentRecordNumber never applies.
While the general approach to add '{cObj : parentRecordNumber} - 1' is in general correct, the same query had to be used to retrieve the results records.

Therefore the `where` clause in my query should be omitted, then the counting works like expected.
I tried this with more elements too, so I'm sure that it's no accidental result.
For safety these lines can be added in `renderObj`, but it's not required:

    renderObj {
        if {
            equals = tx_mysitepackage_hero
            value.field = CType
        }
        ...
    }

Actions

Also available in: Atom PDF