Magento – Top Menu Cache Problem and Fixes

block-cachecachemagento-1.9topmenu

I have added category thumbnail images for sub-categories in top navigation.
On non secure pages images are being pulled from non secure path that is correct but when I am navigating to https page, the images are still pulled from http page which is incorrect.
To fix the issue I have modified method getCacheKeyInfo in class Mage_Page_Block_Html_Topmenu from

 $shortCacheId = array(
             'TOPMENU',
             Mage::app()->getStore()->getId(),
             Mage::getDesign()->getPackageName(),
             Mage::getDesign()->getTheme('template'),
             Mage::getSingleton('customer/session')->getCustomerGroupId(),
             'template' => $this->getTemplate(),
             'name' => $this->getNameInLayout(),
             $this->getCurrentEntityKey()
         );
         $cacheId = $shortCacheId;

         $shortCacheId = array_values($shortCacheId);
         $shortCacheId = implode('|', $shortCacheId);
         $shortCacheId = md5($shortCacheId);
         $cacheId['entity_key'] = $this->getCurrentEntityKey();
         $cacheId['short_cache_id'] = $shortCacheId;

         return $cacheId;

to

$shortCacheId = array(
            'TOPMENU',
            Mage::app()->getStore()->getId(),
            (int)Mage::app()->getStore()->isCurrentlySecure(),
            Mage::getDesign()->getPackageName(),
            Mage::getDesign()->getTheme('template'),
            Mage::getSingleton('customer/session')->getCustomerGroupId(),
            'template' => $this->getTemplate(),
            'name' => $this->getNameInLayout(),
            $this->getCurrentEntityKey()
        );
        $cacheId = $shortCacheId;
        $shortCacheId = array_values($shortCacheId);
        $shortCacheId = implode('|', $shortCacheId);
        $shortCacheId = md5($shortCacheId);

        $cacheId['entity_key'] = $this->getCurrentEntityKey();
        $cacheId['short_cache_id'] = $shortCacheId;

        return $cacheId;

But the issue persists and still the images in top navigation are getting pulled from http url on https page.

Please let me know how this issue can be fixed.
Any help will be appreciated.

CODE FOR ADDING IMAGES

I have re-written class Mage_Catalog_Model_Observer below methods

public function addCategoryImages(Varien_Event_Observer $observer) {
    $block = $observer->getEvent()->getBlock();
    $block->addCacheTag(Mage_Catalog_Model_Category::CACHE_TAG);
    $this->_addCategoriesToMenu(
        Mage::helper('catalog/category')->getStoreCategories(), $observer->getMenu(), $block, true
    );
}

public function _addCategoriesToMenu($categories, $parentCategoryNode, $menuBlock, $addTags = false) {
    $categoryModel = Mage::getModel('catalog/category');
    foreach ($categories as $category) {
        if (!$category->getIsActive()) {
            continue;
        }

        $nodeId = 'category-node-' . $category->getId();

        $categoryModel->setId($category->getId());
        if ($addTags) {
            $menuBlock->addModelTags($categoryModel);
        }

        $tree = $parentCategoryNode->getTree();
        $categoryData = array(
            'name' => $category->getName(),
            'id' => $nodeId,
            'url' => Mage::helper('catalog/category')->getCategoryUrl($category),
            'is_active' => $this->_isActiveMenuCategory($category),
            'thumbnail' => $categoryModel->load($category->getId())->getThumbnail()
        );
        $categoryNode = new Varien_Data_Tree_Node($categoryData, 'id', $tree, $parentCategoryNode);
        $parentCategoryNode->addChild($categoryNode);

        $flatHelper = Mage::helper('catalog/category_flat');
        if ($flatHelper->isEnabled() && $flatHelper->isBuilt(true)) {
            $subcategories = (array) $category->getChildrenNodes();
        } else {
            $subcategories = $category->getChildren();
        }

        $this->_addCategoriesToMenu($subcategories, $categoryNode, $menuBlock, $addTags);
    }
}

I have added "thumbnail" in categoryData array and then fetched this in template app/design/frontend/rwd/bluebath/template/page/html/topmenu/renderer.phtml

Below is the code for renderer.phtml

$html = '';

$children = $menuTree->getChildren(); $parentLevel =
$menuTree->getLevel(); $childLevel = is_null($parentLevel) ? 0 :
$parentLevel + 1;

$counter = 1; $childrenCount = $children->count();

$parentPositionClass = $menuTree->getPositionClass();
$itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass
. '-' : 'nav-';

if(Mage::app()->getStore()->isCurrentlySecure()){ $mediaurl =
Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA,true); }else{
$mediaurl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA); }

foreach ($children as $child) {
$child->setLevel($childLevel);
$child->setIsFirst($counter == 1);
$child->setIsLast($counter == $childrenCount);
$child->setPositionClass($itemPositionClassPrefix . $counter);

$outermostClassCode = 'level' . $childLevel;
$_hasChildren = ($child->hasChildren()) ? 'has-children' : '';

if ($childLevel != 0) {
    $urls = $mediaurl . 'catalog/category/' . $child->getData('thumbnail');
    $img = '<img src="' . $urls . '" alt="' . $child->getName() . '" />';
}

$html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>';

if ($childLevel != 0) {
    $html .= '<a href="' . $child->getUrl() . '" class="' . $outermostClassCode . ' ' . $_hasChildren . '">' . $img .

$this->escapeHtml($this->($child->getName())) . '';
} else {
$html .= 'getUrl() . '" class="' . $outermostClassCode . ' ' . $_hasChildren . '">' .
$this->escapeHtml($this->
($child->getName())) . '';
}

if (!empty($childrenWrapClass)) {
    $html .= '<div class="' . $childrenWrapClass . '">';
}

$nextChildLevel = $childLevel + 1;

if (!empty($_hasChildren)) {
    $html .= '<ul class="level' . $childLevel . '">';
    $html .= '<li class="level' . $nextChildLevel . '">';
    $html .= '<a class="level' . $nextChildLevel . '" href="' . $child->getUrl() . '">';
    $html .= $this->__('View All ') . $this->escapeHtml($this->__($child->getName()));
    $html .= '</a>';
    $html .= '</li>';
    $html .= $this->render($child, $childrenWrapClass);
    $html .= '</ul>';
}

if (!empty($childrenWrapClass)) {
    $html .= '</div>';
}

$html .= '</li>';

$counter++; }

return $html;

Best Answer

Modified method getCacheKeyInfo in class Mage_Page_Block_Html_Topmenu as below

public function getCacheKeyInfo()
    {
        $shortCacheId = array(
            'TOPMENU',
            Mage::app()->getStore()->getId(),
            (int)Mage::app()->getStore()->isCurrentlySecure(), // newly added line to check if secure or non secure
            Mage::getDesign()->getPackageName(),
            Mage::getDesign()->getTheme('template'),
            Mage::getSingleton('customer/session')->getCustomerGroupId(),
            'template' => $this->getTemplate(),
            'name' => $this->getNameInLayout(),
            $this->getCurrentEntityKey()
        );
        $cacheId = $shortCacheId;

        $shortCacheId = array_values($shortCacheId);
        $shortCacheId = implode('|', $shortCacheId);
        $shortCacheId = md5($shortCacheId);

        $cacheId['entity_key'] = $this->getCurrentEntityKey();
        $cacheId['short_cache_id'] = $shortCacheId;

        return $cacheId;
    }
Related Topic