Magento 1.9.2.0静态块显示问题


77

我的网站上有多个在1.9.1.0中工作的静态块,但是在1.9.2.0中,静态块开始偶尔显示,因为它们有时显示错误的块而不是正确的块。有时它们会根据需要显示。有谁知道如何解决可能与此问题相关的问题


这听起来不可复制且疯狂。如果您有更好的解释,我们可能会为您提供帮助,但是对不起,我看不到任何办法。
Fabian Blechschmidt 2015年

2
我可以确认这一点。在一家商店遇到它。2个块之间的缓存密钥相同
Sander Mangel


9
根据Piotr的说法,现在这是一个已确认的错误,Magento核心团队正在研究该错误。
Benmarks 2015年

1
该错误在1.9.2.4中仍然明显。在脚本跟踪器注释中添加了场景/细节。
zigojacko

Answers:


61

我在EE 1.14.2中遇到了这个问题,看来在CE 1.9.2中也出现了同样的问题。我记录了有关此SE问题的问题和解决方案。

基本上是由于以下代码被添加到的构造函数中Mage_Cms_Block_Block

$this->setCacheTags(array(Mage_Cms_Model_Block::CACHE_TAG));
$this->setCacheLifetime(false);

CMS静态块现在已缓存。问题来自于如何生成缓存键信息。可以归结为Mage_Core_Block_Abstract在布局中使用块名称的行为。如果未在布局中添加块(例如在cms页面上),则此名称不存在。这可能导致静态块共享相同的缓存密钥并在缓存中混淆。

我的解决方案是覆盖Mage_Cms_Block_Block该类,并根据块ID和当前存储设置缓存键信息。

/**
 * Override cms/block to add cache key. This started being a problem as of EE 1.14.2 and CE 1.9.2 when the _construct
 * method was added which turns on caching for cms blocks
 */
class Mysite_Cms_Block_Block extends Mage_Cms_Block_Block
{

    /**
     * If this block has a block id, use that as the cache key.
     *
     * @return array
     */
    public function getCacheKeyInfo()
    {
        if ($this->getBlockId()) {
            return array(
                Mage_Cms_Model_Block::CACHE_TAG,
                Mage::app()->getStore()->getId(),
                $this->getBlockId(),
                (int) Mage::app()->getStore()->isCurrentlySecure()
            );
        } else {
            return parent::getCacheKeyInfo();
        }
    }
}

显然,这需要使用config.xml文件和块替代等添加到您自己的模块中。或者,您可以将其复制Mage_Cms_Block_Block到本地代码池并在其中添加缓存键。

您可以在此处查看 1.9.2中添加的新行


您如何实例化这些静态块?如果通过布局xml进行操作,则可以向块添加唯一的名称,并且可以很好地进行缓存。在哪种情况下,您不会给块命名(可能是小部件?)
Erfan 2015年

1
@Erfan当将块添加到{{block type =“ cms / block” block_id =“ block_id”}}这样的CMS页面时,或者直接在模板中加载静态块时,就会发生此问题
Andrew Kett

6
这是这个奇怪问题的免费扩展。希望它将使所有面对这个问题的人受益。github.com/progammer-rkt/Rkt_SbCache
Rajeev K Tomy

@Rajeev它与哪个版本的Magento兼容?在Mage 1.6.x中也可以正常工作吗?
zitix

1
我根据安德鲁凯特的回答为临时解决方案创建了要点。只需将此app / code / local / Mage / Cms / Block / Block.php添加到您的Magento目录中,即可解决问题。只需记住在执行下一个Magento更新之前删除文件(假设它们在下一个更新中包含了此修复程序)。
Jay El-Kaake

13

我刚刚升级到1.9.2.0,也遇到了这种情况。设置为显示“静态块+产品”的类别随机显示错误的“静态块”。在我的1.9.2.0升级之前,这不存在。

临时修复禁用“块” HTML输出缓存,并且正确显示了块。


我也在首页和产品页面中都
遇到

这项工作目前
2015年

是的,这就是我现在所做的。
谢里夫

13

这里我们使用基于本地模块的解决方案,因为上述解决方案没有提供完整的步骤。我们需要创建自定义模块,因为大家都知道Magento Boogieman会帮到您!如果改变核心:)

您将需要以下文件: 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;
   }
}

有关更多信息,您可以访问以下链接,也可以从 以下链接下载https://www.milople.com/blogs/ecommerce/solved-magento-static-block-display-issue.html


