1

Back again. I'm almost there with my observer to update "Manage Stock" on child items when the parent configurable item is changed, but I've run into a memory problem. First, I tried updating all the children when the memory limit was set to 64MB, then raised it to 256MB and finally to 512MB...each time, I hit the limit when executing the code. As a test, I made it to where the script would exit after updating just one child product, but it still hit the limit. This leads me to believe that I'm doing something wrong, as I'm pretty sure Magento wouldn't need more than half a gig of memory allocated to update two fields of one child. My observer is as follows:

<?php

class MyCompany_Catalog_Model_Observer
{
    public function mc_update_child (Varien_Event_Observer $observer)
    {
        if (Mage::app()->getRequest()->getPost('mc_update_child_products'))
        {
            $productid = Mage::registry('current_product')->getId();
            $product = Mage::getModel('catalog/product')->load($productid);
            $productType = $product->getTypeID();
            if ($productType === 'configurable')
            {
                $parent = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productid);
                $parentMS = $parent->getData('manage_stock');
                $parentUCMS = $parent->getData('use_config_manage_stock');
                $children = $product->getTypeInstance()->getUsedProducts();
                foreach ($children as $child)
                {
                    $childId = $child->getId();
                    $childProduct = Mage::getModel('catalog/product')->load($childId);
                    $childStock = $childProduct->getStockItem();
                    $childStock->setData('manage_stock', $parentMS);
                    $childStock->setData('use_config_manage_stock', $parentUCMS);
                    $childStock->save();
                    $childProduct->save();
                    Mage::log($childId);
                    exit;
                }
            }
        }
    }
}

As you can see, I was hoping to log the id of the child product that got updated, and exit, but no log entry is made, and I get this in the Apache error log:

[Wed Mar 19 16:45:03 2014] [error] [client 192.168.1.120] PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 32 bytes) in /var/www/magento-www/docs/lib/Zend/Db/Statement/Pdo.php on line 290, referer: https://www.mycompany.com.local/index.php/admin/catalog_product/edit/id/9407/back/edit/tab/product_info_tabs_inventory/key/d32f1b287f7eff4f68951efbd09418265067fabe9adb78541b070adb748dbfd6/

Hopefully someone can see a mistake I'm making. TIA.

  • What triggers mc_update_child? Are you sure you are not creating some infinite loop? Try moving your log entries to before the save calls. – Kristof at Fooman Mar 19 '14 at 21:49
  • I would echo or log memory_get_usage() at each of those steps to see at which point your memory explodes. – musicliftsme Mar 20 '14 at 3:19
  • Sorry for the delay in reply; just got back into work. Started logging after each step, and it is in an infinite loop, but I have no idea as to why. Between the last 'setData' call and the 'save' call, it starts the loop again and keeps getting the same childId. Never actually completes the save. – John Mar 20 '14 at 13:12
  • Seems that every time it gets to the 'save' call, the save fails (haven't been able to figure out why) and it just starts the loop over again. – John Mar 20 '14 at 14:47
  • 1
    Which event are you actually observing? I'm going to guess it's a product save, which will also be triggered when you do $childProduct->save(). And since the product in your registry hasn't changed, this function will be run again. You would get the same childId and you'd have an infinite loop. – Vicky Mar 20 '14 at 15:19
1

Many thanks to Vicky for putting me on the right track. My observer was firing on a product save, so each time the observer tried to run save() on the child object, the observer was firing again and getting stuck in an infinite loop. A Google search later and I found that I could set a flag when my observer was executed and test that flag so that the observer would only run once during the process. The updated (and working) code is below, and I hope it can help someone else should they have that 'DOH!' moment like me.

<?php

class MyCompany_Catalog_Model_Observer
{
    public function mc_update_child (Varien_Event_Observer $observer)
    {
        if (Mage::registry('mc_update_child_event') == 1)
        {
            return $this;
        }
        Mage::register('mc_update_child_event', 1);
        if (Mage::app()->getRequest()->getPost('mc_update_child_products'))
        {
            $productid = Mage::registry('current_product')->getId();
            $product = Mage::getModel('catalog/product')->load($productid);
            $productType = $product->getTypeID();
            if ($productType === 'configurable')
            {
                $parent = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productid);
                $parentMS = $parent->getData('manage_stock');
                $parentUCMS = $parent->getData('use_config_manage_stock');
                $children = $product->getTypeInstance()->getUsedProducts();
                unset($parent);
                foreach ($children as $child)
                {
                    $childProd = Mage::getModel('catalog/product')->load($child->getId());
                    $childStockObj = Mage::getModel('cataloginventory/stock_item')->load($child->getId());
                    $childStockData = $childStockObj->getData();
                    $childStockData['manage_stock'] = (int)$parentMS;
                    $childStockData['use_config_manage_stock'] = (int)$parentUCMS;
                    $childProd->setStockData($childStockData);
                    try
                    {
                        $childProd->save();
                    }
                    catch  (Exception $e)
                    {
                        Mage::log($e);
                    }
                }
            }
        }
    }
}
  • feel free to accept this answer if it is now working. – David Manners May 23 '14 at 14:06

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.