Bug #91487

Extbase repository query using equals on a relation field is different whether one passes $entity or $entity->getUid() in multi-language context

Added by Stefan P 5 months ago. Updated 2 months ago.

Status:
New
Priority:
Should have
Category:
Extbase + l10n
Target version:
-
Start date:
2020-05-26
Due date:
% Done:

0%

TYPO3 Version:
9
PHP Version:
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

The following two queries behave differently if in L>0 context:

$query->matching(
  $query->equals('relation', $entity)
)->execute()
$query->matching(
  $query->equals('relation', $entity->getUid())
)->execute()

When dumping $entity it is always displayed with the L=0 uid (also in L>0 context) and the overlayed fields from L>0, which is correct.

In L=0 context both queries behave the same. The second one works correct also in L>0, the first one only in L=0 context.

In L>0 context the first query extracts and uses the _localizedUid from the object. This is the bug afaik.

Discovered in 9, probably present in 10 as well.

History

#1 Updated by Markus Klein 2 months ago

That's a tough one, because it depends on how relations are stored. Whether the uid of L=0 or the translation is used.

How does your relation look in detail? (TCA?)

#2 Updated by Stefan P 2 months ago

When passing the entity object directly (in queries or in fluid variables), the logic must be like this implicitly (pseduocode):

$entity->l10n_parent ?: $entity->uid

We always want the l10n_parent uid. If it is not set, then we either are L=0 anyways (then uid is correct) or teh record was directly created in L>0 (then we want its own uid, of course).

Or can the l10n_parent contain anything else than 0 or the L=0 uid?

That's exactly what ->getUid() does implicitly.

When do one ever wants the uid of the overlaying(!) object? Can this be used for anything?

#3 Updated by Stefan P 2 months ago

An example from Typo3DbQueryParser:

        if ($consistentHandlingEnabled
            && $value instanceof AbstractDomainObject
            && $value->_hasProperty('_localizedUid')
            && $value->_getProperty('_localizedUid') > 0
        ) {
            $plainValue = (int)$value->_getProperty('_localizedUid');
        }

This must be $plainValue = $value->getUid(); I believe. Because getUid() already has all this magic resolved (the Extbase var_dump always shows the correct value at least).

If consistent handling is NOT enabled then the code is actually doing ->getUid() eventually;

#4 Updated by Markus Klein 2 months ago

I am well aware of all this, don't worry.

Please answer my question: How does your relation look like? TCA?

It matters if relations are built upon uid of the default language record or if the uid of a translation is used.
Depending on the use case both solutions may be valid.
Question rather is: can extbase guess somehow, what the intended way is?

#5 Updated by Stefan P 2 months ago

I believe it was only for relations using with l10n_mode => exclude. Everything else is just "standard TCA" (foreign_table_where relations and in the Extbase Model just a relation field to this table, all tables have all the language related fields in DB and ctrl)

But I can't really remember which of our many project this was as this dates 3 month back already. I know from colleaques that they experienced the same in other projects (and just switched to using ->getUid() to fix this). It always happened after upgrading from 8 to 9.

Since this experience we just switched to always using ->getUid() (in extbase) or .uid (in fluid), because this always worked in all our cases and projects and we had no problems ever again in v9 (works for L=0, works for L>0 with l10n_parent, works for records created in L>0 without l10n_parent, works for l10n_mode => exclude or not).

Also available in: Atom PDF