[BUGFIX] Use cHash in language menu links if necessary 42/21242/4
authorDmitry Dulepov <dmitry.dulepov@gmail.com>
Wed, 5 Jun 2013 13:05:49 +0000 (16:05 +0300)
committerGeorg Ringer <georg.ringer@gmail.com>
Thu, 13 Mar 2014 08:23:37 +0000 (09:23 +0100)
Current menu implementation does not add the cHash in language
menus. This causes a non-cached page and performance
degradation if the page contains parameters and a user switches
between languages. Together with extensions like RealURL it
can become a long time issue because of the caching of wrong
URLs. The fix implements analysis for the query string and
relevant parameters to decide whether the cHash should be
added or not.

Change-Id: I711e732555e03c9bf5a1321523b505735aa20c41
Resolves: #33833
Releases: 6.2
Reviewed-on: https://review.typo3.org/21242
Reviewed-by: Philipp Gampe
Tested-by: Philipp Gampe
Reviewed-by: Jigal van Hemert
Reviewed-by: Georg Ringer
Tested-by: Georg Ringer
typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php

index 403944a..b091855 100644 (file)
@@ -216,6 +216,14 @@ class AbstractMenuContentObject {
         */
        public $nameAttribute = 'name';
 
+       /**
+        * TRUE to use cHash in generated link (normally only for the language
+        * selector and if parameters exist in the URL).
+        *
+        * @var bool
+        */
+       protected $useCacheHash = FALSE;
+
        /**
         * The initialization of the object. This just sets some internal variables.
         *
@@ -373,6 +381,8 @@ class AbstractMenuContentObject {
         */
        public function makeMenu() {
                if ($this->id) {
+                       $this->useCacheHash = FALSE;
+
                        // Initializing showAccessRestrictedPages
                        if ($this->mconf['showAccessRestrictedPages']) {
                                // SAVING where_groupAccess
@@ -415,6 +425,7 @@ class AbstractMenuContentObject {
                                                        }
                                                        if ($this->conf['addQueryString']) {
                                                                $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'], array('L' => $sUid), TRUE);
+                                                               $this->analyzeCacheHashRequirements($getVars);
                                                        } else {
                                                                $getVars = '&L=' . $sUid;
                                                        }
@@ -908,6 +919,28 @@ class AbstractMenuContentObject {
                }
        }
 
+       /**
+        * Analyzes the parameters to find if the link needs a cHash parameter.
+        *
+        * @param string $queryString
+        * @return void
+        */
+       protected function analyzeCacheHashRequirements($queryString) {
+               $parameters = \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array($queryString);
+               if (count($parameters) > 0) {
+                       $cacheHashCalculator = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator');
+                       /** @var \TYPO3\CMS\Frontend\Page\CacheHashCalculator $cacheHashCalculator */
+                       $cHashParameters = $cacheHashCalculator->getRelevantParameters($queryString);
+                       if (count($cHashParameters) > 1) {
+                               $this->useCacheHash = (
+                                       $GLOBALS['TYPO3_CONF_VARS']['FE']['disableNoCacheParameter'] ||
+                                       !isset($parameters['no_cache']) ||
+                                       !$parameters['no_cache']
+                               );
+                       }
+               }
+       }
+
        /**
         * Checks if a page is OK to include in the final menu item array. Pages can be excluded if the doktype is wrong, if they are hidden in navigation, have a uid in the list of banned uids etc.
         *
@@ -1765,6 +1798,8 @@ class AbstractMenuContentObject {
                }
                if ($no_cache) {
                        $conf['no_cache'] = TRUE;
+               } elseif ($this->useCacheHash) {
+                       $conf['useCacheHash'] = TRUE;
                }
                if ($oTarget) {
                        $conf['target'] = $oTarget;