Magento - 在脚本中累积自定义选项

发布于 2024-09-28 22:25:44 字数 3976 浏览 2 评论 0原文

在下面的脚本中,我迭代了一堆产品。对于其中每一个,我想添加一个自定义选项“Eskestørrelse”。在第一个产品上就像一个魅力,但是对于以下产品,以前产品的自定义选项以某种方式保留,并且该产品最终将具有多个自定义选项。

例如 - 第 10 个产品将有 10 个自定义选项,这些选项是为产品 1、2、3、... 生成的选项 10.

我做错了什么?

这是脚本(如果您更喜欢 Pastie,请参阅 http://pastie.org/1243529)、自定义选项和产品以粗体保存:

$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 +{$pricediff}%), 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;

?>

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 +{$pricediff}%), 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;

?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痕至 2024-10-05 22:25:44

经过几个小时和深入研究 Magentos 模型类后,我解决了这个问题。似乎产品选项是用单例模式设计的。

无需重新加载第 37 行中的产品:

$product = Mage::getModel('catalog/product')->load($product->getId());

……这只是解决此问题的绝望尝试。我应该做的是重置 Magentos 单例 Product_Option 实例中设置的多个选项。将第 37 行替换为以下行可以解决问题:

Mage::getSingleton('catalog/product_option')->unsetOptions(); // forget me and Magento will hate you

希望这可以避免其他人的挫败感。 ;)

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. ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文