18

When I upgraded to EE 1.14.2, most things went smoothly but I came across an issue when I started to check my various frontend pages. I have a catalog node with several subcategories and each of those has a different static block showing on them. After the upgrade, whichever page was hit first after a cache flush would end up showing on all of the different pages.

I don't know if this same issue will be present when CE 1.9.2 is released but I wanted to put my solution here for those who may find this same issue.

UPDATE: As confirmed here the same problem came up in CE 1.9.2

Mike
  • 426
  • 3
  • 7

4 Answers4

11

Since this was EE, I was able to utilize Magento support but I also worked things out on my own to help focus the issue and get a solution as fast as possible. The code changes were provided by Magento so applying them to the actual app/code/core files is fine though you could always duplicate the files in your /app/code/local and apply the changes there.

The issue was that the block caching method that was added in 1.14.2 was not generating a unique cache key so when I had multiple blocks used in the category controller space, the generated cache key ended up being unique only for the first page hit, resulting in all of those pages to show duplicate content.

The fix was to add the following (displayed in diff file format to show the context surrounding the additions - just add in the lines with the + where they need to go):

In app/code/core/Mage/Cms/Block/Block.php at line 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;
+    }
 }

In app/code/core/Mage/Cms/Block/Widget/Block.php at line 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;
+    }
 }

I wouldn't think I'd be the only one to see this issue and if it shows up in CE 1.9.2, hopefully this will help resolve it for some people.

Mike
  • 426
  • 3
  • 7
10

I think proper way is we need to create Custom module because you all know that Magento Boogieman will get you! if change the core :)

You will need to following files: 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;
   }
}

For more information you can visit following blog and you can also download from it https://www.milople.com/blogs/ecommerce/solved-magento-static-block-display-issue.html

Bhupendra Jadeja
  • 2,729
  • 24
  • 46
4

There is one more problem with CMS blocks caching, that is not fixed with given code from above.

If you are using secure urls and {{media}} tags in your CMS blocks, you will receive "Insecure content warning" message from browser, as Magento serves insecure links from cache.

To resolve it, you need to add one more cache info tag, as

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

This bug can also be fixed with this little extension (no need to edit core files nor to rewrite blocks):

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

And it also contains the line mentioned by @AdvancedLogic to avoid insecure content warning:

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

zitix
  • 2,192
  • 7
  • 32
  • 48