5

我想从小部件的代码中更改和保存小部件的配置。我正在寻找这样的东西:

class My_Module_Block_Widget
    extends Mage_Catalog_Block_Product_List
    implements Mage_Widget_Block_Interface
{
    // ...
    protected function _beforeToHtml()
    {
        // ...
        if(/* data needs to be changed */)
        {
            // assuming "widget_config_data" to be one of the widget's
            // parameters configured in the etc/widget.xml file of my module
            $this->setData("widget_config_data", "New Data");
            $this->save();
        }
        // ...
    }
    // ...
}

由于小部件不是模型,因此它们没有 save() 方法。那么如何保存我的小部件的更改数据?

4

1 回答 1

11

这将是棘手的,并且可能更多地涉及单个堆栈溢出问题。这里有一些背景可以帮助您入门。您在上面处理的类/对象是一个块类。块用于呈现 HTML。正如您所指出的,它们是无国籍的。

该块从小部件实例模型对象中获取其数据。

Mage::getModel('widget/widget_instance');
Mage_Widget_Model_Widget_Instance

这些对象的状态(您尝试更改的数据)位于表中widget_instance

问题是,块对象对小部件实例对象一无所知。小部件通过存储在数据库中的特殊布局句柄插入到页面布局中(这是一种过度简化,因为您可以在布局系统上写一本书)。您的实例小部件显示在页面上的原因是因为页面布局已经更新了类似这样的信息

<reference name="content">
    <block type="cms/widget_page_link" name="48fc761f38fa9838fcc3a3b498c47f72" template="cms/widget/link/link_block.phtml">
        <action method="setData">
            <name>anchor_text</name>
            <value>asdfasdfsad</value>
        </action>
        <action method="setData">
            <name>title</name>
            <value>asdfasdfasdfasd</value>
        </action>
        <action method="setData">
            <name>page_id</name>
            <value>2</value>
        </action>
    </block>
</reference>

没有对小部件实例 ID 的引用,这意味着您无法加载实例对象。

理论上,您可以尝试根据参数值加载小部件实例,因为它们存储在数据库中。但是,它们存储在widget_paramater列中,是一个序列化的字符串。这意味着您不能使用 SQL 或模型过滤器来查询它。您必须加载特定实例类型/主题/存储的所有小部件实例,然后手动foreach完成,直到找到正确的对象。这对于少量的小部件可能是有效的,但对于大量的小部件来说很快就会变得无效。此外,这不能保证有效,因为您的小部件参数的值可能已被其他布局更新代码更改(尽管不太可能)。

更好(也更耗时)的方法是重写小部件插入代码,使其在布局更新 XML 中包含页面 id。这会将实例 ID 传递给小部件块代码,允许您实例化小部件实例对象并保存它。您还可以将字段添加到其自定义类将始终保存实例 ID 的小部件。

祝你好运!

于 2012-05-22T17:05:04.820 回答