Создание пользовательской опции при сохранении товара

18

Я работаю над созданием настраиваемой опции для моих продуктов автоматически при каждом создании продукта. Пока у меня есть наблюдатель, который запускает catalog_product_save_beforeсобытие и запускает следующий код:

    //check that we haven't made the option already
    $options = $product->getProductOptions();
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
    $options[] = array(
        'title' => $product->getDateLabel(),
        'type' => 'date_time',
        'is_require' => 1,
        'sort_order' => 0,
        'is_delete' => '',
        'previous_type' => '',
        'previous_group' => '',
        'price' => '0.00',
        'price_type' => 'fixed',
        'sku' => ''
    );
    $product->setProductOptions($options);
    $product->setCanSaveCustomOptions(true);
    //this line doesnt make sense here, but it works ... kinda
    $product->save();

Если я оставляю $product->save()in, я получаю 2 настраиваемые опции, хотя я проверяю, чтобы убедиться, что во 2-й раз, когда событие срабатывает, оператор return вызывается в цикле foreach.

Если я возьму это. Пользовательские параметры не создаются.

Может кто-нибудь сказать мне, что я делаю не так?
Я работаю с Magento 1.7

Джейсон Нейман
источник
Привет, поскольку вы используете событие catalog_product_save_before, вам не нужно вызывать -> save, так как продукт будет сохранен после завершения события. Что произойдет, если вы удалите этот вызов сохранения в своем наблюдателе?
ProxiBlue
Если я удаляю вызов save (), никакие пользовательские опции не создаются.
Джейсон Нейман

Ответы:

12

Пока я не найду точную проблему, вот решение. Вместо этого catalog_product_save_beforeиспользуйте событие catalog_product_prepare_save. Недостатком этого является то, что prepare_saveсобытие отправляется только при сохранении продукта из интерфейса администратора или API. Поэтому, если вы сохраняете из пользовательского кода, он не сработает, если вы не запустите его вручную.

У меня есть догадка, что проблема как-то связана с Mage_Catalog_Model_Product::_beforeSave()методом. Там есть некоторая обработка пользовательских опций.
Но catalog_product_save_beforeотправляется после того, как эта обработка происходит, поэтому, пока обрабатываются пользовательские параметры, Mage_Catalog_Model_Product::_beforeSave()они фактически пусты, потому что событие еще не сработало, поэтому они не добавляются.
Если вы переместите строку parent::_beforeSave();в методе, который я упомянул в верхней части метода, параметры будут добавлены (еще дважды, но они добавлены). Я опубликую больше, когда / если я найду проблему.

[РЕДАКТИРОВАТЬ]
Нашел это. Я был как-то прямо в строках выше.
Как я уже говорил, проблема в том, что catalog_product_save_beforeотправляется после обработки пользовательских параметров. но вот почему это не работает.
Пользовательские параметры сохраняются в Mage_Catalog_Model_Product::_afterSave()этом коде:

$this->getOptionInstance()->setProduct($this)
            ->saveOptions();

Но $this->getOptionInstance()заполняется с опциями, _beforeSaveкогда массив опций пуст в вашем случае. Отсюда ... нечего спасать.
Если вы все еще хотите использовать catalog_product_save_beforeвот код, который должен работать.

//check that we haven't made the option already
$options = $product->getOptions();
if ($options){
    foreach ($options as $option) {
        if ($option['title'] == 'Auto Date & Time' && $option['type'] == 'date_time' && !$option['is_delete']) {
            //we've already added the option
            return;
        }
    }
}
$option = array(
    'title' => 'Auto Date & Time',
    'type' => 'date_time',
    'is_require' => 1,
    'sort_order' => 0,
    'is_delete' => '',
    'previous_type' => '',
    'previous_group' => '',
    'price' => '0.00',
    'price_type' => 'fixed',
    'sku' => ''
);
//don't use it like this because it has no effect
//$product->setProductOptions($options);
$product->setCanSaveCustomOptions(true);
//use it this way. Populate `$product->getOptionInstance()` directly
$product->getOptionInstance()->addOption($option);
//don't forget to state that the product has custom options
$product->setHasOptions(true);
Мариус
источник
Привет @Marus я могу использовать catalog_product_prepare_saveвместо catalog_product_save_beforeи как я могу обновить опцию, если какие-либо изменения требуются.
Захираббас
0

У меня просто была такая же проблема, ответ от Мариус работал отлично. Мне потребовалось некоторое время, чтобы понять, как обновить пользовательский параметр. Зная, что $ product-> getOptionInstance () -> addOption () работает для сохранения параметра, а установка «is_delete» в 1 удаляет параметр сохранения, я пришел к следующему коду:

$oldOptions = $product->getOptionInstance()->getOptions();
foreach ($oldOptions as $key => $option){
    if($option['title'] == "Custom Option Title") {
        $oldOptions[$key]['is_delete'] = 1;                 
        $product->getOptionInstance()->addOption($oldOptions[$key]);
    }
}

После удаления вы можете добавить обновленную пользовательскую опцию с этим кодом:

$newOption = array(
    'title' => "Custom Option Title",
    'type' => 'radio',
    'is_require' => 1,
    'sort_order' => 20,
    'values' => array(
        array(
            'title' => "Value 1 Title",
            'price' => 42.00,
            'price_type' => 'fixed',
            'sku' => "",
            'sort_order' => '1'
        ),
        array(
            'title' => "Value 2 Title",
            'price' => 50,
            'price_type' => 'percent',
            'sku' => "",
            'sort_order' => '2'
        )
    )
);
$product->getOptionInstance()->addOption($newOption);
Андреас Ридмюллер
источник
0

Чтобы создать пользовательский параметр в magento при сохранении продукта, это очень простые шаги.

   $product = Mage::getModel("catalog/product")->load($productid);

    $options[] = array(
            'title' => 'Pet',
            'type' => 'field',
            'is_require' => 0,
            'sort_order' => 0,
        );
    $options[] = array(
            'title' => 'Date',
            'type' => 'field',
            'is_require' => 1,
            'sort_order' => 2,
        );

    $product->setProductOptions(($options));
    $product->setCanSaveCustomOptions(true);
    $product->save();`

Если уже создана пользовательская опция, вы можете удалить ее, используя следующий код

$product = Mage::getModel("catalog/product")->load($productid);

    $customOptions = $product->getOptions();

    foreach ($customOptions as $option) {
        $option->delete();
    }

    $product->setHasOptions(0);
    $product->save();

Благодарность

Mage2Solutions
источник