Criando opção personalizada ao salvar o produto

18

Estou trabalhando para criar uma opção personalizada para meus produtos automaticamente sempre que um produto for criado. O que eu tenho até agora é um observador que dispara no catalog_product_save_beforeevento e executa o seguinte código:

    //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();

Se eu deixar o $product->save()in, termino com duas opções personalizadas sendo criadas, mesmo que eu tenha verificado se a segunda vez que o evento dispara, a declaração de retorno é chamada no loop foreach.

Se eu tirar. Nenhuma opção personalizada é criada.

Alguém pode me dizer o que estou fazendo de errado?
Eu estou trabalhando com Magento 1.7

Jason Neumann
fonte
Olá, como você está usando o evento catalog_product_save_before, não seria necessário chamar o -> save, pois o produto será salvo após o término do evento. O que acontece se você remover a chamada salva no seu observador?
ProxiBlue
Se eu remover a chamada para save (), nenhuma opção personalizada será criada.
Jason Neumann

Respostas:

12

Até encontrar o problema exato, aqui está a solução. Em vez disso, catalog_product_save_beforeuse o evento catalog_product_prepare_save. A desvantagem disso é que o prepare_saveevento é despachado apenas ao salvar um produto da interface administrativa ou da API. Portanto, se você estiver salvando de um código personalizado, isso não será acionado, a menos que você seja acionado manualmente.

Eu tenho um palpite de que o problema tem algo a ver com o Mage_Catalog_Model_Product::_beforeSave()método. Existe algum processamento das opções personalizadas.
Mas catalog_product_save_beforeé despachado depois que esse processamento ocorre, portanto, enquanto as opções personalizadas são processadas, Mage_Catalog_Model_Product::_beforeSave()elas estão realmente vazias porque o evento ainda não foi acionado e, portanto, não foram adicionadas.
Se você mover a linha parent::_beforeSave();no método que mencionei na parte superior do método, as opções serão adicionadas (ainda duas vezes, mas são adicionadas). Vou postar mais quando / se encontrar o problema.

[EDIT]
Encontrei. De alguma forma, eu estava certo nas falas acima.
Como eu disse, o problema é que catalog_product_save_beforeé despachado após o processamento das opções personalizadas. mas é por isso que não funciona.
As opções personalizadas são salvas Mage_Catalog_Model_Product::_afterSave()neste código:

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

Mas $this->getOptionInstance()é preenchido com opções _beforeSavequando a matriz de opções está vazia no seu caso. Portanto ... nada para salvar.
Se você ainda deseja usar, catalog_product_save_beforeaqui está o código que deve funcionar.

//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);
Marius
fonte
Olá @Marius, posso usar em catalog_product_prepare_savevez de catalog_product_save_beforee como posso atualizar a opção, se houver alguma alteração necessária.
Zaheerabbas
0

Eu apenas tive o mesmo problema, a resposta de marius funcionou muito bem. Levei algum tempo para descobrir como atualizar uma opção personalizada. Com o conhecimento de que $ product-> getOptionInstance () -> addOption () trabalha para salvar uma opção, e definir "is_delete" como 1 remove uma opção para salvar, vim com esse código:

$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]);
    }
}

Após a exclusão, você pode adicionar sua opção personalizada atualizada com este código:

$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);
Andreas Riedmüller
fonte
0

Para criar uma opção personalizada no magento ao salvar o produto, essas são etapas muito fáceis.

   $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();`

Se já houver uma opção personalizada criada, você poderá excluí-la seguindo o código

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

    $customOptions = $product->getOptions();

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

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

obrigado

Mage2Solutions
fonte