Reputation: 322
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.
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']
)
);
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
Reputation: 3797
1.$collection = Mage::getModel('catalog/product')->getCollection() ->addAttributeToSelect($observe['attribute_code']);That is really awful :)2.Mage::getModel('catalog/product')->load($productId) ->getAttributeText( $observe['attribute_code'] );
3.$product = $product->load($productId);
$collection = Mage::getModel('catalog/product')->getCollection() ->addAttributeToSelect('*');//this string should load all of the product attributesThere also were some methods to add product websites, product store and some others.
Upvotes: 0
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