Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在观测器中停止产品保存过程_Php_Magento_Save_Observer Pattern_Abort - Fatal编程技术网

Php 在观测器中停止产品保存过程

Php 在观测器中停止产品保存过程,php,magento,save,observer-pattern,abort,Php,Magento,Save,Observer Pattern,Abort,我目前正在开发一个在后端使用产品编辑的模块。 其目的是检索产品所属的类别,并使用选定类别的列表填充属性(品牌属性) 管理员必须至少选择一个类别。 我的模块按预期工作,但如果管理员在编辑产品时未选择任何类别,我不知道如何停止保存过程 这是工作流程 管理员在“产品编辑”页面的“类别”选项卡中选择类别 管理员点击“保存” 我的模块“观察”并收集所有类别 -->如果有选定的类别 我的模块的观察者做了一些事情来更新品牌属性 -->否则 我的模块的观察者向管理会话添加了一个错误 我的模块观察员应该

我目前正在开发一个在后端使用产品编辑的模块。 其目的是检索产品所属的类别,并使用选定类别的列表填充属性(品牌属性)

管理员必须至少选择一个类别。

我的模块按预期工作,但如果管理员在编辑产品时未选择任何类别,我不知道如何停止保存过程

这是工作流程

  • 管理员在“产品编辑”页面的“类别”选项卡中选择类别
  • 管理员点击“保存”
  • 我的模块“观察”并收集所有类别
-->如果有选定的类别

  • 我的模块的观察者做了一些事情来更新品牌属性
-->否则

  • 我的模块的观察者向管理会话添加了一个错误
  • 我的模块观察员应该告诉Magento停止保存产品。但是我该怎么做呢
一般的问题可能是:如何将“停止-保存”参数传递给观察者

下面是我的config.xml文件的一个示例,以及处理上述工作流的方法

非常感谢你的帮助,祝你玩得开心

config.xml

    <catalog_product_prepare_save>
        <observers>
            <brands_product_save_observer>
                <type>singleton</type>
                <class>brands/observer</class>
                <method>saveProductBrand</method>
            </brands_product_save_observer>
        </observers>
    </catalog_product_prepare_save>

我不认为你可以通过观察者以你想要的方式停止执行,Magento不会注意你可能通过观察者返回或设置的任何内容

一个想法是重写产品模型的save方法。您可以检查在观察者中设置的任何错误标志,然后从该点阻止保存。大概是这样的:

function save()
{
    if( $error_detection )
    {
        return $this;
    }
    else
    {
        return parent::save();
    }
}

关于Magento的哪些部分支持这一点总是一个废话,但是抛出异常通常是告诉Magento出了问题的规定方式。堆栈上层的层被设置为捕捉这些异常,并使用它们返回表单并显示错误消息。试试这个

Mage::throwException(Mage::helper('adminhtml')->__('You totally failed at that.'));
如果您看一下
Adminhtml
模块的
目录/ProductController.php
(1.5,但在以前的版本中我会采用类似的格式)

\u initProductSave
方法是触发
catalog\u product\u prepare\u save
事件的位置。由于这在
saveAction
的try/catch块之外,因此不会捕获异常(如下面的注释所述)


您需要将验证代码移动到产品模型的“保存前”事件中(
catalog\u product\u save\u before
)。这样做应该可以让您抛出一个异常,让管理员显示错误消息并表示要编辑的表单

一些想法。您真的想停止保存,还是“撤消”更改就足够了?如果您的观察者检测到缺少所需的信息,则只需迭代更改的数据并将其设置回原始数据,然后继续保存。您应该能够执行
$product->getOrigData()
来比较哪些更改了

或者,为什么不强制使用category属性呢?您应该能够在您的配置xml中实现这一点(不完全确定我的想法有多离谱)

最后,您可以绑定到
controller\u action\u predispatch\u catalog\u product\u save
事件,如果检测到错误状态,请设置
no dispatch
标志,将错误消息添加到会话并重定向referer。查看我先前的答案了解详细信息

============================

我找到了一条新路。在观察者中,将对象上的
\u dataSaveAllowed
值更改为
false
Mage\u Core\u Model\u Abstract::save()
在继续保存之前检查该值

HTH,

JD

一种可能的方法也可以是这种方法——尽管这是一种黑客攻击


Mage::app()->getRequest()->setPost(“您的_键”,false)

如果需要阻止对核心模型(即目录/产品)执行保存方法,可以使用反射将“$\u dataSaveAllowed”设置为false:

public function catalogProductSaveBefore($observer)
{
    try {
        $product = $observer->getProduct();

        $reflectionClass = new ReflectionClass('Mage_Catalog_Model_Product');
        $reflectionProperty = $reflectionClass->getProperty('_dataSaveAllowed');
        $reflectionProperty->setAccessible(true);
        $reflectionProperty->setValue($product, false);
    } catch (Exception $e) {
            Mage::log($e->getMessage());
    }

    return $this;
}

我会非常小心重写产品模型。。。许多自定义模块重写了该模型,结果导致了大量冲突。尽可能避免!是的,这是一个很好的观点。这只是我想到的第一个想法,因为我不认为Magento会在这种情况下捕获抛出的异常。虽然我可能错了。我也同意,不会走这条路:)绝对值得一试。我查看了Mage_Catalog_Model_产品、其父类和相关资源类的
\u beforeSave()
方法,但在继续保存之前,它们没有检查任何异常:(伙计们,我尝试了,结果“失败”因为它会在一个漂亮的错误报告页面上抛出异常,而不是在产品编辑页面上重新加载“You All failed”消息。非常感谢。我会继续挖掘,并让你知道我是否成功!@vrnet我进一步研究了这个问题,并用更多信息更新了答案。如果你在活动前将验证移至目录“产品”保存“你应该被设置。vrnet::getHappiness('applauses')->thankAlanTonsOfTimes()-这太棒了!非常感谢!nano唯一的缺点是在重新加载时不会保留产品版本中的数据。管理员必须重新键入所有信息…他/她会小心下一个产品:)再次感谢。@vrnet保留您可以调用的数据
Mage::getSingleton('adminhtml/session')->set[MODULE]data($this->getData())$form->setValues(Mage::getSingleton('adminhtml/session')->get[MODULE]Data())
在Form.phpHey Jonathan中的
\u prepareForm
函数的末尾-非常感谢,但Magento似乎并不关心no分派。我已经甩了M
function saveAction()
{
    ...
    $product = $this->_initProductSave();

    try {
        $product->save();
        $productId = $product->getId();
    ...
}
public function catalogProductSaveBefore($observer)
{
    try {
        $product = $observer->getProduct();

        $reflectionClass = new ReflectionClass('Mage_Catalog_Model_Product');
        $reflectionProperty = $reflectionClass->getProperty('_dataSaveAllowed');
        $reflectionProperty->setAccessible(true);
        $reflectionProperty->setValue($product, false);
    } catch (Exception $e) {
            Mage::log($e->getMessage());
    }

    return $this;
}