1

I'm trying to run a one-time script (in a custom module upgrade) to set a new attribute last_order_date based on the date of that customer's last order.

I have this script:

$users = mage::getModel('customer/customer')->getCollection()
           ->addAttributeToSelect('last_order_date');

foreach ($users as $user){
   $lastDate = $user->getData('last_order_date');
   if(empty($lastDate)){
       $orderCollection = Mage::getModel('sales/order')->getCollection()
            ->addFilter('customer_id', $user->getId())
            ->setOrder('created_at', Varien_Data_Collection_Db::SORT_ORDER_DESC)
        ;
        $numberOfOrders = $orderCollection->count();
        if($numberOfOrders!=0){
            $newestOrder = $orderCollection->getFirstItem();
            $lastOrderDate = $newestOrder->getCreatedAt();
            $user->setData('last_order_date', $lastOrderDate);
            $user->save();
        }
   }
}

But it's causing a memory leak:

Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 32 bytes) in [..]/web-root/lib/Zend/Db/Adapter/Pdo/Abstract.php on line 292

Which I understand is due to the looped calls to Mage::getModel('sales/order').

How do I achieve this without the repeated calls?

1

require_once 'app/Mage.php';
Mage::app();

$current_page = isset($_GET['current_page']) ? 1 : $_GET['current_page'];

$users = mage::getModel('customer/customer')->getCollection()
           ->addAttributeToSelect('last_order_date')
           ->setPageSize(100)
           ->setCurPage($current_page);

if($users->count() == 0){
    die('done');
}

foreach ($users as $user){
   $lastDate = $user->getData('last_order_date');
   if(empty($lastDate)){
       $orderCollection = Mage::getModel('sales/order')->getCollection()
            ->addFilter('customer_id', $user->getId())
            ->setOrder('created_at', Varien_Data_Collection_Db::SORT_ORDER_DESC)
        ;
        $numberOfOrders = $orderCollection->count();
        if($numberOfOrders!=0){
            $newestOrder = $orderCollection->getFirstItem();
            $lastOrderDate = $newestOrder->getCreatedAt();
            $user->setData('last_order_date', $lastOrderDate);
            $user->save();
        }
   }
}

$current_page++;

//go to next page
$redirect_url = "http://yoururlhere/set_last_order_date.php?current_page=" . $current_page;
?>
<script type="text/javascript">
    setTimeout("location.href = '<?php echo $redirect_url;?>';", 50);
</script>
3
  • I think the above code will sort out your performance issue
    – phanvugiap
    Feb 5 '16 at 16:39
  • Thanks - I can see this working, but where do I put it? In the upgrade script? Or should I call it separately and add an include to Mage?
    – WillPS
    Feb 5 '16 at 16:40
  • http://yoururlhere/set_last_order_date.php - so should be your root folder
    – phanvugiap
    Feb 5 '16 at 16:44
1

Added to gurutheme answer a huge performance server is to use saveAttribute instead of save

So replace the following

$user->setData('last_order_date', $lastOrderDate);
        $user->save();

With:

$user->setData('last_order_date', $lastOrderDate);
        $user->getResource()->saveAttribute($user,'last_order_date');

This way you will only save one attribute instead of saving every attribute of the customer model.

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.