Bug #103063
openExtbase repository does not respect fallback chain
0%
Description
Topic
In a site with multiple languages and fallback chains configured, extbase models retrieved by an extbase repository do not respect the configured fallback chains.
Example
SiteConfig (only relevant parts):
languages:
-
title: 'English (Global)'
enabled: true
languageId: 0
base: /en/
-
title: ES-ES
enabled: true
base: /es-es/
typo3Language: es
fallbackType: strict
flag: es
languageId: 15
-
title: 'AR-ES'
enabled: true
base: /es-ar/
typo3Language: es
fallbackType: fallback
fallbacks: 15
languageId: 5
Extbase Models in DB:
uid, sys_language_uid, title, l10n_parent 1, 0, 'Model 1 global', 0 2, 15, 'Model 1 spanish', 1 3, 0, 'Model 2 global', 0 4, 5, 'Model 2 spanish argentina', 3 5, 15, 'Model 2 spanish', 3
Using a extbase repository $repository->findAll() return the following results:
1, 0, 'Model 1 global', 0 4, 5, 'Model 2 spanish argentina', 3
instead of the expected result:
2, 15, 'Model 1 spanish', 1 4, 5, 'Model 2 spanish argentina', 3
I've tracked the problem down to
\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend->overlayLanguageAndWorkspaceForSingleRecord
in line 540 a new instance of LanguageAspect is created but without handing over the fallbackChain of the original languageAspect:
$customLanguageAspect = new LanguageAspect($languageUid, $languageUid, LanguageAspect::OVERLAYS_MIXED);
$row = $pageRepository->getLanguageOverlay($tableName, $row, $customLanguageAspect);
I am not sure, if this is done with purpose, but the pageRepository further more does not know about the configured fallbackChain and so cannot return the correct record. In my opinion the above code should look like this:
$customLanguageAspect = new LanguageAspect($languageUid, $languageUid, LanguageAspect::OVERLAYS_MIXED, $languageAspect->getFallbackChain());
$row = $pageRepository->getLanguageOverlay($tableName, $row, $customLanguageAspect);
Updated by Jens Bergau 10 months ago
Topic
In a site with multiple languages and fallback chains configured, extbase models retrieved by an extbase repository do not respect the configured fallback chains.
Example
SiteConfig (only relevant parts):
languages:
-
title: 'English (Global)'
enabled: true
languageId: 0
base: /en/
-
title: ES-ES
enabled: true
base: /es-es/
typo3Language: es
fallbackType: strict
flag: es
languageId: 15
-
title: 'AR-ES'
enabled: true
base: /es-ar/
typo3Language: es
fallbackType: fallback
fallbacks: 15
languageId: 5
Extbase Models in DB:
uid, sys_language_uid, title, l10n_parent 1, 0, 'Model 1 global', 0 2, 15, 'Model 1 spanish', 1 3, 0, 'Model 2 global', 0 4, 5, 'Model 2 spanish argentina', 3 5, 15, 'Model 2 spanish', 3
Using an extbase repository $repository->findAll() returns the following results in language=5:
1, 0, 'Model 1 global', 0 4, 5, 'Model 2 spanish argentina', 3
instead of the expected result:
2, 15, 'Model 1 spanish', 1 4, 5, 'Model 2 spanish argentina', 3
I've tracked the problem down to
\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend->overlayLanguageAndWorkspaceForSingleRecord
in line 540 a new instance of LanguageAspect is created but without handing over the fallbackChain of the original languageAspect:
$customLanguageAspect = new LanguageAspect($languageUid, $languageUid, LanguageAspect::OVERLAYS_MIXED);
$row = $pageRepository->getLanguageOverlay($tableName, $row, $customLanguageAspect);
I am not sure, if this is done with purpose, but the pageRepository further more does not know about the configured fallbackChain and so cannot return the correct record. In my opinion the above code should look like this:
$customLanguageAspect = new LanguageAspect($languageUid, $languageUid, LanguageAspect::OVERLAYS_MIXED, $languageAspect->getFallbackChain());
$row = $pageRepository->getLanguageOverlay($tableName, $row, $customLanguageAspect);
Updated by Pascal Geldmacher 4 months ago
I have the same problem.
I found out that the function in Backend.php is the problem.
/**
* Returns the object with the (internal) identifier, if it is known to the
* backend. Otherwise NULL is returned.
*
* @param string $identifier
* @param string $className
* @return object|null The object for the identifier if it is known, or NULL
*/
public function getObjectByIdentifier($identifier, $className)
{
if ($this->session->hasIdentifier($identifier, $className)) {
return $this->session->getObjectByIdentifier($identifier, $className);
}
$query = $this->persistenceManager->createQueryForType($className);
$query->getQuerySettings()->setRespectStoragePage(false);
$query->getQuerySettings()->setRespectSysLanguage(false);
// This allows to fetch IDs for languages for default language AND language IDs
// This is especially important when using the PropertyMapper of the Extbase MVC part to get
// an object of the translated version of the incoming ID of a record.
$languageAspect = $query->getQuerySettings()->getLanguageAspect();
$languageAspect = new LanguageAspect(
$languageAspect->getId(),
$languageAspect->getContentId(),
$languageAspect->getOverlayType() === LanguageAspect::OVERLAYS_OFF ? LanguageAspect::OVERLAYS_ON_WITH_FLOATING : $languageAspect->getOverlayType()
);
$query->getQuerySettings()->setLanguageAspect($languageAspect);
return $query->matching($query->equals('uid', $identifier))->execute()->getFirst();
}
The code get the languageAspect from the QuerySettings with the correct fallbackchain and then, I dont' know why but ok, created a new LanguageAspect object but without the fallbackchain, as fourth parameter.
I think that this would be the correct implementation, wouldn't it?
$languageAspect = $query->getQuerySettings()->getLanguageAspect();
$languageAspect = new LanguageAspect(
$languageAspect->getId(),
$languageAspect->getContentId(),
$languageAspect->getOverlayType() === LanguageAspect::OVERLAYS_OFF ? LanguageAspect::OVERLAYS_ON_WITH_FLOATING : $languageAspect->getOverlayType(),
$languageAspect->getFallbackChain()
);
Updated by Gerrit Code Review 7 days ago
- Status changed from New to Under Review
Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/87036
Updated by Gerrit Code Review 5 days ago
Patch set 2 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/87036