[BUGFIX] Invalid shortcut target on translated pages 65/12765/6
authorOliver Hader <oliver@typo3.org>
Sat, 13 Oct 2012 11:38:19 +0000 (13:38 +0200)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Mon, 17 Feb 2014 22:57:31 +0000 (23:57 +0100)
A feature to resolve shortcut links directly in menu rendering
does not consider the overlay behaviour of the "shortcut" value.

TSFE first uses the "shortcut" value of the original/default
page and then serves for possible translated alternatives
(TypoScriptFrontendController::checkTranslatedShortcut()).
In menu rendering it's the other way round, the translated
overlay (if any) is used directly - the fallback to use the
"shortcut" value of the original/default page is not implemented.

This change introduces the fallback when rendering menus, which
will take the "shortcut" value of the default language if the
value in the overlay is empty.

Change-Id: I26a9eb4813c6b99327043b0a764ec7ff80b6a905
Fixes: #36822
Releases: 6.2, 6.1
Reviewed-on: https://review.typo3.org/12765
Reviewed-by: Markus Klein
Tested-by: Markus Klein
Reviewed-by: Wouter Wolters
Reviewed-by: Stefan Neufeind
Tested-by: Stefan Neufeind
typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php

index 0d05bb7..347236c 100644 (file)
@@ -1277,9 +1277,16 @@ class AbstractMenuContentObject {
                }
                // Override url if current page is a shortcut
                if ($this->menuArr[$key]['doktype'] == \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_SHORTCUT && $this->menuArr[$key]['shortcut_mode'] != \TYPO3\CMS\Frontend\Page\PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) {
+
+                       $menuItem = $this->determineOriginalShortcutPage($this->menuArr[$key]);
+
                        $shortcut = NULL;
                        try {
-                               $shortcut = $GLOBALS['TSFE']->getPageShortcut($this->menuArr[$key]['shortcut'], $this->menuArr[$key]['shortcut_mode'], $this->menuArr[$key]['uid']);
+                               $shortcut = $GLOBALS['TSFE']->getPageShortcut(
+                                       $menuItem['shortcut'],
+                                       $menuItem['shortcut_mode'],
+                                       $menuItem['uid']
+                               );
                        } catch (\Exception $ex) {
 
                        }
@@ -1289,7 +1296,7 @@ class AbstractMenuContentObject {
                        // Only setting url, not target
                        $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array(
                                'parameter' => $shortcut['uid'],
-                               'additionalParams' => $this->mconf['addParams'] . $MP_params . $this->I['val']['additionalParams'] . $this->menuArr[$key]['_ADD_GETVARS']
+                               'additionalParams' => $this->mconf['addParams'] . $MP_params . $this->I['val']['additionalParams'] . $menuItem['_ADD_GETVARS'],
                        ));
                }
                // Manipulation in case of access restricted pages:
@@ -1345,6 +1352,38 @@ class AbstractMenuContentObject {
        }
 
        /**
+        * Determines original shortcut destination in page overlays.
+        *
+        * Since the pages records used for menu rendering are overlaid by default,
+        * the original 'shortcut' value is lost, if a translation did not define one.
+        * The behaviour in TSFE can be compared to the 'mergeIfNotBlank' feature, but
+        * it's hardcoded there and not related to the mentioned setting at all.
+        *
+        * @param array $page
+        * @return array
+        * @todo Once the page_language_overlay behaviour was removed, this method can be removed again
+        */
+       protected function determineOriginalShortcutPage(array $page) {
+               // Check if modification is required
+               if (
+                       $GLOBALS['TSFE']->sys_language_uid > 0
+                       && empty($page['shortcut'])
+                       && !empty($page['uid'])
+                       && !empty($page['_PAGES_OVERLAY'])
+                       && !empty($page['_PAGES_OVERLAY_UID'])
+               ) {
+                       // Using raw record since the record was overlaid and is correct already:
+                       $originalPage = $this->sys_page->getRawRecord('pages', $page['uid']);
+
+                       if (!empty($originalPage['shortcut'])) {
+                               $page['shortcut'] = $originalPage['shortcut'];
+                       }
+               }
+
+               return $page;
+       }
+
+       /**
         * Will change $LD (passed by reference) if the page is access restricted
         *
         * @param array $LD The array from the linkData() function