1

I wrote this piece of code. This method takes as an argument name and price of the item. Data are taken from the file line by line. There is 20k rows so this method is called 20k times. What is your suggestion to optimize this code? beacuse import takes about 2,5 hours.

protected function saveProductPrice($singleProduct) {

        $productCollection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
            ->getFirstItem();
        $websiteID = $this->determineStoreID((int)$singleProduct['ERP_PRICE_LIST_ID']);
        $productCollection->setWebsiteId($websiteID);
        $productCollection->setUrlKey(false);
        $productCollection->setStoreId($websiteID)
            ->setPrice($singleProduct['LIST_PRICE']);

        try {
            $productCollection->save($productCollection);
            echo $singleProduct['PRODUCT_NUMBER'] . " price updated and added to website " . $websiteID . "\n";
        } catch (Exception $ex) {
            Mage::logException($ex);
        }
        unset($productCollection);
    }
2

One thing that could change a lot is to restrict the size of your product collection as you only get the first item everytime.

Instead of:

$productCollection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
    ->getFirstItem();

I reckon you should do:

 $productCollection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
    ->setPageSize(1)
    ->getFirstItem();

On top of that, it's not recommended to save products in a loop. (BTW I don't understand why you pass the $productCollection as an argument to the save() method).

A suggestion that is way faster could be to use the saveAttribute method:

$productCollection->setStoreId($websiteID)->setPrice($singleProduct['LIST_PRICE']);
$productCollection->getResource()->saveAttribute($productCollection, 'price');
2
  • thks, pagination and saveAttributes reduced the time to 15minutes! Jun 13 '16 at 9:42
  • @sherdog 2.5hours to 15min not bad ^^ Jun 13 '16 at 9:44
3

Since you need to update only the price, for a lot of products you can just load the collection upfront, and make an array of products based on the name

$collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('name');
$productsByName = array();
foreach ($collection as $product) {
    if (!isset($productsByName[$product->getName()])) {
        $productsByName[$product->getName()] = array();
    }
    $productsByName[$product->getName()][] = $product;
}

I see that you also use a method to retrieve the website id $this->determineStoreID((int)$singleProduct['ERP_PRICE_LIST_ID']);.
I have no idea how that works, but you can load the websites upfront using the same method as for products and make a mapping between $singleProduct['ERP_PRICE_LIST_ID'] and the websites.

Then all you have to do is this: Let's say you have $singleProduct with data from your file.

do this now:

$name = $singleProduct['PRODUCT_NUMBER'];
if (isset($productsByName[$name])) {  //if the products with the name exists
    $newPrice = $singleProduct['LIST_PRICE'];
    $storeId = your custom logic to determine the store view id
    $productIds = array(); 
    foreach ($productsByName[$name] as $product) {
        $productIds[] = $product->getId();
    }
    Mage::getSingleton('catalog/product_action')->updateAttributes(
        $productIds, //bulk update all the products with the same name
        array('price' => $newPrice), //update only the price
        $storeId //update for only the store id you need.
    )
}

Watch for syntax errors, I didn't test the code.

0

You can use Mage::getSingleton('catalog/product_action')->updateAttributes(array of product id, array of attribute data,store id) Method to save product price.

$data['price'] = 12; 
Mage::getSingleton('catalog/product_action')->updateAttributes(aary(1),$data,0);

This method is fast compared to product save method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.