Nate H
Nate H

Reputation: 322

Any way to speed up this Magento code?

Is there any way to speed up this Magento code? Currently it is looking through about 2k products and takes approximately 20 minutes to run.

I'm guessing the issue is around the product->load() call, but I'm not familiar enough Magento to know the overhead it takes.

Thank you.

from controller

Mage::dispatchEvent(
    'category_rule_save',
    array(
        'rule_id'        => $id,
        'attribute_code' => $data['attribute_code'],
        'operator'       => $data['operator'],
        'value'          => $data['value'],
        'category_id'    => $data['category'],
        'store_id'       => $data['store_id']
    )
);

from Observer.php

public function onCategoryRuleSave($observe)
{
    $collection =
        Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect($observe['attribute_code']);
    $write = Mage::getSingleton('core/resource')->getConnection('core_write');

    foreach ($collection as $product) {
        $productId = $product->getId();
        $product = $product->load($productId);
        $productAttributeValue = '';
        $productAttributeValue =
            Mage::getModel('catalog/product')->load($productId)
                ->getAttributeText( $observe['attribute_code'] );
        $r = 0;

        if ( is_numeric($observe['value']) ) {
            switch($observe['operator']) {
                case "<":
                    $r = ($productAttributeValue < $observe['value']) ? 1 : 0;
                    break;
                case ">":
                    $r = ($productAttributeValue > $observe['value']) ? 1 : 0;
                    break;
                case "<=":
                    $r = ($productAttributeValue <= $observe['value']) ? 1 : 0;
                    break;
                case ">=":
                    $r = ($productAttributeValue >= $observe['value']) ? 1 : 0;
                    break;
                case "==":
                    $r = ($productAttributeValue == $observe['value']) ? 1 : 0;
                    break;
                case "!=":
                    $r = ($productAttributeValue != $observe['value']) ? 1 : 0;
                    break;
            }
        }
        else {
            switch($observe['operator']) {
                case "==":
                    $r = (
                        strcmp(strtolower($productAttributeValue) , strtolower($observe['value'])) == 0
                    ) ? 1 : 0;
                    break;
                case "!=":
                    $r = (
                        strtolower($productAttributeValue) != strtolower($observe['value'])
                    ) ? 1 : 0;
                    break;
            }
        }

        if ($r==1) {
            $write->query(
                "REPLACE INTO `catalog_category_product` (`category_id`, `product_id`)
                VALUES (" . $observe['category_id'] . "," . $product->getId() . ")"
            );
        }
    }
}

Upvotes: 2

Views: 572

Answers (2)

Jevgeni Smirnov
Jevgeni Smirnov

Reputation: 3797

1.$collection =
        Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToSelect($observe['attribute_code']);

2.Mage::getModel('catalog/product')->load($productId) ->getAttributeText( $observe['attribute_code'] );

3.$product = $product->load($productId);

That is really awful :)

$collection =
        Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToSelect('*');//this string should load all of the product attributes
There also were some methods to add product websites, product store and some others.

Upvotes: 0

Roscius
Roscius

Reputation: 1534

Try replacing the product loading with:

...
foreach ($collection as $product) {
 $productAttributeValue = $product->getAttributeText( $observe['attribute_code'] );
 $r = 0;
...

You're loading a product object 2 extra times. The $product variable in the foreach already is the loaded product with the attribute that you need to work with. Loading a $product object with all of its attributes is expensive given Magento's EAV database structure.

Upvotes: 1

Related Questions