Подтвердить что ты не робот

WooCommerce: Создать продукт по коду

Мой магазин продает виниловые наклейки. Каждый продукт (наклейка) имеет 144 варианта (24 цвета, 3 размера и 2 ориентации). Каждый вариант необходим для присвоения уникального SKU.

Вручную заполнять каталог нереально. Я собираюсь сделать форму, в которой пользователь указывает имя, описание и основной образ продукта, а также возможные размеры и цвета. При обработке формы мне нужно создать продукт и все его варианты.

Как создать продукт и его варианты?

4b9b3361

Ответ 1

У меня была аналогичная ситуация, вот что я узнал.

Продукты на самом деле являются настраиваемым типом сообщений (совершенно очевидно!: P), поэтому вы можете использовать wp_insert_post для вставки нового продукта. После того, как вы вставляете, вы получаете идентификатор типа нового продукта, используйте update_post_meta для установки мета-ключа и мета-значения как _visibility и visible соответственно. Если вы не установите видимость, ваш новый продукт никогда не будет виден в вашем магазине. В качестве альтернативы вы также можете установить видимость с заднего конца. Для различных размеров продукта используйте варианты этого продукта. Вы можете установить для каждого варианта другой тип, цену, SKU и т.д. Все это post meta, поэтому вы можете использовать PHP-код, чтобы добавить изменения и прочее. Изучите таблицу postmeta, чтобы увидеть имена ключей.

Ответ 2

Как писал Джейсон в своем комментарии, REST API - это путь сюда. Это можно сделать даже без запросов HTTP REST, что делает работу даже при установке Wordpress, у которых отключен интерфейс REST.

Вот простая функция, которую я сделал для этой цели:

$products_controler = new WC_REST_Products_Controller();
function create_item($rest_request) {
    global $products_controler;
    if (!isset($rest_request['status']))
        $rest_request['status'] = 'publish';
    $wp_rest_request = new WP_REST_Request('POST');
    $wp_rest_request->set_body_params($rest_request);
    return $products_controler->create_item($wp_rest_request);
}

Здесь $rest_request - это массив, который вы обычно отправляете через REST (см. docs здесь).

Переменная $products_controler является глобальной, потому что мне нужно было вызвать эту функцию несколько раз, и я не хотел каждый раз воссоздавать объект. Не стесняйтесь сделать его локальным.

Это работает для всех типов продуктов (простых, сгруппированных, переменных,...), и это должно быть более устойчивым к внутренним изменениям WooCommerce, чем добавление продуктов вручную через wp_insert_post и update_post_meta.

Изменить: Учитывая, что этот ответ по-прежнему получает случайную поддержку, вот обновление WooCommerce 3.0 +. Изменение заключается в том, что изменения больше не добавляются автоматически, поэтому мы должны сделать это сами.

Это текущая версия функции:

protected function create_item( $rest_request ) {
    if ( ! isset( $rest_request['status'] ) ) {
        $rest_request['status'] = $this->plugin->get_option( 'default_published_status' );
    }
    if ( ! isset( $this->products_controler ) ) {
        $this->products_controler = new WC_REST_Products_Controller();
    }
    $wp_rest_request = new WP_REST_Request( 'POST' );
    $wp_rest_request->set_body_params( $rest_request );
    $res = $this->products_controler->create_item( $wp_rest_request );
    $res = $res->data;
    // The created product must have variations
    // If it doesn't, it the new WC3+ API which forces us to build those manually
    if ( ! isset( $res['variations'] ) )
        $res['variations'] = array();
    if ( count( $res['variations'] ) == 0 && count( $rest_request['variations'] ) > 0 ) {
        if ( ! isset( $this->variations_controler ) ) {
            $this->variations_controler = new WC_REST_Product_Variations_Controller();
        }
        foreach ( $rest_request['variations'] as $variation ) {
            $wp_rest_request = new WP_REST_Request( 'POST' );
            $variation_rest = array(
                'product_id' => $res['id'],
                'regular_price' => $variation['regular_price'],
                'image' => array( 'id' => $variation['image'][0]['id'], ),
                'attributes' => $variation['attributes'],
            );
            $wp_rest_request->set_body_params( $variation_rest );
            $new_variation = $this->variations_controler->create_item( $wp_rest_request );
            $res['variations'][] = $new_variation->data;
        }
    }
    return $res;
}

Это используется в плагине для печати и Dropshipping on Demand, начиная с (скоро будет опубликовано) версии 1.1, в файле api/publish_products.php.

