4

私は現在、バックエンドで製品編集を行うモジュールを開発しています。その目的は、製品が属するカテゴリを取得し、選択したカテゴリのリストを属性 (ブランド属性) に入力することです。

管理者は少なくとも 1 つのカテゴリを選択する必要があります。

製品の編集中に管理者がカテゴリを選択していない場合に保存プロセスを停止する方法がわからないことを除いて、私のモジュールは期待どおりに動作します。

ワークフローはこちら

  • 管理者は、商品編集ページのカテゴリ タブでカテゴリを選択します
  • 管理者は「保存」をクリックします
  • 私のモジュールは「観察」し、すべてのカテゴリを収集します

--> カテゴリが選択されている場合

  • 私のモジュールのオブザーバーは、ブランド属性を更新するためにその作業を行います

--> そうでなければ

  • モジュールのオブザーバーが管理者セッションにエラーを追加します
  • モジュールのオブザーバーは、Magento に製品の保存を停止するように指示する必要があります。しかし、どうすればいいですか?

一般的な質問は、「保存を停止する」引数をオブザーバーに渡す方法ですか?

上記で説明したワークフローを処理する config.xml ファイルとメソッドのサンプルを次に示します。

ご協力ありがとうございました。Magentoing をお楽しみください。

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>

Observer.php

public function saveProductBrand($observer) {
    $product = $observer->getProduct();
    $categoryIds = $product->getCategoryIds();
    if (isset($categoryIds)) {
        foreach ($categoryIds as $categoryId) {
            $isBrandCategory = Mage::getModel('brands/navigation')->isBrandCategory($categoryId);
            if ($isBrandCategory)
                $brandCategories[] = $categoryId;
        }
        if (isset($brandCategories)) {
            $brandId = Mage::getModel('brands/navigation')->getBrand($brandCategories[0]);
            if ($brandId) {
                $attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 140);
                foreach ($attribute->getSource()->getAllOptions(true, true) as $option) {
                    $attributeArray[$option['label']] = $option['value'];
                }
                $categoryName = Mage::getModel('catalog/category')->load($brandId)->getName();
                $product->setData('brand', $attributeArray[$categoryName]);
            }
        } else {
            Mage::getSingleton('adminhtml/session')->addError(Mage::helper('catalog')->__('Please add this product to a brand in the "Categories" tab.'));

            HERE SOME CODE TO TELL MAGENTO TO STOP SAVING THE PRODUCT

            return;
        }
    }
}
4

5 に答える 5

15

Magento のどのセクションがこれをサポートしているかについては、常にくだらない問題ですが、例外をスローすることは、Magento に何か問題が発生したことを伝えるための規定の方法であることがよくあります。スタックの上位にあるレイヤーは、これらの例外をキャッチし、それらを使用してフォームに戻り、エラー メッセージを表示するように設定されています。これを試してみてください

Mage::throwException(Mage::helper('adminhtml')->__('You totally failed at that.'));

AdminhtmlモジュールCatalog/ProductController.php(1.5、ただし、以前のバージョンでは同様の形式を想定しています) を見ると、

function saveAction()
{
    ...
    $product = $this->_initProductSave();

    try {
        $product->save();
        $productId = $product->getId();
    ...
}

_initProductSaveメソッドは、catalog_product_prepare_saveイベントが発生する場所です。これは の try/catch ブロックの外側にあるためsaveAction、例外はキャッチされません (以下のコメントで説明されているように)。

検証コードを製品モデルの before save イベント ( ) に移動する必要がありますcatalog_product_save_before。これを行うと、例外がスローされ、管理者にエラー メッセージが表示され、編集用のフォームが表示されます。

于 2011-03-24T22:03:13.780 に答える
2

いくつかの考え。実際に保存を停止しますか、それとも変更を「元に戻す」だけで十分ですか? オブザーバーが必要な情報が欠落していることを検出した場合は、変更されたデータを反復処理して元のデータに戻し、保存を続行できるようにします。$product->getOrigData()どちらが変更されたかを比較することができるはずですか?

または、カテゴリ属性を必須にしないのはなぜですか? あなたはあなたのconfig xmlでそれを行うことができるはずです(私の頭の上からどのように正確にわからない)

最後に、代わりに Event にバインドしcontroller_action_predispatch_catalog_product_save、エラー状態を検出した場合はno-dispatchフラグを設定し、エラー メッセージをセッションに追加して、redirectReferrer をリダイレクトすることができます。詳細については、こちらの以前の回答をご覧ください。

=========編集=========

新しい方法を見つけました。Observer で_dataSaveAllowed、オブジェクトの値を に変更しますfalseMage_Core_Model_Abstract::save()保存を続行する前にその値をチェックします。

HTH、
JD

于 2011-03-25T01:46:23.727 に答える
1

コア モデル (つまり、カタログ/製品) に対して保存メソッドが実行されないようにする必要がある場合は、リフレクションを使用して "$_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;
}
于 2016-06-24T16:34:47.783 に答える
0

オブザーバーを介して実行を停止できるとは思いません。Magento は、オブザーバーを介して返されたり設定されたりする可能性のあるものには注意を払いません。

製品モデルの保存方法を書き直すのも一案でしょう。オブザーバーで設定したエラー フラグを確認し、その時点からの保存を防ぐことができます。このようなもの:

function save()
{
    if( $error_detection )
    {
        return $this;
    }
    else
    {
        return parent::save();
    }
}
于 2011-03-24T21:45:24.110 に答える
0

考えられるアプローチの1つは、これも可能です-これはハックですが

Mage::app()->getRequest()->setPost("YOUR_KEY",false);

于 2013-03-06T18:17:57.927 に答える