设置模块并没有帮助-我的问题是分配给类别的CMS块消失了,它们根本不显示。
Haim

@Haim,如果您使用的是1.9.2.2,则需要进入该特定块的System-> permission-> cms块
Bhupendra Jadeja

我正在使用Magento ver。1.9.2.0-但是我的问题还是稍有不同,我将CMS块设置为显示在类别页面上,而CMS块只是不显示-如果我刷新它显示的缓存,直到下次消失为止
Haim

我建议您更新我认为已经存在的magento版本。
彭德拉·贾德贾

7

没有官方的补丁程序,但是,它已在CE 1.9.2.1中解决。

diff -r magento-CE-1.9.2.0/app/code/core/Mage/Cms/Block/Block.php magento-CE-1.9.2.1/app/code/core/Mage/Cms/Block/Block.php
74a75,94
> 
>     /**
>      * Retrieve values of properties that unambiguously identify unique content
>      *
>      * @return array
>      */
>     public function getCacheKeyInfo()
>     {
>         $blockId = $this->getBlockId();
>         if ($blockId) {
>             $result = array(
>                 'CMS_BLOCK',
>                 $blockId,
>                 Mage::app()->getStore()->getCode(),
>             );
>         } else {
>             $result = parent::getCacheKeyInfo();
>         }
>         return $result;
>     }
diff -r magento-CE-1.9.2.0/app/code/core/Mage/Cms/Block/Widget/Block.php magento-CE-1.9.2.1/app/code/core/Mage/Cms/Block/Widget/Block.php
84a85
>                 $this->addModelTags($block);
90a92,106
> 
>     /**
>      * 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;
>     }

注意:据报道,多个商店视图上的CMS页面仍然存在问题:

Magento CE 1.9.2.1仅部分修复了此问题。

对于多个商店视图上的CMS页面,问题仍然存在。这是一个更新的修补程序(请注意,这不是官方补丁):https : //gist.github.com/tux-rampage/77b286f7973336877f7b#file-luka-mce20150805-1-9-2-1-caching-hotfix-patch

来源:http//www.magentocommerce.com/products/bug-tracking/issue/index/id/870



4

我也可以确认这个问题。

复制:

  1. 使用CMS -> Widgets,创建一个小部件以将静态块添加到左侧边栏中。

  2. 然后创建第二个小部件,以将第二个静态块(与中的块不同step 1)添加到左侧边栏中。

  3. 如果禁用了缓存,则两个静态块都将正确显示在侧栏中。

  4. 但是,如果启用缓存,您将看到静态块step 1 显示两次。


嗨,Zitix,我面临着同样的问题,就像你能告诉我如何解决这个问题
Jaimin


3

将Magento升级到1.9.2.1

我做到了,并为“ Blocks HTML”输出启用了缓存,它似乎已修复。

新版本还解决了一些安全问题。


3

在最新版本的Magento中,它通过新的安全功能进行了增强。您可以在system-> permissions中为静态块添加权限。


2
在magento 1.9.2.0中,在缓存静态块时出现问题,您正在谈论的是不同的东西。
2015年

不错,我不知道此功能
amit_game

我喜欢这个。:)
zed Blackbeard

2

我的商店也遇到了同样的问题。到目前为止,我发现的最佳解决方法是为受影响的块停用缓存。您可以通过将块的缓存生存期设置为null来实现。

全局禁用实时站点上的“阻止HTML输出”缓存不是一个好主意,因为它不必要地影响站点性能。

为xml中的一个块禁用缓存:

<block ... >
    ...
    <action method="unsetData"><key>cache_lifetime</key></action>
    <action method="unsetData"><key>cache_tags</key></action>
</block>

在php中为一个块禁用缓存:

$this->getLayout()->createBlock('cms/block')
    ->setCacheLifetime(null)
    ->setBlockId('block-id')
    ->toHtml();

请勿将本文指出的缓存生存期设置为“ 0”


安德烈亚斯(Andreas)-我很好奇,使用那篇文章中描述的技术会产生什么影响?您在此处提供的两种选择如何避免您概述的负面影响?
Bryan'BJ'Hoffpauir Jr.'Jul

1
第一种方法行不通,因为magento将把布局更新解释为像此$block->setCacheLifeTime("null");Note NULL 和“ null”是两个不同的事物(后一个是字符串),因此将无法获得预期的结果。
Rajeev K Tomy 2015年

1
@BJ Hoffpauir:如果激活了cms / block块的缓存,则相同的缓存的cms / block将用于所有商店视图。如果您具有同一块标识符的英语(商店视图)和德语(商店视图)版本,则两种商店视图都将使用英语或德语。禁用此块的缓存可以解决此问题。如果仍然要缓存该块,可以通过将其放入另一个块并缓存该块来实现。
AndreasRiedmüller'15

1
@Rajeev谢谢,我在几篇文章中都找到了这种方法,但是我很确定你是对的。我更改了禁用xml中的缓存的方法。以前的方法在这里是一个公认的答案,但:stackoverflow.com/questions/27684236/...
安德烈亚斯Riedmüller

2

我可以通过更新Magento Connection Manager中的现有扩展程序来解决此问题。仔细研究之后,我觉得该问题存在于Magento缓存系统中。

默认情况下,Magento有几个与其缓存技术相关的软件包。它们包括Zend和Redis的适配器和库。

我没有尝试找到合适的软件包,而是选择更新安装中的所有软件包。

然后,我选择了以下标记:Mage_All_Latest,这是用于最新稳定的Magento 1.9.0.0版本的Metapackage。

通过仅升级正确的软件包,可以解决此问题。我觉得这是更好的方法,因为我怀疑这种方法也会应用安全补丁。


1

您将必须进行完全升级或回传1.9.2.0

1.9.2.1中的CMS Block和Widget缓存更改

magento-1921 / app / code / core / Mage / Cms / Block / Block.php

diff -r magento-1920/app/code/core/Mage/Cms/Block/Block.php magento-1921/app/code/core/Mage/Cms/Block/Block.php
74a75,94
> 
>     /**
>      * Retrieve values of properties that unambiguously identify unique content
>      *
>      * @return array
>      */
>     public function getCacheKeyInfo()
>     {
>         $blockId = $this->getBlockId();
>         if ($blockId) {
>             $result = array(
>                 'CMS_BLOCK',
>                 $blockId,
>                 Mage::app()->getStore()->getCode(),
>             );
>         } else {
>             $result = parent::getCacheKeyInfo();
>         }
>         return $result;
>     }

