Jump to content

Recursion in actionProductSave hook


talbet

Recommended Posts

Hi,

 

I was hoping someone might be able to help. I am trying to update a product using the actionProductSave hook, for a module that does additional validation to products when they are saved.

 

At the moment I am just trying to read values from the product, change them and save the changes back to the database. However, since $product->save() calls actionProductSave, the module creates a recursive loop. Has anyone found a way to update a product from inside the actionProductSave hook?

public function hookActionProductSave()
{
  $id = Tools::getValue('id_product');
  $product = new Product($id);

  //Arbitrary change to product for testing pruposes
  $product->wholesale_price = (float)20.000001;
  $product->price = (float)55.000001;

  //The save method invokes the hook again, resulting in recursion
  $product->save();
}

Link to comment
Share on other sites

 

Hi,

 

I was hoping someone might be able to help. I am trying to update a product using the actionProductSave hook, for a module that does additional validation to products when they are saved.

 

At the moment I am just trying to read values from the product, change them and save the changes back to the database. However, since $product->save() calls actionProductSave, the module creates a recursive loop. Has anyone found a way to update a product from inside the actionProductSave hook?

public function hookActionProductSave()
{
  $id = Tools::getValue('id_product');
  $product = new Product($id);

  //Arbitrary change to product for testing pruposes
  $product->wholesale_price = (float)20.000001;
  $product->price = (float)55.000001;

  //The save method invokes the hook again, resulting in recursion
  $product->save();
}

as i see, its look like makes endless loop where $porduct->save() will trigger the hook to run.

consider to use prestashop configuration to store the wholesale_price price and the other additional things you need instead of using $porduct->save() inside of hookActionProductSave.

 

it may look like :

public function hookActionProductSave()

{

$id = Tools::getValue('id_product');

 

//Arbitrary change to product for testing pruposes

Configuration::updateValue('wholesale_price'.$id,(float)20.000001)

//$product->price = (float)55.000001; i think its not necessary, prestashop has the default storage for product price

 

}

 

Hope this help.

Edited by AgusN (see edit history)
Link to comment
Share on other sites

Thanks AgusN,

 

I see what you mean about storing values in the configuration table, but in this case I actually need to save the values back to the product object so that any changes are reflected in the fontend, without having to rewrite the product display templates.

 

You did give me an idea that solves my problem though which is to store a boolean in the config table and skip the validation and saving to break out of the loop like so

public function hookActionProductSave()
{
  //Check to see if we should break the ProductSave loop
  if (0 == Configuration::get('MOD_AUTO_ATTRIBUTE_SKIP')){

    $id = Tools::getValue('id_product');
    $product = new Product($id);
    $product->wholesale_price = (float)20.000001;
    $product->price = (float)50.000001;

    Configuration::updateValue('MOD_AUTO_ATTRIBUTE_SKIP', (int)1 );
    $product->save();
  }

  // Reset the ProductSaveLoop
  Configuration::updateValue('MOD_AUTO_ATTRIBUTE_SKIP', (int)0 );
} 

It would be great to know if anyone else has run into this and if there is a better way to do this. This is the first Prestashop project I have worked on. 

Edited by talbet (see edit history)
Link to comment
Share on other sites

  • 2 years later...

Up with a solution on ps 1.6, to avoid infinite loop recursion on actionProductSave calling Product->save() (for example) :

 

/modules/mymodule/mymodule.php

class MyModule extends Module
{

/** Only enable one execution per Module instance */
public static $executed = false;

[...]

public function hookactionProductSave($params){

    // Test if hook as has already been executed (as there is only one instance per module in ps 1.6)
    $executed = Self::$executed;
    if($executed == true)
	return

    // Set executed static property
    Self::$executed = true;

    $product = $params[0]['product'];
    [...]
    $product->save();
}
[...]

Be aware that this will only allow this hookactionProductSave() to be executed once.

 

Edited by Merguezzz (see edit history)
Link to comment
Share on other sites

  • 5 years later...

Hi,

A solution for the loop recursion problem.

 

 public function hookActionProductSave()
    {

        if(isset($_SESSION['hookFlood'])) {
            if (($_SESSION['hookFlood'] > time() - 10)) {
				//exit();
                return $this->l("?flood");
            }
        }
        $_SESSION['hookFlood'] = time();

		//do something
	}

 

Edited by Cem Kurt (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...