Commit 9e259706 authored by Johannes Goslar's avatar Johannes Goslar Committed by Oliver Hader
Browse files

[!!!][TASK] Remove support for transForeignTable in TCA

Remove support for transForeignTable and transOrigPointerTable in TCA.
More details in Breaking-78191-RemoveSupportForTransForeignTableInTCA.rst

Resolves: #78191
Releases: master
Change-Id: Ibd7e1a963fdbf84ca7f4b5926b4a8cd02ba24631
Reviewed-on: https://review.typo3.org/50819

Reviewed-by: default avatarValentin Funk <valentin.funk@computerfabrik.de>
Reviewed-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent 0df8e24a
......@@ -229,7 +229,7 @@ class ClickMenu
// Used to hide cut,copy icons for l10n-records
$l10nOverlay = false;
// Should only be performed for overlay-records within the same table
if (BackendUtility::isTableLocalizable($table) && !isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])) {
if (BackendUtility::isTableLocalizable($table) && $table !== 'pages_language_overlay') {
$l10nOverlay = (int)$this->rec[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0;
}
// If record found (or root), go ahead and fill the $menuItems array which will contain data for the elements to render.
......
......@@ -496,7 +496,7 @@ class Clipboard
{
$lines = [];
$tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
if ($table !== 'pages' && BackendUtility::isTableLocalizable($table) && !$tcaCtrl['transOrigPointerTable']) {
if ($table !== 'pages' && BackendUtility::isTableLocalizable($table) && $table !== 'pages_language_overlay') {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
->removeAll()
......
......@@ -204,7 +204,7 @@ class TranslationConfigurationProvider
*/
public function isTranslationInOwnTable($table)
{
return $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] && !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
return $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] && $table !== 'pages_language_overlay';
}
/**
......@@ -215,17 +215,7 @@ class TranslationConfigurationProvider
*/
public function foreignTranslationTable($table)
{
$translationTable = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'];
if (
!$translationTable ||
!$GLOBALS['TCA'][$translationTable] ||
!$GLOBALS['TCA'][$translationTable]['ctrl']['languageField'] ||
!$GLOBALS['TCA'][$translationTable]['ctrl']['transOrigPointerField'] ||
$GLOBALS['TCA'][$translationTable]['ctrl']['transOrigPointerTable'] !== $table
) {
$translationTable = '';
}
return $translationTable;
return $table === 'pages' ? 'pages_language_overlay' : '';
}
/**
......
......@@ -1541,7 +1541,8 @@ class EditDocumentController extends AbstractModule
// Table editable and activated for languages?
if ($this->getBackendUser()->check('tables_modify', $table)
&& $languageField
&& $transOrigPointerField && !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']
&& $transOrigPointerField
&& $table !== 'pages_language_overlay'
) {
if (is_null($pid)) {
$row = BackendUtility::getRecord($table, $uid, 'pid');
......
......@@ -318,9 +318,9 @@ class LocalizationRepository
{
$recordLocalization = false;
// Check if translations are stored in other table
if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
$table = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'];
// Pages still stores translations in the pages_language_overlay table, all other tables store in themself
if ($table === 'pages') {
$table = 'pages_language_overlay';
}
if (BackendUtility::isTableLocalizable($table)) {
......
......@@ -47,8 +47,8 @@ class DatabaseLanguageRows implements FormDataProviderInterface
) {
// Table pages has its overlays in pages_language_overlay, this is accounted here
$tableNameWithDefaultRecords = $result['tableName'];
if (!empty($result['processedTca']['ctrl']['transOrigPointerTable'])) {
$tableNameWithDefaultRecords = $result['processedTca']['ctrl']['transOrigPointerTable'];
if ($tableNameWithDefaultRecords === 'pages_language_overlay') {
$tableNameWithDefaultRecords = 'pages';
}
// Default language record of localized record
......
......@@ -379,16 +379,16 @@ class BackendUtility
{
$recordLocalization = false;
// Check if translations are stored in other table
if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
$table = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'];
// Pages still stores translations in the pages_language_overlay table, all other tables store in themself
if ($table === 'pages') {
$table = 'pages_language_overlay';
}
if (self::isTableLocalizable($table)) {
$tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($table);
->getQueryBuilderForTable($table);
$expressionBuilder = $queryBuilder->expr();
$constraint = $expressionBuilder->andX(
......@@ -620,18 +620,15 @@ class BackendUtility
/**
* Gets the original translation pointer table.
* For e.g. pages_language_overlay this would be pages.
* That is now the same table, apart from pages_language_overlay
* where pages is the original.
*
* @param string $table Name of the table
* @return string Pointer table (if any)
*/
public static function getOriginalTranslationTable($table)
{
if (!empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])) {
$table = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
}
return $table;
return $table === 'pages_language_overlay' ? 'pages' : $table;
}
/**
......@@ -4218,10 +4215,10 @@ class BackendUtility
public static function translationCount($table, $ref, $msg = '')
{
$count = null;
if (empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])
if ($table !== 'pages'
&& $GLOBALS['TCA'][$table]['ctrl']['languageField']
&& $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
&& !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']
&& $table !== 'pages_language_overlay'
) {
$queryBuilder = static::getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
......
......@@ -924,7 +924,6 @@ class BackendUtilityTest extends UnitTestCase
[
'foo' => [
'ctrl' => [
'transOrigPointerTable' => '',
'transOrigPointerField' => 'origUid'
],
'columns' => [
......@@ -944,38 +943,6 @@ class BackendUtilityTest extends UnitTestCase
'field3' => 'trans',
]
],
'other table: mergeIfNotBlank' => [
'foo',
[
'origUid' => 1,
'field2' => '',
'field3' => 'trans',
],
[
'foo' => [
'ctrl' => [
'transOrigPointerTable' => 'bar',
'transOrigPointerField' => 'origUid'
]
],
'bar' => [
'columns' => [
'field2' => ['l10n_mode' => 'mergeIfNotBlank'],
'field3' => ['l10n_mode' => 'mergeIfNotBlank']
]
]
],
[
'origUid' => 0,
'field2' => 'basic',
'field3' => '',
],
[
'origUid' => 1,
'field2' => 'basic',
'field3' => 'trans',
]
],
'same table: exclude' => [
'foo',
[
......@@ -986,7 +953,6 @@ class BackendUtilityTest extends UnitTestCase
[
'foo' => [
'ctrl' => [
'transOrigPointerTable' => '',
'transOrigPointerField' => 'origUid'
],
'columns' => [
......@@ -1006,38 +972,6 @@ class BackendUtilityTest extends UnitTestCase
'field3' => '',
]
],
'other table: exclude' => [
'foo',
[
'origUid' => 1,
'field2' => 'fdas',
'field3' => 'trans',
],
[
'foo' => [
'ctrl' => [
'transOrigPointerTable' => 'bar',
'transOrigPointerField' => 'origUid'
]
],
'bar' => [
'columns' => [
'field2' => ['l10n_mode' => 'exclude'],
'field3' => ['l10n_mode' => 'exclude']
]
]
],
[
'origUid' => 0,
'field2' => 'basic',
'field3' => '',
],
[
'origUid' => 1,
'field2' => 'basic',
'field3' => '',
]
],
];
}
......@@ -1056,11 +990,7 @@ class BackendUtilityTest extends UnitTestCase
*/
public function replaceL10nModeFieldsReplacesFields($table, array $row, array $tca, array $originalRow, $expected)
{
if (!empty($tca[$table]['ctrl']['transOrigPointerTable'])) {
$tableName = $tca[$table]['ctrl']['transOrigPointerTable'];
} else {
$tableName = $table;
}
$tableName = $table === 'pages_language_overlay' ? 'pages' : $table;
list($queryBuilderProphet, $connectionPoolProphet) = $this->mockDatabaseConnection($tableName);
......
......@@ -699,9 +699,9 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
public function checkFullLanguagesAccess($table, $record)
{
$recordLocalizationAccess = $this->checkLanguageAccess(0);
if ($recordLocalizationAccess && (BackendUtility::isTableLocalizable($table) || isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']))) {
if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
$l10nTable = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'];
if ($recordLocalizationAccess && (BackendUtility::isTableLocalizable($table) || $table === 'pages')) {
if ($table === 'pages') {
$l10nTable = 'pages_language_overlay';
$pointerField = $GLOBALS['TCA'][$l10nTable]['ctrl']['transOrigPointerField'];
$pointerValue = $record['uid'];
} else {
......@@ -779,7 +779,7 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
return false;
}
} elseif (
isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) && $checkFullLanguageAccess &&
$table === 'pages' && $checkFullLanguageAccess &&
!$this->checkFullLanguagesAccess($table, $idOrRow)
) {
return false;
......
......@@ -1424,7 +1424,7 @@ class DataHandler
BackendUtility::fixVersioningPid($table, $currentRecord);
// Get original language record if available:
if (is_array($currentRecord) && $GLOBALS['TCA'][$table]['ctrl']['transOrigDiffSourceField'] && $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $currentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0 && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] && (int)$currentRecord[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] > 0) {
$lookUpTable = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'] ?: $table;
$lookUpTable = $table === 'pages_language_overlay' ? 'pages' : $table;
$originalLanguageRecord = $this->recordInfo($lookUpTable, $currentRecord[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']], '*');
BackendUtility::workspaceOL($lookUpTable, $originalLanguageRecord);
$originalLanguage_diffStorage = unserialize($currentRecord[$GLOBALS['TCA'][$table]['ctrl']['transOrigDiffSourceField']]);
......@@ -4114,7 +4114,7 @@ class DataHandler
public function copyL10nOverlayRecords($table, $uid, $destPid, $first = false, $overrideValues = [], $excludeFields = '')
{
// There's no need to perform this for page-records or for tables that are not localizable
if (!BackendUtility::isTableLocalizable($table) || !empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) || !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])) {
if (!BackendUtility::isTableLocalizable($table) || $table === 'pages' || $table === 'pages_language_overlay') {
return;
}
$where = '';
......@@ -4465,7 +4465,7 @@ class DataHandler
public function moveL10nOverlayRecords($table, $uid, $destPid, $originalRecordDestinationPid)
{
// There's no need to perform this for page-records or not localizable tables
if (!BackendUtility::isTableLocalizable($table) || !empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) || !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])) {
if (!BackendUtility::isTableLocalizable($table) || $table === 'pages' || $table === 'pages_language_overlay') {
return;
}
$where = '';
......@@ -4500,7 +4500,6 @@ class DataHandler
/**
* Localizes a record to another system language
* In reality it only works if transOrigPointerTable is not set. For "pages" the implementation is hardcoded
*
* @param string $table Table name
* @param int $uid Record uid (to be localized)
......@@ -4516,7 +4515,7 @@ class DataHandler
}
$this->registerNestedElementCall($table, $uid, 'localize');
if ((!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] || $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) && $table !== 'pages') {
if ((!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] || $table === 'pages_language_overay') && $table !== 'pages') {
if ($this->enableLogging) {
$this->newlog('Localization failed; "languageField" and "transOrigPointerField" must be defined for the table!', 1);
}
......@@ -4574,7 +4573,7 @@ class DataHandler
}
if ($table === 'pages') {
$pass = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'] === 'pages_language_overlay' && !BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $uid, (' AND ' . $GLOBALS['TCA']['pages_language_overlay']['ctrl']['languageField'] . '=' . (int)$langRec['uid']));
$pass = !BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $uid, (' AND ' . $GLOBALS['TCA']['pages_language_overlay']['ctrl']['languageField'] . '=' . (int)$langRec['uid']));
$Ttable = 'pages_language_overlay';
} else {
$pass = !BackendUtility::getRecordLocalization($table, $uid, $langRec['uid'], ('AND pid=' . (int)$row['pid']));
......@@ -5395,7 +5394,7 @@ class DataHandler
public function deleteL10nOverlayRecords($table, $uid)
{
// Check whether table can be localized or has a different table defined to store localizations:
if (!BackendUtility::isTableLocalizable($table) || !empty($GLOBALS['TCA'][$table]['ctrl']['transForeignTable']) || !empty($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])) {
if (!BackendUtility::isTableLocalizable($table) || $table === 'pages' || $table === 'pages_language_overlay') {
return;
}
$where = '';
......
......@@ -21,7 +21,6 @@ return [
'endtime' => 'endtime',
'fe_group' => 'fe_group'
],
'transForeignTable' => 'pages_language_overlay',
'typeicon_column' => 'doktype',
'typeicon_classes' => [
'1' => 'apps-pagetree-page-default',
......
.. include:: ../../Includes.txt
==============================================================
Breaking: #78191 - Remove support for transForeignTable in TCA
==============================================================
See :issue:`78191`
Description
===========
TCA allowed the definition of separate tables to hold localized and translated records.
The property names used for that were ``transForeignTable`` (basically pointed to
table ``pages_language_overlay``) and ``transOrigPointerTable`` (basically
pointed back to table ``pages``). The mentioned two pages tables are the only
tables that make use of this feature in the TYPO3 core.
To overcome special handling and to combine ``pages_language_overlay`` with
``pages`` at a later step, the configured table names are replaced with
hardcoded table names.
Impact
======
Modifications concerning the following two TCA control properties won't have
any effect anymore:
+ ``$TCA[<tableName>]['ctrl']['transForeignTable']``
+ ``$TCA[<tableName>]['ctrl']['transOrigPointerTable']``
Affected Installations
======================
All sites using localizations and translations for page hierarchies.
Migration
=========
No special actions are required if just the core defaults are used. Special
adjustments concerning the mentioned TCA properties should be verified and
hard-coded for the time being.
+ ``$TCA['pages']['ctrl']['transForeignTable']``, use value ``pages_language_overlay`` directly
+ ``$TCA['pages_language_overlay']['ctrl']['transOrigPointerTable']``, use value ``pages`` directly
.. index:: TCA
......@@ -532,7 +532,7 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
if (isset($tableName) && isset($GLOBALS['TCA'][$tableName])
&& isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField'])
&& isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])
&& !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])
&& $tableName !== 'pages_language_overlay'
) {
if (isset($row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']])
&& $row[$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0
......@@ -563,8 +563,8 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
if ($tableName == 'pages') {
$row = $pageRepository->getPageOverlay($row, $querySettings->getLanguageUid());
} elseif (isset($GLOBALS['TCA'][$tableName]['ctrl']['languageField'])
&& $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== ''
&& !isset($GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerTable'])
&& $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] !== ''
&& $tableName !== 'pages_language_overlay'
) {
if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], [-1, 0])) {
$overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : '';
......
......@@ -552,7 +552,7 @@ class PageRepository
if ($GLOBALS['TCA'][$table] && $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
// Return record for ALL languages untouched
// TODO: Fix call stack to prevent this situation in the first place
if (!$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'] && (int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] !== -1) {
if ($tableName !== 'pages_language_overlay' && (int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] !== -1) {
// Will not be able to work with other tables (Just didn't implement it yet;
// Requires a scan over all tables [ctrl] part for first FIND the table that
// carries localization information for this table (which could even be more
......@@ -1881,8 +1881,8 @@ class PageRepository
$localizedId = $element['_PAGES_OVERLAY_UID'];
}
if (!empty($GLOBALS['TCA'][$tableName]['ctrl']['transForeignTable'])) {
$tableName = $GLOBALS['TCA'][$tableName]['ctrl']['transForeignTable'];
if ($tableName === 'pages') {
$tableName = 'pages_language_overlay';
}
$isTableLocalizable = (
......
......@@ -17,7 +17,6 @@ return [
'endtime' => 'endtime'
],
'transOrigPointerField' => 'pid',
'transOrigPointerTable' => 'pages',
'transOrigDiffSourceField' => 'l18n_diffsource',
'shadowColumnsForNewPlaceholders' => 'title',
'languageField' => 'sys_language_uid',
......
......@@ -514,8 +514,8 @@ class DatabaseRecordList extends AbstractDatabaseRecordList
$titleCol = $GLOBALS['TCA'][$table]['ctrl']['label'];
$thumbsCol = $GLOBALS['TCA'][$table]['ctrl']['thumbnail'];
$l10nEnabled = $GLOBALS['TCA'][$table]['ctrl']['languageField']
&& $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
&& !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
&& $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
&& $tableName !== 'pages_language_overlay';
$tableCollapsed = (bool)$this->tablesCollapsed[$table];
// prepare space icon
$this->spaceIcon = '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>';
......@@ -1005,7 +1005,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList
$theData['uid'] = $row['uid'];
if (isset($GLOBALS['TCA'][$table]['ctrl']['languageField'])
&& isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])
&& !isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'])
&& $table !== 'pages_language_overlay'
) {
$theData['_l10nparent_'] = $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
}
......
......@@ -824,7 +824,7 @@ class DataHandlerHook
}
// l10n-fields must be kept otherwise the localization
// will be lost during the publishing
if (!isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
if ($table !== 'pages_language_overlay' && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
$keepFields[] = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
}
// Swap "keepfields"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment