From 2f9d14703586686b73640ab4559bb1e6ad43d100 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Thu, 7 May 2020 22:07:42 +0200
Subject: [PATCH] [BUGFIX] Fix HMENU special=directory when site language is in
 free mode

When setting a site language into free mode for translations, then
"$cObj->exec_getQuery()" only returns the pages without overlays.
HMENU however always expects sys_language_uid=0 records, as it does a
MountPoint + overlay again. Doing an getPageOverlay of a translated page
results in an empty result.

The change now modifies the HMENU directory resolving
to fetch the original record (cached in PageRepository), and do
the overlay information as well.

This also fixes the same issue in HMENU.special = updated

Big Kudos to Jones for great support on tackling this issue!

Resolves: #91292
Releases: master, 9.5
Change-Id: Ifc0faddb6562c2b83dc95aa84ed40f37b5a1a0e9
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64436
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Jonas Temmen <jonas.temmen@artundweise.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Jonas Temmen <jonas.temmen@artundweise.de>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../Menu/AbstractMenuContentObject.php           | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
index 9193ed6e6d86..dbc3c8941581 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
@@ -686,6 +686,14 @@ abstract class AbstractMenuContentObject
             // Get sub-pages:
             $statement = $this->parent_cObj->exec_getQuery('pages', ['pidInList' => $id, 'orderBy' => $sortingField]);
             while ($row = $statement->fetch()) {
+                // When the site language configuration is in "free" mode, then the page without overlay is fetched
+                // (which is kind-of strange for pages, but this is what exec_getQuery() is doing)
+                // this means, that $row is a translated page, but hasn't been overlaid. For this reason, we fetch
+                // the default translation page again, (which does a ->getPageOverlay() again - doing this on a
+                // translated page would result in no record at all)
+                if ($row['l10n_parent'] > 0 && !isset($row['_PAGES_OVERLAY'])) {
+                    $row = $this->sys_page->getPage($row['l10n_parent'], true);
+                }
                 $tsfe->sys_page->versionOL('pages', $row, true);
                 if (!empty($row)) {
                     // Keep mount point?
@@ -856,6 +864,14 @@ abstract class AbstractMenuContentObject
             'max' => $limit
         ]);
         while ($row = $statement->fetch()) {
+            // When the site language configuration is in "free" mode, then the page without overlay is fetched
+            // (which is kind-of strange for pages, but this is what exec_getQuery() is doing)
+            // this means, that $row is a translated page, but hasn't been overlaid. For this reason, we fetch
+            // the default translation page again, (which does a ->getPageOverlay() again - doing this on a
+            // translated page would result in no record at all)
+            if ($row['l10n_parent'] > 0 && !isset($row['_PAGES_OVERLAY'])) {
+                $row = $this->sys_page->getPage($row['l10n_parent'], true);
+            }
             $tsfe->sys_page->versionOL('pages', $row, true);
             if (is_array($row)) {
                 $menuItems[$row['uid']] = $this->sys_page->getPageOverlay($row);
-- 
GitLab