La mise à jour de la mise en cache des blocs EE 1.14.2 / CE 1.9.2 a des clés de cache non uniques - le contenu en double s'affiche sur le frontend

18

Lorsque j'ai mis à niveau vers EE 1.14.2, la plupart des choses se sont bien déroulées, mais j'ai rencontré un problème lorsque j'ai commencé à vérifier mes différentes pages frontales. J'ai un nœud de catalogue avec plusieurs sous-catégories et chacun d'eux a un bloc statique différent qui s'affiche. Après la mise à niveau, la page qui a été touchée en premier après un vidage du cache finirait par apparaître sur toutes les différentes pages.

Je ne sais pas si ce même problème sera présent lors de la sortie de CE 1.9.2 mais je voulais mettre ma solution ici pour ceux qui pourraient trouver ce même problème.

MISE À JOUR: Comme confirmé ici, le même problème est apparu dans CE 1.9.2

Mike
la source
Duplication possible des problèmes d'affichage des blocs statiques
Teja Bhagavan Kollepara

Réponses:

11

Comme il s'agissait d'EE, j'ai pu utiliser le support de Magento, mais j'ai également travaillé par moi-même pour aider à résoudre le problème et obtenir une solution aussi rapidement que possible. Les modifications de code ont été fournies par Magento, donc les appliquer aux fichiers app / code / core réels est correct, bien que vous puissiez toujours dupliquer les fichiers dans votre / app / code / local et y appliquer les modifications.

Le problème était que la méthode de mise en cache des blocs qui a été ajoutée dans 1.14.2 ne générait pas une clé de cache unique, donc lorsque j'ai utilisé plusieurs blocs dans l'espace du contrôleur de catégorie, la clé de cache générée a fini par être unique uniquement pour le premier accès à la page, résultant dans toutes ces pages pour afficher le contenu en double.

Le correctif consistait à ajouter ce qui suit (affiché au format de fichier diff pour montrer le contexte entourant les ajouts - il suffit d'ajouter les lignes avec le + où ils doivent aller):

Dans app / code / core / Mage / Cms / Block / Block.php à la ligne 72:

         }
         return $html;
     }
+
+    /**
+     * Retrieve values of properties that unambiguously identify unique content
+     *
+     * @return array
+     */
+    public function getCacheKeyInfo()
+    {
+        $blockId = $this->getBlockId();
+        if ($blockId) {
+            $result = array(
+                $blockId,
+                Mage::app()->getStore()->getCode(),
+            );
+        } else {
+            $result = parent::getCacheKeyInfo();
+        }
+        return $result;
+    }
 }

Dans app / code / core / Mage / Cms / Block / Widget / Block.php à la ligne 82:

                 $helper = Mage::helper('cms');
                 $processor = $helper->getBlockTemplateProcessor();
                 $this->setText($processor->filter($block->getContent()));
+                $this->addModelTags($block);
             }
         }

         unset(self::$_widgetUsageMap[$blockHash]);
         return $this;
     }
+
+    /**
+     * Retrieve values of properties that unambiguously identify unique content
+     *
+     * @return array
+     */
+    public function getCacheKeyInfo()
+    {
+        $result = parent::getCacheKeyInfo();
+        $blockId = $this->getBlockId();
+        if ($blockId) {
+            $result[] = $blockId;
+        }
+        return $result;
+    }
 }

Je ne pense pas que je serais le seul à voir ce problème et s'il apparaît dans CE 1.9.2, j'espère que cela aidera à le résoudre pour certaines personnes.

Mike
la source
Malheureusement, il n'est pas entré dans CE 1.9.2 qui a été publié hier, j'ai donc rencontré ce problème sur l'un des sites Web de nos clients après la mise à niveau. Va essayer ce correctif.
Marco Miltenburg
cela ne fonctionne pas pour moi
Pixelomo
10

Je pense que la bonne façon est de créer un module personnalisé parce que vous savez tous que Magento Boogieman vous obtiendra! si changer le noyau :)

Vous aurez besoin des fichiers suivants: app/etc/modules/Bhupendra_Cms.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Bhupendra_Cms>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Cms/>
            </depends>
        </Bhupendra_Cms>
    </modules>
</config>

app/code/local/Bhupendra/Cms/etc/config.xml

<?xml version="1.0"?>
<config>
        <modules>
            <Bhupendra_Cms>
                <version>1.0.0</version>
            </Bhupendra_Cms>
        </modules>
        <global>
            <blocks>
                <cms>
                    <rewrite>
                        <block>Bhupendra_Cms_Block_Block</block>
                        <widget_block>Bhupendra_Cms_Block_Widget_Block</widget_block>
                    </rewrite>
                </cms>
            </blocks>
        </global>
