获取订单项自定义索引并将其分配给 Woocommerce 中的选项值

Get an order item custom index and assign it to options value In Woocommerce

我使用 Woocommerce 最新版本 3.4.2。 在这种情况下,我们收集订单数据:产品及其添加剂(我接受元数据)。

如何将变量$skus[] = $product->get_sku();的索引赋值给变量$product_mod[] = '';的值?

$product_mod[1] = "0"; // 键为 1 的产品(成分糖)是键为 0 的产品修饰符。

// Get product details
$skus = $item_quantities = $line_item_totals = $product_mod = array();

// Loop though order items
foreach( $order->get_items() as $item_id => $item){
    $product_id = $item->get_product_id();
    $product = $item->get_product();

    $item_quantities[] = $item->get_quantity();
    $line_item_totals[] = $item->get_total();
    $skus[] = $product->get_sku();
    $product_mod[] = NULL;

    $ai = $item->get_meta('Optionally select');
    if( strpos( $ai, 'Cinnamon' ) !== false ) {
        $skus[] = '10001';
        $item_quantities[] ='1';
        $line_item_totals[] = '50';
        $product_mod[] = '';
    }

    if( strpos( $ai, 'Sugar' ) !== false ) {
        $skus[] = '10002';
        $item_quantities[] ='1';
        $line_item_totals[] = '50';
        $product_mod[] = '';
    }

    if( strpos( $ai, 'Mint' ) !== false ) {
        $skus[] = '10003';
        $item_quantities[] ='1';
        $line_item_totals[] = '50';
        $product_mod[] = '';
    }
}

// Product details
foreach ($skus as $key => $value){
    $data .= "&product_sku[".$key."]=".$value."";
    $data .= "&product_quantity[".$key."]=".$item_quantities[$key]."";
    $data .= "&product_price[".$key."]=".$line_item_totals[$key]."";
    if( isset($product_mod[$key]) ) {
        $data .= "&product_mod[".$key."]=".$key."";
    }
}

print_r( $data ); 现在显示: // 为了阅读方便,我写在专栏里,不过这是一个字符串。

&product_sku[0]=10030 
&product_quantity[0]=1
&product_price[0]=499
&product_sku[1]=10002
&product_quantity[1]=1
&product_price[1]=50
&product_mod[1]=1

需要:

&product_sku[0]=10030 // Coffe sku
&product_quantity[0]=1 // Coffe quantity
&product_price[0]=499 // Coffe price
&product_sku[1]=10002 // Sugar sku
&product_quantity[1]=1 // Sugar quantity
&product_price[1]=50 // Sugar price
&product_mod[1]=0 // Ingredient Sugar with number 1, is a product modifier with number 0.

我认为这是正确的方法:

就做一个class。这就是它们的用途。 这样一来,您将始终按照您想要的方式将数据整齐地分组在一起,而不必保持顺序或多个数组的混乱。

下面的 class 只是一个概念验证,您必须自己制作 getter 和 setter,但是如果您这样做,您就可以控制数据,它去哪里,做什么属于什么,您甚至可以将数据从一个数组移动到另一个数组或将对象复制过来。

您要做的是制作您自己的对象,其中包含您想要的产品数据。 然后你在其中添加一个数组 "extras" ,你可以在其中 "extras" 到产品。 然后你添加一个函数来计算 "own price + price of extras" 的总数 以及您需要的其他一些辅助函数。

然后你把它包起来,有一个很好的class来帮助你。

请注意,这是伪代码,需要一些工作。

class ProductData 
{
   protected $product_id;
   protected $product;
   protected $quantity;
   protected $total;
   protected $sku;
   protected $extras = [];

   public function __construct($product_id, $product, $sku, $total, $quantity) 
   {
      $this->product_id = $product_id;
      $this->product = $product;
      $this->sku = $sku;
      $this->total = $total;
      $this->quantity = $quantity;
   }
   public function addExtra($product) 
   {
      $this->extras[] = $product;
   }
   public function getTotal() 
   {
      $total = $this->total;
      foreach($this->extras as $extra)  {
          $this->total += $extra->getTotal();
      }
      return total;
   }
   public static function fromItem($item) 
   {
       $product = new self(
                          $item->get_product_id(),
                          $item->get_product(),
                          $item->get_sku(),
                          $item->line_item_totals(),
                          $item->get_quantity()
                   );
       return $product;

   }
}

$preregistered_extras = [
     'Cinnamon' => new Product(
                             wc_get_product_id_by_sku('10001'), 
                             wc_get_product(wc_get_product_id_by_sku('10001')), 
                             '10001', 
                             '50', 
                             '1'),
     'Sugar' => new Product(
                             wc_get_product_id_by_sku('10002'), 
                             wc_get_product(wc_get_product_id_by_sku('10002')), 
                             '10002', 
                             '50', 
                             '1'),
     'Mint' => new Product(
                             wc_get_product_id_by_sku('10003'), 
                             wc_get_product(wc_get_product_id_by_sku('10003')), 
                             '10003', 
                             '50', 
                             '1'),
];

$product_list = [];
foreach( $order->get_items() as $item_id => $item){
   $product = Product::fromItem($item);
   $ai = $item->get_meta('Optionally select');

   foreach($preregistered_extras as $name => $extra) {
      if( stripos( $ai, $name ) !== false ) { 
          $product->addExtra($extra);
      }
   }    
}
var_dump($product_list);
$total = 0;
foreach($product_list as $item) {
    $total += $item->getTotal();
}
echo "Total = $total";

你让事情有点复杂了……你需要在一个变量中设置主订单项目索引,以便在选定的附加选项中为你的产品修饰符获取它。不需要任何并发症......

我已经重新访问、简化和压缩了您的代码:

// Array of defined options ( sku => option name )
$options  = array(
    '10001' => 'Cinnamon',
    '10002' => 'Sugar',
    '10003' => 'Mint',
);
$count = 0;

// Loop though order items
foreach( $order->get_items() as $item_id => $item){
    $product_id = $item->get_product_id();
    $product    = $item->get_product();

    $data .= '&product_sku['.$count.']='.$product->get_sku();
    $data .= '&product_quantity['.$count.']='.$item->get_quantity();
    $data .= '&product_price['.$count.']='.$item->get_total();
    $ind   = $count; // Here we set the main order item index in a variable
    $count++; 

    // Get order item selected options
    $options_selected = $item->get_meta('Optionally select');

    // Loop though order items selected options
    foreach( $options as $sku_key => $label_value ){
        if( strpos( $options_selected, $label_value ) !== false ) {
            $data .= '&product_sku['.$count.']='.$sku_key;
            $data .= '&product_quantity['.$count.']=1';
            $data .= '&product_price['.$count.']=50';
            $data .= '&product_mod['.$count.']='.$ind;
            $count++;
        }
    }
}

// Testing output
print_r( $data );

未经测试,但它应该按预期工作。