magento-1921 / app / code / core / Mage / Cms / Block / Widget / Block.php

diff -r magento-1920/app/code/core/Mage/Cms/Block/Widget/Block.php magento-1921/app/code/core/Mage/Cms/Block/Widget/Block.php
84a85
>                 $this->addModelTags($block);
89a91,105
>     }
> 
>     /**
>      * 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;

0

我正在使用Magento 1.9.3.8,问题仍然存在。

您可以在这里找到我的解决方法:

基本上,我将基于页面url和blockId的唯一字符串添加到每个缓存键信息,因此每个块将具有唯一键:

 /**
 * Generates a string based on the page url (for example category/product pages) and concatenate the block id to the url
 * Removes the caracters: /, . , &, = and , from this string
 */
private function generateUrlBasedString($blockId = null)
{
    $currentUrl = Mage::helper('core/url')->getCurrentUrl();
    $url = Mage::getSingleton('core/url')->parseUrl($currentUrl);
    $path = '_' . $url->getPath();

    $path = str_replace('/', '', $path);
    $path = str_replace('.', '', $path);
    $path = str_replace('&', '', $path);
    $path = str_replace(',', '', $path);
    $path = str_replace('=', '', $path);

    if(isset($blockId)) {
        $path .= '_' . $blockId;
    }

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

在Magento为该问题准备修复程序之前,您可以创建以下文件:

应用程序/代码/本地/法师/厘米/块/Block.php

并插入上述github网址中的代码作为内容。

此代码已针对Magento 1.9.2。*和1.9.3。*进行了测试


-1

这已在1.9.2版本中确认为错误,暂时您可以通过从管理员->缓存管理部分禁用“阻止HTML输出”缓存来解决此问题。

希望能帮助到你


studio2f提到了答案,您可以使用@andrewkett或在主要问题中单击“此问题”,这也会对您有所帮助
wk

2
我要说的是,禁用所有块缓存来解决仅在某些特定块上才表现出来的问题,就像在手指上冻伤时会砍断一只手。砍下手指,虽然也很不愉快,但至少会更适当地应对这种疾病。Andrewkett的(magento.stackexchange.com/users/527/andrewkett)的答案是一个比较合理的做法:magento.stackexchange.com/questions/73685/...
布莱恩'BJ' Hoffpauir小

切勿编辑或更改CORE类。
Ahsan Horani
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.