La actualización de almacenamiento en caché de bloque EE 1.14.2 / CE 1.9.2 tiene claves de caché no únicas: contenido duplicado que se muestra en la interfaz


18

Cuando actualicé a EE 1.14.2, la mayoría de las cosas salieron bien, pero me encontré con un problema cuando comencé a revisar mis diversas páginas frontend. Tengo un nodo de catálogo con varias subcategorías y cada una de ellas tiene un bloque estático diferente que se muestra en ellas. Después de la actualización, la página que se haya accedido primero después de un vaciado de caché terminaría mostrándose en todas las páginas diferentes.

No sé si este mismo problema estará presente cuando se publique CE 1.9.2, pero quería poner mi solución aquí para aquellos que puedan encontrar este mismo problema.

ACTUALIZACIÓN: Como se confirmó aquí, el mismo problema surgió en CE 1.9.2


Respuestas:


11

Como se trataba de EE, pude utilizar el soporte de Magento, pero también resolví las cosas por mi cuenta para ayudar a enfocar el problema y obtener una solución lo más rápido posible. Magento proporcionó los cambios de código, por lo que aplicarlos a los archivos de la aplicación / código / núcleo está bien, aunque siempre podría duplicar los archivos en su / app / code / local y aplicar los cambios allí.

El problema era que el método de almacenamiento en caché de bloques que se agregó en 1.14.2 no generaba una clave de caché única, por lo que cuando utilicé varios bloques en el espacio del controlador de categoría, la clave de caché generada terminó siendo única solo para el primer golpe de página, resultando en todas esas páginas para mostrar contenido duplicado.

La solución fue agregar lo siguiente (se muestra en formato de archivo diff para mostrar el contexto que rodea las adiciones; solo agregue las líneas con el + a donde deben ir):

En app / code / core / Mage / Cms / Block / Block.php en la línea 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;
+    }
 }

En app / code / core / Mage / Cms / Block / Widget / Block.php en la línea 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;
+    }
 }

No creo que sea el único en ver este problema y si aparece en CE 1.9.2, espero que esto ayude a resolverlo para algunas personas.


Desafortunadamente, no llegó a CE 1.9.2, que se lanzó ayer, así que me encontré con este problema en uno de los sitios web de nuestros clientes después de la actualización. Intentará esta solución.
Marco Miltenburg

esto no funciona para mí
Pixelomo

10

¡Creo que es necesario crear un módulo personalizado porque todos saben que Magento Boogieman lo atrapará! si cambia el núcleo :)

Necesitará los siguientes archivos: 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;
   }
}

Para obtener más información, puede visitar el siguiente blog y también puede descargarlo https://www.milople.com/blogs/ecommerce/solved-magento-static-block-display-issue.html


¿por qué no lo empacas en un módulo con compositor?
Aleksey Razbakov

No he tenido mucho respuesta a esta entrada, así que pensé ningún organismo quiere que en el módulo
Bhupendra Jadeja

Nadie tenía este problema todavía. nadie usa la nueva versión de magento todavía. tampoco lo usaría si no tuviera problemas con el módulo de trementina
Aleksey Razbakov

He agregado el enlace para descargar este módulo
Bhupendra Jadeja

sería genial tenerlo en github con modman y compositor como github.com/progammer-rkt/Rkt_SbCache
Aleksey Razbakov

4

Hay un problema más con el almacenamiento en caché de bloques CMS, que no se soluciona con el código dado desde arriba.

Si está utilizando URL seguras y etiquetas {{media}} en sus bloques de CMS, recibirá un mensaje de "Advertencia de contenido inseguro" del navegador, ya que Magento sirve enlaces inseguros de la memoria caché.

Para resolverlo, debe agregar una etiqueta de información de caché más, como

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

1

Este error también se puede solucionar con esta pequeña extensión (no es necesario editar archivos principales ni reescribir bloques):

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

Y también contiene la línea mencionada por @AdvancedLogic para evitar advertencias de contenido inseguro:

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


esto no funcionó durante 1 bloque de alguna manera
Aleksey Razbakov

¿Para qué bloque? No entiendo, ¿puedes ser más específico, por favor?
zitix

Es solo un bloque estático. Nada específico. Incluso pensé que era solo un bloque aleatorio. Hubo un HTML incorrecto. Parecía que se usó caché incorrecta para este bloque. No sé cómo ser más específico aquí.
Aleksey Razbakov
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.