Bug #100849
closedContentContentObject::render has wrong condition
0%
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
Updated by David Bruchmann over 1 year ago
- File ContentContentObject.patch added
Updated by David Bruchmann over 1 year ago
- File deleted (
ContentContentObject.patch)
Updated by David Bruchmann over 1 year ago
Updated by Markus Klein over 1 year ago
- Related to Task #93640: Fix PHP 8 compatibility issues part 2/x added
Updated by Markus Klein over 1 year 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?
Updated by David Bruchmann over 1 year 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.
Updated by Christophe Duhamel 12 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!
Updated by Markus Klein 11 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?
Updated by David Bruchmann 11 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.
Updated by Christophe Duhamel 11 months ago
I can confirm, in my case it's working on 10.4 without the patch but not in 11.5.
Updated by David Bruchmann 11 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)?
Updated by Markus Klein 11 months ago
- Related to deleted (Task #93640: Fix PHP 8 compatibility issues part 2/x)
Updated by David Bruchmann 11 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'; }
Updated by David Bruchmann 11 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 } ... }
Updated by Georg Ringer 4 months ago
- Status changed from Needs Feedback to Closed
closing issue as it is solved for the author. if I read that wrong, please contact me via slack