Commit 355be2e7 authored by Benni Mack's avatar Benni Mack
Browse files

[!!!][TASK] Migrate pages_language_overlay into pages

The patch migrates all data from pages_language_overlay into pages,
and moves all API calls to overlay pages.

The following restrictions are set:
* Backend is always showing pages only for "sys_language_uid=0"
  for the page tree, element browser (e.g. "linking to default
  language page"), except where explicitly requested like the Page
  Module => Languages view.
* pid and sorting are always the same for all translations and
  their default language page
* Elements on a page are always keeping the field "pid" to the
  default language page (no change)
* Permission checks for Backend users are always made against
  the default language page (perms_* fields and webmounts)

Resolves: #82445
Releases: master
Change-Id: I62536e21d7110fa434c75fbd4470a3f53b79d260
Reviewed-on: https://review.typo3.org/51272

Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Frans Saris's avatarFrans Saris <franssaris@gmail.com>
Tested-by: Frans Saris's avatarFrans Saris <franssaris@gmail.com>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <typo3@scripting-base.de>
parent 6621faf1
......@@ -474,7 +474,7 @@ class Clipboard
{
$lines = [];
$tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
if ($table !== 'pages' && BackendUtility::isTableLocalizable($table) && $table !== 'pages_language_overlay') {
if (BackendUtility::isTableLocalizable($table)) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
->removeAll()
......
......@@ -110,37 +110,36 @@ class TranslationConfigurationProvider
if (!is_array($row)) {
return 'Record "' . $table . '_' . $uid . '" was not found';
}
$translationTable = $this->getTranslationTable($table);
if ($translationTable === '') {
if (!BackendUtility::isTableLocalizable($table)) {
return 'Translation is not supported for this table!';
}
if ($translationTable === $table && $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a language value "' . $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] . '", relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
}
if ($translationTable === $table && $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
if ($row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
}
// Look for translations of this record, index by language field value:
if (!$selFieldList) {
$selFieldList = 'uid,' . $GLOBALS['TCA'][$translationTable]['ctrl']['languageField'];
$selFieldList = 'uid,' . $GLOBALS['TCA'][$table]['ctrl']['languageField'];
}
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($translationTable);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$queryBuilder
->select(...GeneralUtility::trimExplode(',', $selFieldList))
->from($translationTable)
->from($table)
->where(
$queryBuilder->expr()->eq(
$GLOBALS['TCA'][$translationTable]['ctrl']['transOrigPointerField'],
$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter(
($table === 'pages' ? $row['uid'] : $row['pid']),
$row['pid'],
\PDO::PARAM_INT
)
)
......@@ -148,7 +147,7 @@ class TranslationConfigurationProvider
if (!$languageUid) {
$queryBuilder->andWhere(
$queryBuilder->expr()->gt(
$GLOBALS['TCA'][$translationTable]['ctrl']['languageField'],
$GLOBALS['TCA'][$table]['ctrl']['languageField'],
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
)
);
......@@ -156,7 +155,7 @@ class TranslationConfigurationProvider
$queryBuilder
->andWhere(
$queryBuilder->expr()->eq(
$GLOBALS['TCA'][$translationTable]['ctrl']['languageField'],
$GLOBALS['TCA'][$table]['ctrl']['languageField'],
$queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)
)
);
......@@ -168,10 +167,10 @@ class TranslationConfigurationProvider
$translations = [];
$translationsErrors = [];
foreach ($translationRecords as $translationRecord) {
if (!isset($translations[$translationRecord[$GLOBALS['TCA'][$translationTable]['ctrl']['languageField']]])) {
$translations[$translationRecord[$GLOBALS['TCA'][$translationTable]['ctrl']['languageField']]] = $translationRecord;
if (!isset($translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]])) {
$translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]] = $translationRecord;
} else {
$translationsErrors[$translationRecord[$GLOBALS['TCA'][$translationTable]['ctrl']['languageField']]][] = $translationRecord;
$translationsErrors[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]][] = $translationRecord;
}
}
return [
......@@ -179,7 +178,6 @@ class TranslationConfigurationProvider
'uid' => $uid,
'CType' => $row['CType'],
'sys_language_uid' => $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']],
'translation_table' => $translationTable,
'translations' => $translations,
'excessive_translations' => $translationsErrors
];
......@@ -190,10 +188,12 @@ class TranslationConfigurationProvider
*
* @param string $table The table name
* @return string
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
*/
public function getTranslationTable($table)
{
return $this->isTranslationInOwnTable($table) ? $table : $this->foreignTranslationTable($table);
trigger_error('getTranslationTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
return BackendUtility::isTableLocalizable($table) ? $table : '';
}
/**
......@@ -201,21 +201,27 @@ class TranslationConfigurationProvider
*
* @param string $table The table name
* @return bool
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
*/
public function isTranslationInOwnTable($table)
{
return $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] && $table !== 'pages_language_overlay';
trigger_error('isTranslationInOwnTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
return $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
}
/**
* Returns foreign translation table, if any
* Returns foreign translation table, if any.
* Since TYPO3 v9, even "pages" translations are stored in the same table, having this method return always
* empty, as with other tables as well.
*
* @param string $table The table name
* @return string Translation foreign table
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
*/
public function foreignTranslationTable($table)
{
return $table === 'pages' ? 'pages_language_overlay' : '';
trigger_error('foreignTranslationTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
return '';
}
/**
......
......@@ -1509,14 +1509,20 @@ class EditDocumentController
if ($this->getBackendUser()->check('tables_modify', $table)
&& $languageField
&& $transOrigPointerField
&& $table !== 'pages_language_overlay'
) {
if (is_null($pid)) {
$row = BackendUtility::getRecord($table, $uid, 'pid');
$pid = $row['pid'];
}
// Get all available languages for the page
$langRows = $this->getLanguages($pid);
// If editing a page, the translations of the current UID need to be fetched
if ($table === 'pages') {
$row = BackendUtility::getRecord($table, $uid, 'l10n_parent');
// Ensure the check is always done against the default language page
$langRows = $this->getLanguages($row['l10n_parent'] ?: $uid);
} else {
$langRows = $this->getLanguages($pid);
}
// Page available in other languages than default language?
if (is_array($langRows) && count($langRows) > 1) {
$rowsByLang = [];
......@@ -1631,7 +1637,6 @@ class EditDocumentController
public function localizationRedirect($justLocalized)
{
list($table, $origUid, $language) = explode(':', $justLocalized);
$table = $table === 'pages' ? 'pages_language_overlay' : $table;
if ($GLOBALS['TCA'][$table]
&& $GLOBALS['TCA'][$table]['ctrl']['languageField']
&& $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
......@@ -1674,7 +1679,7 @@ class EditDocumentController
*
* @param int $id Page id: If zero, the query will select all sys_language records from root level which are NOT
* hidden. If set to another value, the query will select all sys_language records that has a
* pages_language_overlay record on that page (and is not hidden, unless you are admin user)
* translation record on that page (and is not hidden, unless you are admin user)
* @return array Language records including faked record for default language
*/
public function getLanguages($id)
......@@ -1718,11 +1723,11 @@ class EditDocumentController
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(HiddenRestriction::class));
}
// Add join with pages_languages_overlay table to only show active languages
$queryBuilder->from('pages_language_overlay', 'o')
// Add join with pages translations to only show active languages
$queryBuilder->from('pages', 'o')
->where(
$queryBuilder->expr()->eq('o.sys_language_uid', $queryBuilder->quoteIdentifier('s.uid')),
$queryBuilder->expr()->eq('o.pid', $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT))
$queryBuilder->expr()->eq('o.l10n_parent', $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT))
);
}
......
......@@ -557,9 +557,6 @@ class NewRecordController
$iconFile[$_EXTKEY] = '';
}
} else {
if ($table === 'pages_language_overlay' && !$this->checkIfLanguagesExist()) {
continue;
}
$_EXTKEY = 'system';
$thisTitle = $lang->getLL('system_records');
$iconFile['system'] = $this->moduleTemplate->getIconFactory()->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render();
......@@ -656,8 +653,8 @@ class NewRecordController
if ($table === 'pages' && $addContentTable) {
$urlParameters['tt_content']['prev'] = 'new';
$urlParameters['returnNewPageId'] = 1;
} elseif ($table === 'pages_language_overlay') {
$urlParameters['overrideVals']['pages_language_overlay']['doktype'] = (int)$this->pageinfo['doktype'];
} elseif ($table === 'pages') {
$urlParameters['overrideVals']['pages']['doktype'] = (int)$this->pageinfo['doktype'];
}
$url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
return '<a href="' . htmlspecialchars($url) . '">' . $linkText . '</a>';
......
......@@ -306,7 +306,7 @@ class PageLayoutController
$this->modSharedTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.SHARED');
$this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->moduleName);
// First, select all pages_language_overlay records on the current page. Each represents a possibility for a language on the page. Add these to language selector.
// First, select all localized page records on the current page. Each represents a possibility for a language on the page. Add these to language selector.
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language');
$queryBuilder->getRestrictions()->removeAll();
if ($this->id) {
......@@ -314,38 +314,38 @@ class PageLayoutController
->from('sys_language')
->join(
'sys_language',
'pages_language_overlay',
'pages_language_overlay',
'pages',
'pages',
$queryBuilder->expr()->eq(
'sys_language.uid',
$queryBuilder->quoteIdentifier('pages_language_overlay.sys_language_uid')
$queryBuilder->quoteIdentifier('pages.sys_language_uid')
)
)
->where(
$queryBuilder->expr()->eq(
'pages_language_overlay.deleted',
'pages.deleted',
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'pages_language_overlay.pid',
'pages.l10n_parent',
$queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
),
$queryBuilder->expr()->orX(
$queryBuilder->expr()->gte(
'pages_language_overlay.t3ver_state',
'pages.t3ver_state',
$queryBuilder->createNamedParameter(
(string)new VersionState(VersionState::DEFAULT_STATE),
\PDO::PARAM_INT
)
),
$queryBuilder->expr()->eq(
'pages_language_overlay.t3ver_wsid',
'pages.t3ver_wsid',
$queryBuilder->createNamedParameter($this->getBackendUser()->workspace, \PDO::PARAM_INT)
)
)
)
->groupBy(
'pages_language_overlay.sys_language_uid',
'pages.sys_language_uid',
'sys_language.uid',
'sys_language.pid',
'sys_language.tstamp',
......@@ -634,16 +634,19 @@ class PageLayoutController
{
if ($this->current_sys_language > 0) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages_language_overlay');
->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$overlayRecord = $queryBuilder
$localizedPage = $queryBuilder
->select('*')
->from('pages_language_overlay')
->from('pages')
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq(
'l10n_parent',
$queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'sys_language_uid',
$queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT)
......@@ -652,8 +655,8 @@ class PageLayoutController
->setMaxResults(1)
->execute()
->fetch();
BackendUtility::workspaceOL('pages_language_overlay', $overlayRecord);
return $overlayRecord['title'];
BackendUtility::workspaceOL('pages', $localizedPage);
return $localizedPage['title'];
}
return $this->pageinfo['title'];
}
......@@ -998,20 +1001,20 @@ class PageLayoutController
if (!$this->modTSconfig['properties']['disableIconToolbar']) {
// Edit page properties and page language overlay icons
if ($this->pageIsNotLockedForEditors() && $this->getBackendUser()->checkLanguageAccess(0)) {
// Edit localized page_language_overlay only when one specific language is selected
// Edit localized pages only when one specific language is selected
if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages_language_overlay');
->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$overlayRecord = $queryBuilder
->select('uid')
->from('pages_language_overlay')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'pid',
'l10n_parent',
$queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
......@@ -1025,7 +1028,7 @@ class PageLayoutController
// Edit button
$urlParameters = [
'edit' => [
'pages_language_overlay' => [
'pages' => [
$overlayRecord['uid'] => 'edit'
]
],
......
......@@ -155,6 +155,9 @@ class FormDataCompiler
// Parent page record is either the full row of the parent page the record is located at or should
// be added to, or it is NULL, if a record is added or edited below the root page node.
'parentPageRow' => null,
// If a translated page is handled, the page row of the default language (the page against all page checks
// are made) is set here
'defaultLanguagePageRow' => null,
// Holds the "neighbor" row if incoming vanillaUid is negative and record creation is relative to a row of the same table.
'neighborRow' => null,
// For "new" this is the fully initialized row with defaults
......
......@@ -655,8 +655,7 @@ abstract class AbstractItemProvider
$table = $result['tableName'];
$backendUser = $this->getBackendUser();
// Guard clause returns if not correct table and field or if user is admin
if ($table !== 'pages' && $table !== 'pages_language_overlay'
|| $fieldName !== 'doktype' || $backendUser->isAdmin()
if ($table !== 'pages' || $fieldName !== 'doktype' || $backendUser->isAdmin()
) {
return $items;
}
......
<?php
declare(strict_types=1);
namespace TYPO3\CMS\Backend\Form\FormDataProvider;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
/**
* Fetch page in default language from database if it's a translated pages record
*/
class DatabaseDefaultLanguagePageRow extends AbstractDatabaseRecordProvider implements FormDataProviderInterface
{
/**
* Add default language page row of existing row to result
* defaultLanguagePageRow will stay NULL in result if a record is added or edited below root node
*
* @param array $result
* @return array
*/
public function addData(array $result)
{
// $defaultLanguagePageRow end up NULL if a record added or edited on root node
$tableName = $result['tableName'];
if ($tableName === 'pages' && $result['databaseRow'][$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] > 0) {
$result['defaultLanguagePageRow'] = $this->getRecordFromDatabase('pages', $result['databaseRow'][$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]);
}
return $result;
}
}
......@@ -45,15 +45,9 @@ class DatabaseLanguageRows implements FormDataProviderInterface
if (isset($result['databaseRow'][$languageField]) && $result['databaseRow'][$languageField] > 0
&& isset($result['databaseRow'][$fieldWithUidOfDefaultRecord]) && $result['databaseRow'][$fieldWithUidOfDefaultRecord] > 0
) {
// Table pages has its overlays in pages_language_overlay, this is accounted here
$tableNameWithDefaultRecords = $result['tableName'];
if ($tableNameWithDefaultRecords === 'pages_language_overlay') {
$tableNameWithDefaultRecords = 'pages';
}
// Default language record of localized record
$defaultLanguageRow = $this->getRecordWorkspaceOverlay(
$tableNameWithDefaultRecords,
$result['tableName'],
(int)$result['databaseRow'][$fieldWithUidOfDefaultRecord]
);
if (empty($defaultLanguageRow)) {
......@@ -90,7 +84,7 @@ class DatabaseLanguageRows implements FormDataProviderInterface
continue;
}
$translationInfo = $translationProvider->translationInfo(
$tableNameWithDefaultRecords,
$result['tableName'],
(int)$result['databaseRow'][$fieldWithUidOfDefaultRecord],
$additionalLanguageUid
);
......
......@@ -52,15 +52,15 @@ class DatabasePageLanguageOverlayRows implements FormDataProviderInterface
protected function getDatabaseRows(int $pid): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages_language_overlay');
->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$rows = $queryBuilder->select('*')
->from('pages_language_overlay')
->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)))
->from('pages')
->where($queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)))
->execute()
->fetchAll();
......
......@@ -114,7 +114,7 @@ class DatabaseUserPermissionCheck implements FormDataProviderInterface
// A page or a record on a page is edited
if ($result['tableName'] === 'pages') {
// A page record is edited, check edit rights of this record directly
$userPermissionOnPage = $backendUser->calcPerms($result['databaseRow']);
$userPermissionOnPage = $backendUser->calcPerms($result['defaultLanguagePageRow'] ?? $result['databaseRow']);
if ((bool)($userPermissionOnPage & Permission::PAGE_EDIT) && $backendUser->check('pagetypes_select', $result['databaseRow'][$result['processedTca']['ctrl']['type']])) {
$userHasAccess = true;
} else {
......
......@@ -135,9 +135,6 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid
$result['databaseRow'][$fieldName] = implode(',', $connectedUidsOfLocalizedOverlay);
if ($result['inlineCompileExistingChildren']) {
$tableNameWithDefaultRecords = $result['tableName'];
if ($tableNameWithDefaultRecords === 'pages_language_overlay') {
$tableNameWithDefaultRecords = 'pages';
}
$connectedUidsOfDefaultLanguageRecord = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$tableNameWithDefaultRecords,
......
......@@ -449,17 +449,17 @@ abstract class AbstractRecordList
{
// Look up page overlays:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages_language_overlay');
->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$result = $queryBuilder
->select('*')
->from('pages_language_overlay')
->from('pages')
->where(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)),
$queryBuilder->expr()->gt('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
)
)
......
......@@ -444,6 +444,11 @@ class DataProvider extends \TYPO3\CMS\Backend\Tree\AbstractTreeDataProvider
);
}
// Only show records in default language
$queryBuilder->andWhere(
$expressionBuilder->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
);
if ($searchFilter !== '') {
$searchParts = $expressionBuilder->orX();
if (is_numeric($searchFilter) && $searchFilter > 0) {
......
......@@ -70,7 +70,7 @@ class PageTreeView extends AbstractTreeView
*/
public function init($clause = '', $orderByFields = '')
{
parent::init(' AND deleted=0 ' . $clause, 'sorting');
parent::init(' AND deleted=0 AND sys_language_uid=0 ' . $clause, 'sorting');
}
/**
......
......@@ -302,11 +302,6 @@ class BackendUtility
{
$recordLocalization = false;
// 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'];
......@@ -546,16 +541,15 @@ class BackendUtility
}
/**
* Gets the original translation pointer table.
* That is now the same table, apart from pages_language_overlay
* where pages is the original.
* Gets the original translation pointer table, which is always the same table
*
* @param string $table Name of the table
* @return string Pointer table (if any)
*/
public static function getOriginalTranslationTable($table)
{
return $table === 'pages_language_overlay' ? 'pages' : $table;
trigger_error('Starting with TYPO3 v9, the translation table is always the same as the original table, because pages_language_overlay has been migrated into pages table.', E_USER_DEPRECATED);
return $table;
}
/**
......@@ -3691,10 +3685,8 @@ class BackendUtility
public static function translationCount($table, $ref, $msg = '')
{
$count = null;
if ($table !== 'pages'
&& $GLOBALS['TCA'][$table]['ctrl']['languageField']
if ($GLOBALS['TCA'][$table]['ctrl']['languageField']
&& $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
&& $table !== 'pages_language_overlay'
) {
$queryBuilder = static::getQueryBuilderForTable($table);
$queryBuilder->getRestrictions()
......