向 WooCommerce 添加产品的问题

Problem with adding products to WooCommerce

提问人:Elyas Behroozizade 提问时间:11/17/2023 最后编辑:Elyas Behroozizade 更新时间:11/17/2023 访问量:38

问:

我正在尝试向 WooCommerce 添加一些产品,我为此开设了一门课。这是我的公共插入函数:

public function insert()
{
    $this->_insert_product();
    $this->_update_variations();
    $this->_update_featured_image();
    $this->_update_attributes();
    $this->_update_categories();
    $this->_update_tags();
    $this->_update_custom_fields();
    $this->_update_product_price();
    $this->_update_sku();
    $this->_update_stock();
    return true;
}

这将插入产品、插入变体和其他一些东西。问题出在库存上!当我添加我的产品时,一切都很好,但对于可变产品,当我使用管理面板保存产品或从该产品购买一件商品时,该产品将缺货,我肯定不希望这样。变体仍然有库存,用户可以毫无问题地购买产品,但产品缺货徽章显示在产品上,并且管理面板中的状态为缺货。我可以使用一些帮助吗?

private function _update_stock()
{
    // $this->id is product id
    // This will generate $this->stock variable (0 or 1 or 2 and etc)
    $this->_generate_stock();
    // If product type is simple just update product stock and stock status
    // This is working just fine
    if ($this->type == 'simple') {
        update_post_meta($this->id, '_manage_stock', 'yes');
        update_post_meta($this->id, '_stock', $this->stock);
        if ($this->stock > 0) update_post_meta($this->id, '_stock_status', 'instock');
        else update_post_meta($this->id, '_stock_status', 'outofstock');
        update_post_meta($this->id, '_backorders', 'no');
    }
    // Else if product type is variable (PROBLEM IS HERE)
    else {
        // Variable to store if any of variations has stock
        $has_stock = false;
        // $this->variations is an array of variations ids
        for ($i = 0; $i < count($this->variations); $i++) {
            // Enable stock management for variation
            update_post_meta($this->variations[$i], '_manage_stock', 'yes');
            // Update stock ($this->stock is an array of stocks for each variation)
            update_post_meta($this->variations[$i], '_stock', $this->stock[$i]);
            // Disable backorders
            update_post_meta($this->variations[$i], '_backorders', 'no');
            // If variation has stock update stock status to in stock
            if ($this->stock[$i] > 0) {
                update_post_meta($this->variations[$i], '_stock_status', 'instock');
                $has_stock = true;
            }
            // Else update stock status to out of stock
            else update_post_meta($this->variations[$i], '_stock_status', 'outofstock');
        }
        // Sync variation
        WC_Product_Variable::sync($this->id);
        // Update stock status of main product
        if ($has_stock) update_post_meta($this->id, '_stock_status', 'instock');
        else update_post_meta($this->id, '_stock_status', 'outofstock');
    }
}

private function _insert_product()
{
    $this->_generate_title();
    $this->_generate_permalink();
    $this->_generate_content();
    $this->_generate_excerpt();
    $this->_generate_post_status();
    $post = array(
        'post_title' => $this->title,
        'post_name' => sanitize_title($this->permalink),
        'post_content' => $this->content,
        'post_status' => $this->post_status,
        'post_type' => 'product',
        'post_excerpt' => $this->excerpt,
        'tax_input' => array('product_type' => $this->type),
    );
    $this->id = wp_insert_post($post);
}

private function _update_variations()
{
    if ($this->type == 'variable') {
        $attribute_id = $this->options['import_attribute_for_variations'];
        $attribute = wc_get_attribute($attribute_id);
        $attributes = [];
        $attributes[$attribute->slug] = array(
            'name' => $attribute->slug,
            'value' => '',
            'position' => '0',
            'is_visible' => '0',
            'is_variation' => '1',
            'is_taxonomy' => '1'
        );
        update_post_meta($this->id, '_product_attributes', $attributes);
        $variation_name_index = $this->options['import_variation_name'];
        $variations = [];
        foreach ($this->product as $variation) {
            $variation_name = $variation[$variation_name_index];
            array_push($variations, $variation_name);
        }
        wp_set_object_terms($this->id, $variations, $attribute->slug);
        foreach ($this->product as $variation) {
            $variation_name = $variation[$variation_name_index];
            $variation = array(
                'post_title'   => $this->title . ' - ' . $variation_name,
                'post_content' => '',
                'post_status'  => 'publish',
                'post_parent'  => $this->id,
                'post_type'    => 'product_variation',
            );
            $variation_id = wp_insert_post($variation);
            update_post_meta($variation_id, 'attribute_' . $attribute->slug, sanitize_title($variation_name));
            $this->variations[] = $variation_id;
        }
    }
}

php wordpress woocommerce

评论

0赞 TSCAmerica.com 11/17/2023
您应该调用 WC_Product_Variable::sync($this->id);在更新所有变体之后,而不是在循环中。此方法将变量乘积与其变体同步,并且应在所有变体更新后调用。
0赞 Elyas Behroozizade 11/17/2023
@user580950是的,我试过了,但问题仍然在这里。
0赞 TSCAmerica.com 11/17/2023
用你做了什么更新问题,以便我可以检查
0赞 Elyas Behroozizade 11/17/2023
@user580950 我在循环之后移动了它
1赞 LoicTheAztec 11/17/2023
从 WooCommerce 3 开始,您应该使用可用的 CRUD 方法而不是 WordPress 函数,因为 WooCommerce 正在逐步迁移到自定义数据库表。提供的代码是不可测试的,所以没有人能真正猜测并找出问题所在,给出一个有用的工作答案......请参阅如何创建最小的可重现示例

答:

1赞 TSCAmerica.com 11/17/2023 #1

正如评论中所讨论的,我删除了可变产品库存状态的手动更新,并允许 WooCommerce 根据其变体库存状态自动同步可变产品状态。我希望这有助于解决问题

private function _update_stock()
{
    $this->_generate_stock();
    if ($this->type == 'simple') {
        update_post_meta($this->id, '_manage_stock', 'yes');
        update_post_meta($this->id, '_stock', $this->stock);
        update_post_meta($this->id, '_stock_status', $this->stock > 0 ? 'instock' : 'outofstock');
        update_post_meta($this->id, '_backorders', 'no');
    } else {
        foreach ($this->variations as $i => $variation_id) {
            update_post_meta($variation_id, '_manage_stock', 'yes');
            update_post_meta($variation_id, '_stock', $this->stock[$i]);
            update_post_meta($variation_id, '_backorders', 'no');
            update_post_meta($variation_id, '_stock_status', $this->stock[$i] > 0 ? 'instock' : 'outofstock');
        }
        WC_Product_Variable::sync($this->id);
        WC_Product_Variable::sync_stock_status($this->id);

    }
}

评论

0赞 Elyas Behroozizade 11/17/2023
我试过这个,但正如我所说,现在的产品从一开始就缺货,但变化很好,可以购买。
0赞 TSCAmerica.com 11/17/2023
答案已更新,以在更新所有变体后同步父产品的库存状态:
0赞 Elyas Behroozizade 11/17/2023
还是同样的问题,我添加了其他可能是问题的功能