Création d'une option personnalisée lors de l'enregistrement du produit

18

Je travaille sur la création automatique d'une option personnalisée pour mes produits chaque fois qu'un produit est créé. Ce que j'ai jusqu'à présent, c'est un observateur qui se déclenche sur l' catalog_product_save_beforeévénement et exécute le code suivant:

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

Si je laisse l' $product->save()entrée, je termine avec la création de 2 options personnalisées, même si j'ai vérifié pour vérifier la deuxième fois que l'événement se déclenche, l'instruction de retour est appelée dans la boucle foreach.

Si je le retire. Aucune option personnalisée n'est créée.

Quelqu'un peut-il me dire ce que je fais mal?
Je travaille avec Magento 1.7

Jason Neumann
la source
Bonjour, puisque vous utilisez l'événement catalog_product_save_before, vous n'avez pas besoin d'appeler le -> save, car le produit sera sauvegardé une fois l'événement terminé. Que se passe-t-il si vous supprimez cet appel de sauvegarde dans votre observateur?
ProxiBlue
Si je supprime l'appel à save (), aucune option personnalisée n'est créée.
Jason Neumann

Réponses:

12

Jusqu'à ce que je trouve le problème exact, voici la solution. catalog_product_save_beforeUtilisez plutôt l'événement catalog_product_prepare_save. L'inconvénient est que l' prepare_saveévénement n'est distribué que lors de l'enregistrement d'un produit à partir de l'interface d'administration ou de l'API. Donc, si vous enregistrez à partir d'un code personnalisé, cela ne se déclenchera que si vous le déclenchez manuellement.

J'ai le pressentiment que le problème a quelque chose à voir avec la Mage_Catalog_Model_Product::_beforeSave()méthode. Il y a un certain traitement des options personnalisées.
Mais catalog_product_save_beforeest distribué après que ce traitement se soit produit. Ainsi, bien que les options personnalisées soient traitées, Mage_Catalog_Model_Product::_beforeSave()elles sont en fait vides car l'événement ne s'est pas encore déclenché et ne sont donc pas ajoutées.
Si vous déplacez la ligne parent::_beforeSave();dans la méthode que j'ai mentionnée en haut de la méthode, les options sont ajoutées (toujours deux fois, mais elles sont ajoutées). Je posterai plus quand / si je trouve le problème.

[EDIT] Je l'ai
trouvé. J'avais en quelque sorte raison dans les lignes ci-dessus.
Comme je l'ai dit, le problème est qu'il catalog_product_save_beforeest distribué après le traitement des options personnalisées. mais c'est pourquoi cela ne fonctionne pas.
Les options personnalisées sont enregistrées dans Mage_Catalog_Model_Product::_afterSave()ce code:

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

Mais $this->getOptionInstance()est rempli d'options _beforeSavelorsque le tableau d'options est vide dans votre cas. Par conséquent ... rien à sauver.
Si vous souhaitez toujours utiliser le catalog_product_save_beforevoici le code qui devrait fonctionner.

//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
la source
Bonjour @Marius puis-je utiliser à la catalog_product_prepare_saveplace de catalog_product_save_beforeet comment puis-je mettre à jour l'option si des modifications sont nécessaires.
Zaheerabbas
0

J'ai juste eu le même problème, la réponse de marius a très bien fonctionné. Il m'a cependant fallu un certain temps pour comprendre comment mettre à jour une option personnalisée. Sachant que $ product-> getOptionInstance () -> addOption () fonctionne pour enregistrer une option, et définir "is_delete" sur 1 supprime une option lors de l'enregistrement, j'ai trouvé ce code:

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

Après la suppression, vous pouvez ajouter votre option personnalisée mise à jour avec ce code:

$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
la source
0

Pour créer une option personnalisée dans magento tout en enregistrant le produit, ce sont des étapes très faciles.

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

Si une option personnalisée est déjà créée, vous pouvez la supprimer en suivant le code

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

    $customOptions = $product->getOptions();

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

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

Merci

Mage2Solutions
la source