</config>

app/code/local/Bhupendra/Cms/Block/Block.php

<?php
class Bhupendra_Cms_Block_Block extends Mage_Cms_Block_Block {

   public function getCacheKeyInfo()
    {

      $blockId = $this->getBlockId();
      if ($blockId) {
            $result = array(
                $blockId,
                Mage::app()->getStore()->getCode(),
            );
      } else {
           $result = parent::getCacheKeyInfo();
       }
       return $result;
   }

}

app/code/local/Bhupendra/Cms/Block/Widget/Block.php

class Bhupendra_Cms_Block_Widget_Block extends Mage_Cms_Block_Widget_Block
{
       /**
     * Storage for used widgets
     *
     * @var array
     */
    static protected $_widgetUsageMap = array();

    /**
     * Prepare block text and determine whether block output enabled or not
     * Prevent blocks recursion if needed
     *
     * @return Mage_Cms_Block_Widget_Block
     */
    protected function _beforeToHtml()
    {
        parent::_beforeToHtml();
        $blockId = $this->getData('block_id');
        $blockHash = get_class($this) . $blockId;

        if (isset(self::$_widgetUsageMap[$blockHash])) {
            return $this;
        }
        self::$_widgetUsageMap[$blockHash] = true;

        if ($blockId) {
            $block = Mage::getModel('cms/block')
                ->setStoreId(Mage::app()->getStore()->getId())
                ->load($blockId);
            if ($block->getIsActive()) {
                /* @var $helper Mage_Cms_Helper_Data */
                $helper = Mage::helper('cms');
                $processor = $helper->getBlockTemplateProcessor();
                $this->setText($processor->filter($block->getContent()));
                $this->addModelTags($block);
            }
        }

        unset(self::$_widgetUsageMap[$blockHash]);
        return $this;
    }

     /**
     * Retrieve values of properties that unambiguously identify unique content
     *
     * @return array
     */
    public function getCacheKeyInfo()
    {
        $result = parent::getCacheKeyInfo();
        $blockId = $this->getBlockId();
        if ($blockId) {
            $result[] = $blockId;
       }
        return $result;
   }
}

Pour plus d'informations, vous pouvez visiter le blog suivant et vous pouvez également le télécharger à partir de celui-ci https://www.milople.com/blogs/ecommerce/solved-magento-static-block-display-issue.html

Bhupendra Jadeja
la source
pourquoi ne pas l'emballer dans un module avec compositeur?
Aleksey Razbakov
Je n'ai pas reçu autant de réponses à ce message, donc je pensais que personne ne le voulait dans le module
Bhupendra Jadeja
personne n'avait encore ce problème. personne n'utilise encore de nouvelle version de magento. je ne l'utiliserais pas aussi si je n'avais pas de problème avec le module térébenthine
Aleksey Razbakov
J'ai ajouté le lien pour télécharger ce module
Bhupendra Jadeja
ce serait cool de l'avoir dans github avec modman et compositeur comme github.com/progammer-rkt/Rkt_SbCache
Aleksey Razbakov
4

Il y a un autre problème avec la mise en cache des blocs CMS, qui n'est pas résolu avec le code donné ci-dessus.

Si vous utilisez des URL sécurisées et des balises {{media}} dans vos blocs CMS, vous recevrez un message "Avertissement de contenu non sécurisé" du navigateur, car Magento sert des liens non sécurisés à partir du cache.

Pour le résoudre, vous devez ajouter une balise d'informations de cache supplémentaire, comme

(int)Mage::app()->getStore()->isCurrentlySecure(),
Logique avancée
la source
1

Ce bug peut également être corrigé avec cette petite extension (pas besoin d'éditer les fichiers core ni de réécrire les blocs):

https://github.com/progammer-rkt/Rkt_SbCache

Et il contient également la ligne mentionnée par @AdvancedLogic pour éviter un avertissement de contenu non sécurisé:

(int)Mage::app()->getStore()->isCurrentlySecure()

zitix
la source
cela n'a pas fonctionné pour 1 bloc en quelque sorte
Aleksey Razbakov
Pour quel bloc? Je ne comprends pas, pouvez-vous être plus précis, s'il vous plaît?
zitix
Ce n'est qu'un bloc statique. Rien de spécial. J'ai même pensé que c'était juste un bloc aléatoire. Il y avait un mauvais HTML. Il semblait que le mauvais cache était utilisé pour ce bloc. Je ne sais pas comment être plus précis ici.
Aleksey Razbakov