Magento - accumulating custom options in script
In the script below I iterate through a bunch of products. For each of these I want to add one custom option "Eskestørrelse". Works like a charm on the first product, however for the following products the custom options from the previous products are somehow kept and the product will end up with multiple custom options.
For example - the 10th product would have 10 custom options which are the ones generated for product 1, 2, 3, ... 10.
What am I doing wrong?
Heres the script (if you prefer pastie, see http://pastie.org/1243529), custom options and product save in bold :
$categoryId = 128;
$storeId = 4;
$cwd = getcwd();
chdir($launchdir);
echo "Entered $launchdir...\n";
require_once('includes/config.php');
require_once('app/Mage.php');
try {
$mageObj = Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);;
$category = Mage::getModel('catalog/category')->load($categoryId);
$products = $category->getProductCollection()->addStoreFilter($storeId)->addAttributeToSelect('*');
echo "Found " . count($products) . " products in category #{$categoryId} + store #{$storeId}...\n";
$nodesc = array();
$n = 0;
foreach($products as $product) {
$sku = $product->getSku();
$desc = $product->getDescription();
$shortdesc = $product->getShortDescription();
$price = $product->getPrice();
$matches = array();
if (preg_match('/[Ee]ske med ([0-9]+)/', $desc, $matches)==0) {
$nodesc[] = $product;
}
else {
$product = Mage::getModel('catalog/product')->load($product->getId());
$halfqty = (int)($matches[1] / 2);
$halfpriceExact = ($price / 2) * 1.1;
$halfprice = ceil($halfpriceExact/10) * 10;
$pricediff = round(($halfprice / ($price / 2)) * 100) - 100;
$savepct = round(($halfprice*2 - $price)/($halfprice*2)*100);
echo "{$sku}: quantity ({$matches[1]}, {$halfqty}), price ({$price}, {$halfprice} ({$halfpriceExact}), half +{$pr开发者_JAVA百科icediff}%), savepct {$savepct}% \n";
$newdesc = preg_replace('/([Ee])ske med [0-9]+/', "$1ske med {$halfqty} eller {$matches[1]} ", $desc);
$newshortdesc = preg_replace('/([Ee])ske med [0-9]+/', "$1ske med {$halfqty} eller {$matches[1]} ", $shortdesc);
$product->setPrice($halfprice);
$product->setDescription($newdesc . "\n\n<b>PS! </b>Du sparer $savepct% ved å kjøpe den største esken ({$matches[1]} stk).");
$product->setShortDescription($newshortdesc);
// figure out options
$newopts = array();
$newopts[] = array(
'title' => 'Eskestørrelse',
'type' => 'drop_down',
'previous_type' => null,
'previous_group' => 'select',
'is_require' => 1,
'is_delete' => null,
'sort_order' => 1,
'values' => array(
array(
'option_type_id' => -1,
'is_delete' => null,
'title' => "Eske med {$matches[1]} stk.",
'price' => ($price - $halfprice),
'price_type' => 'fixed',
'sku' => "-{$matches[1]}",
'sort_order' => '1'
),
array(
'option_type_id' => -1,
'is_delete' => null,
'title' => "Eske med {$halfqty} stk.",
'price' => 0.00,
'price_type' => 'fixed',
'sku' => "-{$halfqty}",
'sort_order' => '2'
)
)
);
if ($product->getOptionsReadonly()) {
echo "READONLY options, cant save...\n";
}
else {
$product->setProductOptions($newopts);
$product->setCanSaveCustomOptions(true);
$product->save();
$n++;
if ($n==2) die('temp stop');
}
}
$options = null;
$product = null;
}
echo "SUMMARY: " . count($products) . " products. " . count($nodesc) . " descriptions with no match. \n";
foreach ($nodesc as $product) {
echo "UNMATCHED: " . $product->getSku() . "\n";
}
}
catch (Exception $e) {
echo "Failed with exception " . $e . "\n";
}
chdir($cwd);
echo "Returned to $cwd...\n";
return;
?>
I figured this one out after a few more hours and after sticking my nose into Magentos model classes. Seems like product options was designed with a singleton pattern.
There's no need to reload the product in line 37:
$product = Mage::getModel('catalog/product')->load($product->getId());
…that was just a desperate try to deal with this problem. What I should've done is resetting the multiple options set in the Magentos singleton Product_Option
instance. Replacing line 37 with the line below resolves the problem:
Mage::getSingleton('catalog/product_option')->unsetOptions(); // forget me and Magento will hate you
Hope this can save someone else some frustration. ;)
精彩评论