Project

General

Profile

Bug #17354 » BUGFIX-17354-fallback-for-menus-content_fallback-7_6-.patch

Nikolaj Wojtkowiak-Pfänder, 2016-11-18 09:23

View differences:

typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
) {
if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], [-1, 0])) {
$overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : '';
$row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode);
$row = $pageRepository->getRecordOverlayWithFallback(
$tableName, $row, $querySettings->getLanguageUid(), $overlayMode
);
}
}
if ($row !== null && is_array($row)) {
typo3/sysext/frontend/Classes/Aspect/FileMetadataOverlayAspect.php
{
$overlaidMetaData = $data->getArrayCopy();
$this->getTsfe()->sys_page->versionOL('sys_file_metadata', $overlaidMetaData);
$overlaidMetaData = $this->getTsfe()->sys_page->getRecordOverlay(
'sys_file_metadata',
$overlaidMetaData,
$this->getTsfe()->sys_language_content,
$this->getTsfe()->sys_language_contentOL
);
$overlaidMetaData = $this->getTsfe()->sys_page->getRecordOverlayWithFallback(
'sys_file_metadata',
$overlaidMetaData
);
if ($overlaidMetaData !== null) {
$data->exchangeArray($overlaidMetaData);
}
typo3/sysext/frontend/Classes/Category/Collection/CategoryCollection.php
if ($this->getItemTableName() === 'pages') {
$record = $tsfe->sys_page->getPageOverlay($record);
} else {
$record = $tsfe->sys_page->getRecordOverlay(
$this->getItemTableName(),
$record,
$tsfe->sys_language_content,
$tsfe->sys_language_contentOL
);
$record = $this->getFrontendObject()->sys_page->getRecordOverlayWithFallback(
$this->getItemTableName(),
$record
);
}
}
// Record may have been unset during the overlay process
typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php
if ($referencesForeignTable === 'pages') {
$element = $pageRepository->getPageOverlay($element);
} else {
$element = $pageRepository->getRecordOverlay(
$referencesForeignTable,
$element,
$GLOBALS['TSFE']->sys_language_content,
$GLOBALS['TSFE']->sys_language_contentOL
);
$element = $pageRepository->getRecordOverlayWithFallback($referencesForeignTable, $element);
}
}
typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
$tok = true;
// There is an alternative language active AND the current page requires a translation:
if ($tsfe->sys_language_uid && GeneralUtility::hideIfNotTranslated($data['l18n_cfg'])) {
if (!$data['_PAGES_OVERLAY']) {
if (!$data['_PAGES_OVERLAY'] || (int)$data['sys_language_uid'] !== (int)$GLOBALS['TSFE']->sys_language_uid) {
$tok = false;
}
}
......
while ($row = $this->getDatabaseConnection()->sql_fetch_assoc($resource)) {
$this->sys_page->versionOL('tt_content', $row);
if ($tsfe->sys_language_contentOL && $basePageRow['_PAGES_OVERLAY_LANGUAGE']) {
$row = $this->sys_page->getRecordOverlay('tt_content', $row, $basePageRow['_PAGES_OVERLAY_LANGUAGE'], $tsfe->sys_language_contentOL);
$row = $this->sys_page->getRecordOverlayWithFallback('tt_content', $row, $basePageRow['_PAGES_OVERLAY_LANGUAGE']);
}
if ($this->mconf['sectionIndex.']['type'] !== 'all') {
$doIncludeInSectionIndex = $row['sectionIndex'] >= 1;
typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php
$this->itemArray = [];
$this->data = [];
$tsfe = $this->getTypoScriptFrontendController();
$theValue = '';
$originalRec = $GLOBALS['TSFE']->currentRecord;
$originalRec = $tsfe->currentRecord;
// If the currentRecord is set, we register, that this record has invoked this function.
// It's should not be allowed to do this again then!!
if ($originalRec) {
++$GLOBALS['TSFE']->recordRegister[$originalRec];
++$tsfe->recordRegister[$originalRec];
}
$tables = isset($conf['tables.']) ? $this->cObj->stdWrap($conf['tables'], $conf['tables.']) : $conf['tables'];
......
foreach ($this->itemArray as $val) {
$row = $this->data[$val['table']][$val['id']];
// Perform overlays if necessary (records coming from category collections are already overlaid)
if ($source) {
// Versioning preview
$GLOBALS['TSFE']->sys_page->versionOL($val['table'], $row);
// Language overlay
if (is_array($row) && $GLOBALS['TSFE']->sys_language_contentOL) {
if ($val['table'] === 'pages') {
$row = $GLOBALS['TSFE']->sys_page->getPageOverlay($row);
} else {
$row = $GLOBALS['TSFE']->sys_page->getRecordOverlay($val['table'], $row, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
}
}
}
if ($source) {
// Versioning preview
$tsfe->sys_page->versionOL($val['table'], $row);
// Language overlay
if (is_array($row) && $tsfe->sys_language_contentOL) {
if ($val['table'] === 'pages') {
$row = $tsfe->sys_page->getPageOverlay($row);
} else {
$fallbackChain = NULL;
if (isset($conf['languageFallbackChain'])) {
$fallbackChain = GeneralUtility::intExplode(',', $conf['languageFallbackChain']);
}
$pageLanguageBinding = !isset($conf['respectPageLanguageBinding']) || (int)$conf['respectPageLanguageBinding'] !== '0';
$row = $tsfe->sys_page->getRecordOverlayWithFallback(
$val['table'], $row, NULL, NULL, $fallbackChain, $pageLanguageBinding
);
}
}
}
// Might be unset during the overlay process
if (is_array($row)) {
$dontCheckPid = isset($conf['dontCheckPid.']) ? $this->cObj->stdWrap($conf['dontCheckPid'], $conf['dontCheckPid.']) : $conf['dontCheckPid'];
if (!$dontCheckPid) {
$row = $this->cObj->checkPid($row['pid']) ? $row : '';
}
if ($row && !$GLOBALS['TSFE']->recordRegister[$val['table'] . ':' . $val['id']]) {
if ($row && !$tsfe->recordRegister[($val['table'] . ':' . $val['id'])]) {
$renderObjName = $conf['conf.'][$val['table']] ?: '<' . $val['table'];
$renderObjKey = $conf['conf.'][$val['table']] ? 'conf.' . $val['table'] : '';
$renderObjConf = $conf['conf.'][$val['table'] . '.'];
$this->cObj->currentRecordNumber++;
$cObj->parentRecordNumber = $this->cObj->currentRecordNumber;
$GLOBALS['TSFE']->currentRecord = $val['table'] . ':' . $val['id'];
$tsfe->currentRecord = $val['table'] . ':' . $val['id'];
$this->cObj->lastChanged($row['tstamp']);
$cObj->start($row, $val['table']);
$tmpValue = $cObj->cObjGetSingle($renderObjName, $renderObjConf, $renderObjKey);
......
$theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']);
}
// Restore
$GLOBALS['TSFE']->currentRecord = $originalRec;
$tsfe->currentRecord = $originalRec;
if ($originalRec) {
--$GLOBALS['TSFE']->recordRegister[$originalRec];
}
......
{
return $GLOBALS['TT'];
}
/**
* @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
*/
protected function getTypoScriptFrontendController() {
return $GLOBALS['TSFE'];
}
}
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
*/
public $sys_language_content = 0;
/**
* Contains the prioritized language fallback chain
*
* @var array
*/
public $languageFallbackChain = array();
/**
* Contains the prioritized language fallback chain for the current page
*
* @var array
*/
public $languageFallbackChainWithPageLanguageBinding = array();
/**
* Site content overlay flag; If set - and sys_language_content is > 0 - ,
* records selected will try to look for a translation pointing to their uid. (If
......
// Get values from TypoScript:
$this->sys_language_uid = ($this->sys_language_content = (int)$this->config['config']['sys_language_uid']);
list($this->sys_language_mode, $sys_language_content) = GeneralUtility::trimExplode(';', $this->config['config']['sys_language_mode']);
$this->sys_language_contentOL = $this->config['config']['sys_language_overlay'];
$languageFallbackChain = GeneralUtility::intExplode(',', $this->config['config']['languageFallbackChain']);
$this->sys_language_contentOL = $this->config['config']['sys_language_overlay'];
// If sys_language_uid is set to another language than default:
if ($this->sys_language_uid > 0) {
// check whether a shortcut is overwritten by a translated page
......
$this->pageNotFoundAndExit('Page is not available in the requested language (strict).');
break;
case 'content_fallback':
$fallBackOrder = GeneralUtility::intExplode(',', $sys_language_content);
foreach ($fallBackOrder as $orderValue) {
if ((string)$orderValue === '0' || !empty($this->sys_page->getPageOverlay($this->id, $orderValue))) {
$this->sys_language_content = $orderValue;
// Setting content uid (but leaving the sys_language_uid)
break;
}
}
// default is to fallback to default language
$this->sys_language_content = 0;
foreach ($languageFallbackChain as $languageId) {
// break the language chain if the current language is selected
if ($languageId === 0) {
break;
}
// ignore current and invalid language ids
if ($this->sys_language_uid === $languageId || $languageId < 0) {
continue;
}
$pageOverlay = $this->sys_page->getPageOverlay($this->id, $languageId);
if (!empty($pageOverlay)) {
// Setting content uid (but leaving the sys_language_uid)
$this->sys_language_content = $languageId;
// overlay page with existing page overlay
$this->page = array_merge($this->page, $pageOverlay);
break;
}
}
break;
case 'ignore':
$this->sys_language_content = $this->sys_language_uid;
......
default:
// Default is that everything defaults to the default language...
$this->sys_language_uid = ($this->sys_language_content = 0);
break;
}
}
}
} else {
// Setting sys_language if an overlay record was found (which it is only if a language is used)
$this->page = $this->sys_page->getPageOverlay($this->page, $this->sys_language_uid);
// overlay page with existing page overlay
$this->page = array_merge($this->page, $olRec);
}
// calculate the language fallback chains
if ($this->sys_language_mode === 'content_fallback') {
foreach ($languageFallbackChain as $languageId) {
// ignore current and invalid language ids
if ($this->sys_language_uid === $languageId || $languageId < 0) {
continue;
}
$this->languageFallbackChain[] = $languageId;
if ($languageId === 0 || count($this->sys_page->getPageOverlay($this->id, $languageId))) {
$this->languageFallbackChainWithPageLanguageBinding[] = $languageId;
}
}
}
}
// Setting sys_language_uid inside sys-page:
$this->sys_page->sys_language_uid = $this->sys_language_uid;
// If default translation is not available:
if ((!$this->sys_language_uid || !$this->sys_language_content) && GeneralUtility::hideIfDefaultLanguage($this->page['l18n_cfg'])) {
$message = 'Page is not available in default language.';
// If default translation is not to be selected
if ($this->page['l18n_cfg']&1 && !($this->sys_language_uid && $this->sys_language_content)) {
$message = 'Page is not available in default language.';
GeneralUtility::sysLog($message, 'cms', GeneralUtility::SYSLOG_SEVERITY_ERROR);
$this->pageNotFoundAndExit($message);
}
typo3/sysext/frontend/Classes/Page/PageRepository.php
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Core\Versioning\VersionState;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* Page functions, a lot of sql/pages-related functions
......
return [];
}
// Initialize:
if ($lUid < 0) {
$lUid = $this->sys_language_uid;
}
$noSpecialLanguageRequested = FALSE;
if ($lUid < 0) {
$noSpecialLanguageRequested = TRUE;
$lUid = $this->sys_language_uid;
}
$row = null;
if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay'])) {
foreach ($pagesInput as &$origPage) {
......
}
unset($origPage);
}
// If language UID is different from zero, do overlay:
if ($lUid) {
$fieldArr = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields'], true);
......
$page_ids[] = $origPage;
}
}
if (!empty($fieldArr)) {
if (!in_array('pid', $fieldArr, true)) {
$fieldArr[] = 'pid';
}
// NOTE to enabledFields('pages_language_overlay'):
// Currently the showHiddenRecords of TSFE set will allow
// pages_language_overlay records to be selected as they are
// child-records of a page.
// However you may argue that the showHiddenField flag should
// determine this. But that's not how it's done right now.
// Selecting overlay record:
$db = $this->getDatabaseConnection();
$res = $db->exec_SELECTquery(
implode(',', $fieldArr),
'pages_language_overlay',
'pid IN(' . implode(',', $db->cleanIntArray($page_ids)) . ')'
. ' AND sys_language_uid=' . (int)$lUid . $this->enableFields('pages_language_overlay')
);
$overlays = [];
while ($row = $db->sql_fetch_assoc($res)) {
$this->versionOL('pages_language_overlay', $row);
if (is_array($row)) {
$row['_PAGES_OVERLAY'] = true;
$row['_PAGES_OVERLAY_UID'] = $row['uid'];
$row['_PAGES_OVERLAY_LANGUAGE'] = $lUid;
$origUid = $row['pid'];
// Unset vital fields that are NOT allowed to be overlaid:
unset($row['uid']);
unset($row['pid']);
$overlays[$origUid] = $row;
}
}
$db->sql_free_result($res);
}
if (!empty($fieldArr)) {
if (!in_array('pid', $fieldArr, TRUE)) {
$fieldArr[] = 'pid';
}
$languageClause = 'sys_language_uid=' . (int)$lUid . ' ';
$languageList = array();
if ($noSpecialLanguageRequested) {
$languageList = array_unique(array_merge(
[ $lUid ],
$this->getTypoScriptFrontendController()->languageFallbackChain,
[ $this->getTypoScriptFrontendController()->sys_language_content ]
));
$languageIds = implode(',', array_map('intval', $languageList));
$languageClause = 'sys_language_uid IN (' . $languageIds . ') ';
}
// NOTE to enabledFields('pages_language_overlay'):
// Currently the showHiddenRecords of TSFE set will allow pages_language_overlay records to be selected as they are child-records of a page.
// However you may argue that the showHiddenField flag should determine this. But that's not how it's done right now.
// Selecting overlay record:
if (!in_array('sys_language_uid', $fieldArr)) {
$fieldArr[] = 'sys_language_uid';
}
$db = $this->getDatabaseConnection();
$res = $db->exec_SELECTquery(
implode(',', $fieldArr),
'pages_language_overlay',
'pid IN(' . implode(',', $db->cleanIntArray($page_ids)) . ')'
. ' AND ' . $languageClause . $this->enableFields('pages_language_overlay')
);
$overlays = array();
while ($row = $db->sql_fetch_assoc($res)) {
$this->versionOL('pages_language_overlay', $row);
if (is_array($row)) {
$row['_PAGES_OVERLAY'] = TRUE;
$row['_PAGES_OVERLAY_UID'] = $row['uid'];
$row['_PAGES_OVERLAY_LANGUAGE'] = $lUid;
$origUid = $row['pid'];
// Unset vital fields that are NOT allowed to be overlaid:
unset($row['uid']);
unset($row['pid']);
$overlays[$origUid] = $row;
}
}
$db->sql_free_result($res);
}
}
// Create output:
$pagesOutput = [];
......
}
}
}
return $pagesOutput;
}
/**
* Creates a language overlay for records stored inside tables which contain the
* translation information themselves. In addition to getRecordOverlay this method
* also checks for specified content language fallbacks and includes them.
*
* @param string $table Table name
* @param array $row Record to overlay. Must containt uid, pid and $table]['ctrl']['languageField']
* @param int $sys_language_content Pointer to the sys_language uid for content on the site.
* @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but unset (and return value is FALSE)
* @param array|NULL $fallbackList ordered fallback list of language ids
* @param bool $pageLanguageBinding use page language binding for the language fallback chain (only used if fallbackList is NULL)
* @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
* @throws \UnexpectedValueException
*/
public function getRecordOverlayWithFallback($table, $row, $sys_language_content = NULL, $OLmode = NULL, $fallbackList = NULL, $pageLanguageBinding = TRUE) {
$tsfe = $this->getTypoScriptFrontendController();
$sys_language_content = $sys_language_content !== NULL ? $sys_language_content : $tsfe->sys_language_content;
$OLmode = $OLmode !== NULL ? $OLmode: $tsfe->sys_language_contentOL;
if ($fallbackList === NULL) {
$fallbackList = $tsfe->languageFallbackChainWithPageLanguageBinding;
if (!$pageLanguageBinding) {
$fallbackList = $tsfe->languageFallbackChain;
}
}
$record = $this->getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode);
if (!is_array($record) || !isset($record['_LOCALIZED_UID'])) {
if ($sys_language_content && $OLmode !== 'hideNonTranslated' && !empty($fallbackList)) {
foreach ($fallbackList as $fallbackId) {
$fallbackId = (int)$fallbackId;
if ($fallbackId === 0) {
$record = $row;
break;
}
$record = $this->getRecordOverlayWithoutFallback($table, $row, $fallbackId, $OLmode);
if (isset($record['_LOCALIZED_UID']) && is_array($record)) {
break;
}
}
}
}
return $record;
}
/**
* Creates language-overlay for records in general (where translation is found
* in records from the same table)
......
* @throws \UnexpectedValueException
* @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return FALSE if no translation is found.
*/
public function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '')
{
if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
$hookObject = GeneralUtility::getUserObj($classRef);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException($classRef . ' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881658);
}
$hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this);
}
}
if ($row['uid'] > 0 && ($row['pid'] > 0 || in_array($table, $this->tableNamesAllowedOnRootLevel, true))) {
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) {
// 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
// than a single table) and then use that. Could be implemented, but obviously
// takes a little more....) Will try to overlay a record only if the
// sys_language_content value is larger than zero.
if ($sys_language_content > 0) {
// Must be default language, otherwise no overlaying
if ((int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] === 0) {
// Select overlay record:
$res = $this->getDatabaseConnection()->exec_SELECTquery('*', $table, 'pid=' . (int)$row['pid'] . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '=' . (int)$sys_language_content . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . '=' . (int)$row['uid'] . $this->enableFields($table), '', '', '1');
$olrow = $this->getDatabaseConnection()->sql_fetch_assoc($res);
$this->getDatabaseConnection()->sql_free_result($res);
$this->versionOL($table, $olrow);
// Merge record content by traversing all fields:
if (is_array($olrow)) {
if (isset($olrow['_ORIG_uid'])) {
$row['_ORIG_uid'] = $olrow['_ORIG_uid'];
}
if (isset($olrow['_ORIG_pid'])) {
$row['_ORIG_pid'] = $olrow['_ORIG_pid'];
}
foreach ($row as $fN => $fV) {
if ($fN !== 'uid' && $fN !== 'pid' && isset($olrow[$fN])) {
if ($this->shouldFieldBeOverlaid($table, $fN, $olrow[$fN])) {
$row[$fN] = $olrow[$fN];
}
} elseif ($fN === 'uid') {
$row['_LOCALIZED_UID'] = $olrow['uid'];
}
}
} elseif ($OLmode === 'hideNonTranslated' && (int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] === 0) {
// Unset, if non-translated records should be hidden. ONLY done if the source
// record really is default language and not [All] in which case it is allowed.
unset($row);
}
} elseif ($sys_language_content != $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]) {
unset($row);
}
} else {
// When default language is displayed, we never want to return a record carrying
// another language!
if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
unset($row);
}
}
}
}
}
if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
$hookObject = GeneralUtility::getUserObj($classRef);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException($classRef . ' must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881659);
}
$hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this);
}
}
return $row;
}
public function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '') {
GeneralUtility::logDeprecatedFunction();
return $this->getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode);
}
/**
* Creates a language overlay for records stored inside tables which contain the
* translation information themselves.
*
*
* @param string $table Table name the record comes from
* @param array $row Record to overlay. Must contain the columns uid, pid and $TCA[$table]['ctrl']['languageField']
* @param int $sys_language_content Pointer to the sys_language uid to use for content.
* @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned translated but unset (and return value is FALSE)
* @throws \InvalidArgumentException
* @throws \UnexpectedValueException
* @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
*/
public function getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode) {
if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
$hookObject = GeneralUtility::getUserObj($classRef);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException('$hookObject must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881658);
}
$hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this);
}
}
if ($row['uid'] > 0 && ($row['pid'] > 0 || in_array($table, $this->tableNamesAllowedOnRootLevel, TRUE))) {
if ($GLOBALS['TCA'][$table] && $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
if (!$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) {
// 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
// than a single table) and then use that. Could be implemented, but obviously
// takes a little more....) Will try to overlay a record only if the
// sys_language_content value is larger than zero.
if ($sys_language_content > 0) {
// Must be default language or [All], otherwise no overlaying:
if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] <= 0) {
// Select overlay record:
$res = $this->getDatabaseConnection()->exec_SELECTquery('*', $table, 'pid=' . (int)$row['pid'] . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '=' . (int)$sys_language_content . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . '=' . (int)$row['uid'] . $this->enableFields($table), '', '', '1');
$olrow = $this->getDatabaseConnection()->sql_fetch_assoc($res);
$this->getDatabaseConnection()->sql_free_result($res);
$this->versionOL($table, $olrow);
// Merge record content by traversing all fields:
if (is_array($olrow)) {
if (isset($olrow['_ORIG_uid'])) {
$row['_ORIG_uid'] = $olrow['_ORIG_uid'];
}
if (isset($olrow['_ORIG_pid'])) {
$row['_ORIG_pid'] = $olrow['_ORIG_pid'];
}
foreach ($row as $fN => $fV) {
if ($fN !== 'uid' && $fN !== 'pid' && isset($olrow[$fN])) {
if ($this->shouldFieldBeOverlaid($table, $fN, $olrow[$fN])) {
$row[$fN] = $olrow[$fN];
}
} elseif ($fN === 'uid') {
$row['_LOCALIZED_UID'] = $olrow['uid'];
}
}
} elseif ($OLmode === 'hideNonTranslated' && (int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] === 0) {
// Unset, if non-translated records should be hidden. ONLY done if the source
// record really is default language and not [All] in which case it is allowed.
$row = NULL;
}
} elseif ($sys_language_content != $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]) {
$row = NULL;
}
} else {
// When default language is displayed, we never want to return a record carrying
// another language!
if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
$row = NULL;
}
}
}
}
}
if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
$hookObject = GeneralUtility::getUserObj($classRef);
if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
throw new \UnexpectedValueException('$hookObject must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881659);
}
$hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this);
}
}
return $row;
}
/************************************************
*
typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
$this->subject->sys_page->expects($this->once())->method('getPage')->will($this->returnValue(['_PAGES_OVERLAY_LANGUAGE' => 1]));
$this->subject->parent_cObj->expects($this->once())->method('exec_getQuery')->will($this->returnValue(1));
$GLOBALS['TYPO3_DB']->expects($this->exactly(2))->method('sql_fetch_assoc')->will($this->onConsecutiveCalls($this->returnValue(['uid' => 0, 'header' => 'NOT_OVERLAID']), $this->returnValue(false)));
$this->subject->sys_page->expects($this->once())->method('getRecordOverlay')->will($this->returnValue(['uid' => 0, 'header' => 'OVERLAID']));
$result = $this->subject->_call('sectionIndex', 'field');
$this->subject->sys_page->expects($this->once())->method('getRecordOverlayWithFallback')->will($this->returnValue(array('uid' => 0, 'header' => 'OVERLAID')));
$result = $this->subject->_call('sectionIndex', 'field');
$this->assertEquals($result[0]['title'], 'OVERLAID');
}
(11-11/12)