Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Magento to overwrite attribute values from another Website / Store while updating products programmatically

I have implemented custom Magento module that loops trough data from external service and updates price, weight, name and some other product attributes in Magento multi-language, multi-store website.

My solution is pretty straight forward (inside my Model invoked by Cron every day), as following:

/* THIS IS CODE SNIPPET INSIDE FOREACH LOOP */
$storeId = (string)$jobConfig->store; //cron for each store
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

$extistingProduct = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
$extistingProduct->setPrice($newPrice); //update price
//some code here dealing with Associated products of Configurable product probably not relevant
//...
$extistingProduct->setCanSaveConfigurableAttributes(true);
$extistingProduct->setCanSaveCustomOptions(true);

$extistingProduct->setConfigurableAttributesData($configurableAttributesData);
// This tells Magento to associate the given simple products to this configurable product..
$extistingProduct->setConfigurableProductsData($configurableProductsData);

$extistingProduct->setStoreId($storeId);

$extistingProduct->save();

I have this in cron running daily, separately for each Store. It usually works correctly, only changing the price of each product per Store, but sometimes a weird things happens (like once every 2 months) - all other attributes besides price get overwritten from Store X to current store $storeId. Meaning that all my English product description become German (for ex.) for all affected products.

I have no clue how could this happen, since every time I debug it is working correctly, only changing the price in current scope, which I explicitly set, but leaving all other product attributes intact. It seems like it loads all product data from Store X, sets price and then stores all those values to store which I set before saving product by calling $extistingProduct->setStoreId($storeId).

In situations when this happens, all attributes get overwritten from same Store (for example all English texts become German, but in other case all will become Spanish - they are all from one random Store).

Does anybody have a clue how could this possibly happen? What am I doing wrong?

like image 941
KoviNET Avatar asked Mar 21 '16 15:03

KoviNET


1 Answers

Yeah that whole "logic" is pretty nasty in Magento. Here is what you need to know:

When you load a product you load what is currently set as the scope, in your case the admin-scope which is the default. So what you are doing is loading from admin-scope and saving that into a store-front. So if a "random" language-change happens check what the default values of that product are, you might be surprised.

My advice:

  1. make sure you load each product in the same scope you want to store it in, so set the scope before you even load it
  2. remember that website/global attributes are overwritten each time you store the product
  3. Try to avoid the built-in load/save-methods and instead use other methods that write attributes directly and only for the desired scope

We have an extensive custom product import/update mechanism and in order for everything to work with load/save we first change and save the global values and then we load/save for each store-front changing store-front specific values.

like image 158
greenone83 Avatar answered Oct 14 '22 03:10

greenone83