Существует также более длинная "быстрая" версия под названием create_products_fast, которая напрямую записывается в базу данных, что делает ее потенциально менее устойчивой к будущим изменениям WP/WC, но она намного быстрее (несколько секунд против нескольких минут для нашей 34 на моем тестовом компьютере).

Ответ 3

На основе ответа Vedran, здесь минимальный код для публикации продукта WooCommerce через PHP:

$data = [
    'name' => 'Test product',
    'description' => 'Lorem ipsum',
];
$request = new WP_REST_Request( 'POST' );
$request->set_body_params( $data );
$products_controller = new WC_REST_Products_Controller;
$response = $products_controller->create_item( $request );

Ответ 4

Обратитесь к woocommerce-with-php-code, где указан полный код.

Как сказал Avant Garde, продукты добавляются в сообщение с помощью:

post_type = "product"

Ответ 5

Я использую этот код:

$sku = 21333;
$size = 'S';
$stock = 2;
$price_a = 60;
$price_b = 30;

$product_parent = get_product_by_sku($sku);
$product = new WC_Product_Variable($product_parent->id);
$variations = $product->get_available_variations();

// First off all delete all variations
foreach($variations as $prod_variation) {
  $metaid=mysql_query("SELECT meta_id FROM wp_postmeta WHERE post_id = ".$prod_variation['variation_id']);
  while ($row = mysql_fetch_assoc($metaid)) {
    mysql_query("DELETE FROM wp_postmeta WHERE meta_id = ".$row['meta_id']);
  }
  mysql_query("DELETE FROM wp_posts WHERE ID = ".$prod_variation['variation_id']);
}

// Now add new variation
$thevariation = array(
  'post_title'=> '',
  'post_name' => 'product-' . $product_parent->id . '-variation',
  'post_status' => 'publish',
  'post_parent' => $product_parent->id,
  'post_type' => 'product_variation',
  'guid'=>home_url() . '/?product_variation=product-' . $product_parent->id . '-variation'
);
$variation_id = wp_insert_post( $thevariation );
update_post_meta($variation_id, 'post_title', 'Variation #' . $variation_id . ' of '. $product_parent->id);

wp_set_object_terms( $variation_id, $size, 'pa_size' );
update_post_meta($variation_id, 'attribute_pa_size', $size);

update_post_meta($variation_id, '_regular_price', $price_a);
update_post_meta($variation_id, '_downloadable_files', '');
update_post_meta($variation_id, '_download_expiry', '');
update_post_meta($variation_id, '_download_limit', '');
update_post_meta($variation_id, '_sale_price_dates_to', '');
update_post_meta($variation_id, '_sale_price_dates_from', '');
update_post_meta($variation_id, '_backorders', 'no');
update_post_meta($variation_id, '_stock_status', 'instock');
update_post_meta($variation_id, '_height', '');
update_post_meta($variation_id, '_manage_stock', 'yes');
update_post_meta($variation_id, '_width', '');
update_post_meta($variation_id, '_sale_price_dates_from', '');
update_post_meta($variation_id, '_backorders', 'no');
update_post_meta($variation_id, '_stock_status', 'instock');
update_post_meta($variation_id, '_manage_stock', 'yes');
update_post_meta($variation_id, '_height', '');
update_post_meta($variation_id, '_width', '');
update_post_meta($variation_id, '_length', '');
update_post_meta($variation_id, '_weight', '');
update_post_meta($variation_id, '_downloadable', 'no');
update_post_meta($variation_id, '_virtual', 'no');
update_post_meta($variation_id, '_thumbnail_id', '0');
update_post_meta($variation_id, '_sku', '');

update_post_meta($variation_id, '_sale_price', $price_b);
update_post_meta($variation_id, '_price', $price_b);
update_post_meta($product_parent->id, '_min_variation_price', $price_b);
update_post_meta($product_parent->id, '_max_variation_price', $price_b);
update_post_meta($product_parent->id, '_min_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_min_variation_regular_price', $price_a);
update_post_meta($product_parent->id, '_max_variation_regular_price', $price_a);
update_post_meta($product_parent->id, '_min_regular_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_regular_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_min_variation_sale_price', $price_b);
update_post_meta($product_parent->id, '_max_variation_sale_price', $price_b);
update_post_meta($product_parent->id, '_min_sale_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_sale_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_price', $price_b);

update_post_meta( $variation_id, '_stock', $stock );
update_post_meta($product_parent->id, 'post_status', 'publish');

Ответ 6

WooCommerce представила новые объекты CRUD в версии 3.0 - настоятельно рекомендуется начать использовать это, вместо того, чтобы использовать чистые функции Wordpress для обновления данных обратного проектирования.

https://github.com/woocommerce/woocommerce/wiki/CRUD-Objects-in-3.0