source

새 속성 값을 사용하여 프로그래밍 방식으로 WooCommerce 제품 변형을 생성합니다.

manycodes 2023. 4. 6. 21:47
반응형

새 속성 값을 사용하여 프로그래밍 방식으로 WooCommerce 제품 변형을 생성합니다.

WooCommerce 버전 3+에서 가변 제품("부모" 제품)을 만들었습니다.WordPress 플러그인에서 새로운 속성값으로 제품 바리에이션("자녀" 제품)을 프로그래밍 방식으로 만들고 싶습니다.

우커머스
따라서 하나의 변형이 생성될 때마다 새 속성 값도 프로그래밍 방식으로 생성되어 상위 변수 제품에서 설정되어야 합니다.

이것이 어떻게 행해지는가?가능합니까?


업데이트 : Woocommerce 객체를 사용하여 원하는 코드 라인을 더 작성했으며, WordPress 데이터베이스 객체를 사용하여 용어, 용어 포스트의 관계에 대한 누락된 데이터를 데이터베이스에 추가했습니다.그러나기능을 수행하기에 충분한 것은 없습니다. 또한 스택 오버플로우가 더 적합한 부분을 특정할 수 없었습니다. 그래서 더 좁은 문제를 제공할 수 없었습니다.

2020년 1월 업데이트: 방식이 아닌 방식으로 변경됨get_title()
2018년 9월 갱신: 분류법 작성 처리 (Carl F 덕분). 코네일)

정의된 변수 제품 ID에서 아래에 제품 변형을 추가(생성)하는 커스텀 기능이 있습니다.변수 상위 제품은 필요한 속성을 설정해야 합니다.

다음과 같은 정보를 제공해야 합니다.

  • 속성/값의 배열
  • Sku, 가격, 주식...

이 데이터는 포맷된 다차원 배열에 저장해야 합니다(마지막 참조).

이 함수는 속성 값(용어 이름)이 이미 존재하는지, 존재하지 않는지 확인합니다.

  • 제품 속성에 대해 작성한다.
  • 상위 변수 곱으로 설정합니다.

커스텀 기능 코드:

/**
 * Create a product variation for a defined variable product ID.
 *
 * @since 3.0.0
 * @param int   $product_id | Post ID of the product parent variable product.
 * @param array $variation_data | The data to insert in the product.
 */

function create_product_variation( $product_id, $variation_data ){
    // Get the Variable product object (parent)
    $product = wc_get_product($product_id);

    $variation_post = array(
        'post_title'  => $product->get_name(),
        'post_name'   => 'product-'.$product_id.'-variation',
        'post_status' => 'publish',
        'post_parent' => $product_id,
        'post_type'   => 'product_variation',
        'guid'        => $product->get_permalink()
    );

    // Creating the product variation
    $variation_id = wp_insert_post( $variation_post );

    // Get an instance of the WC_Product_Variation object
    $variation = new WC_Product_Variation( $variation_id );

    // Iterating through the variations attributes
    foreach ($variation_data['attributes'] as $attribute => $term_name )
    {
        $taxonomy = 'pa_'.$attribute; // The attribute taxonomy

        // If taxonomy doesn't exists we create it (Thanks to Carl F. Corneil)
        if( ! taxonomy_exists( $taxonomy ) ){
            register_taxonomy(
                $taxonomy,
               'product_variation',
                array(
                    'hierarchical' => false,
                    'label' => ucfirst( $attribute ),
                    'query_var' => true,
                    'rewrite' => array( 'slug' => sanitize_title($attribute) ), // The base slug
                ),
            );
        }

        // Check if the Term name exist and if not we create it.
        if( ! term_exists( $term_name, $taxonomy ) )
            wp_insert_term( $term_name, $taxonomy ); // Create the term

        $term_slug = get_term_by('name', $term_name, $taxonomy )->slug; // Get the term slug

        // Get the post Terms names from the parent variable product.
        $post_term_names =  wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );

        // Check if the post term exist and if not we set it in the parent variable product.
        if( ! in_array( $term_name, $post_term_names ) )
            wp_set_post_terms( $product_id, $term_name, $taxonomy, true );

        // Set/save the attribute data in the product variation
        update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
    }

    ## Set/save all other data

    // SKU
    if( ! empty( $variation_data['sku'] ) )
        $variation->set_sku( $variation_data['sku'] );

    // Prices
    if( empty( $variation_data['sale_price'] ) ){
        $variation->set_price( $variation_data['regular_price'] );
    } else {
        $variation->set_price( $variation_data['sale_price'] );
        $variation->set_sale_price( $variation_data['sale_price'] );
    }
    $variation->set_regular_price( $variation_data['regular_price'] );

    // Stock
    if( ! empty($variation_data['stock_qty']) ){
        $variation->set_stock_quantity( $variation_data['stock_qty'] );
        $variation->set_manage_stock(true);
        $variation->set_stock_status('');
    } else {
        $variation->set_manage_stock(false);
    }
    
    $variation->set_weight(''); // weight (reseting)

    $variation->save(); // Save the data
}

코드가 기능합니다.php 파일 또는 임의의 플러그인 파일에 있는 활성 자식 테마(또는 테마)입니다.

사용방법(예: 2개의 Atribute):

$parent_id = 746; // Or get the variable product id dynamically

// The variation data
$variation_data =  array(
    'attributes' => array(
        'size'  => 'M',
        'color' => 'Green',
    ),
    'sku'           => '',
    'regular_price' => '22.00',
    'sale_price'    => '',
    'stock_qty'     => 10,
);

// The function to be run
create_product_variation( $parent_id, $variation_data );

테스트 및 동작.

파트 2: WooCommerce에서 프로그래밍 방식으로 가변 제품 및 두 가지 새로운 특성 생성

이것은 백엔드로 취득됩니다.

여기에 이미지 설명 입력

그리고 그것은 프론트 엔드에서 완벽하게 작동될 것이다.

관련: Woocommerce 3에서 CRUD 메서드를 사용하여 프로그래밍 방식으로 제품 생성

위의 예에서는 아무것도 사용할 수 없기 때문에, 이것을 밖으로 던집니다.다른 사람들은 성공한 것 같으니까 나에게 이유를 묻지 마세요.그래서 저는 미니멀리즘 어프로치를 취해서 (wp에서 수동으로 만들고 db를 보면서) 제품 속성+바리에이션의 기본적인 요소를 알아내려고 했습니다.

$article_name = 'Test';

$post_id = wp_insert_post( array(
    'post_author' => 1,
    'post_title' => $article_name,
    'post_content' => 'Lorem ipsum',
    'post_status' => 'publish',
    'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'variable', 'product_type' );

$attr_label = 'Test attribute';
$attr_slug = sanitize_title($attr_label);

$attributes_array[$attr_slug] = array(
    'name' => $attr_label,
    'value' => 'alternative 1 | alternative 2',
    'is_visible' => '1',
    'is_variation' => '1',
    'is_taxonomy' => '0' // for some reason, this is really important       
);
update_post_meta( $post_id, '_product_attributes', $attributes_array );

$parent_id = $post_id;
$variation = array(
    'post_title'   => $article_name . ' (variation)',
    'post_content' => '',
    'post_status'  => 'publish',
    'post_parent'  => $parent_id,
    'post_type'    => 'product_variation'
);

$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 1' );
WC_Product_Variable::sync( $parent_id );

$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 2' );
WC_Product_Variable::sync( $parent_id );

이는 글로벌 제품 특성이 아니라 기사별 특성을 사용합니다.작동하기 전에 머리를 쥐어뜯을 준비가 되어 있었기 때문에 누군가에게 도움이 되었으면 합니다.

편집: 공식 방법을 사용할 수 없는 경우에만 이 방법을 사용합니다.그들은 이러한 것들을 시간에 따라 변화시키고('_regular_price'와 같은 필드 이름 등), 아마도 이런 식으로 하는 것이 슈퍼 미래 증거가 아닐 것이다.

이유는 모르겠지만, 이 솔루션들 중 어느 것도 나에게 효과가 없었기 때문에, 나는 나만의 솔루션을 만들기로 결정했다.

<?php
/**
 * Create a variable product on woocommerce
 * @return int Product ID
 */
function pricode_create_product(){
    $product = new WC_Product_Variable();
    $product->set_description('T-shirt variable description');
    $product->set_name('T-shirt variable');
    $product->set_sku('test-shirt');
    $product->set_price(1);
    $product->set_regular_price(1);
    $product->set_stock_status();
    $product->save();
    return $product;
}

/**
 * Create Product Attributes 
 * @param  string $name    Attribute name
 * @param  array $options Options values
 * @return Object          WC_Product_Attribute 
 */
function pricode_create_attributes( $name, $options ){
    $attribute = new WC_Product_Attribute();
    $attribute->set_id(0);
    $attribute->set_name($name);
    $attribute->set_options($options);
    $attribute->set_visible(true);
    $attribute->set_variation(true);
    return $attribute;
}

/**
 * [pricode_create_variations description]
 * @param  [type] $product_id [description]
 * @param  [type] $values     [description]
 * @return [type]             [description]
 */
function pricode_create_variations( $product_id, $values, $data ){
    $variation = new WC_Product_Variation();
    $variation->set_parent_id( $product_id );
    $variation->set_attributes($values);
    $variation->set_status('publish');
    $variation->set_sku($data->sku);
    $variation->set_price($data->price);
    $variation->set_regular_price($data->price);
    $variation->set_stock_status();
    $variation->save();
    $product = wc_get_product($product_id);
    $product->save();

}
//Adding product
$product = pricode_create_product();

//Creating Attributes 
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);

//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();

//Setting data (following Alexander's rec
$data = new stdClass();
$data->sku = 'sku-123';
$data->price = '10';
//Create variations
pricode_create_variations( $product->get_id(), ['color' => 'red', 'size' => 'M'], $data );

다른 사람들에게 도움이 되길 바랍니다.

Loic Theaztec의 답변을 확장하면, 그의 코드를 다음과 같이 수정하여 속성 조합이 존재하는지 확인할 수 있습니다.

function create_update_product_variation( $product_id, $variation_data ){

    if(isset($variation_data['variation_id'])) {

      $variation_id = $variation_data['variation_id'];

    } else {

      // if the variation doesn't exist then create it

      // Get the Variable product object (parent)
      $product = wc_get_product($product_id);

      $variation_post = array(
          'post_title'  => $product->get_title(),
          'post_name'   => 'product-'.$product_id.'-variation',
          'post_status' => 'publish',
          'post_parent' => $product_id,
          'post_type'   => 'product_variation',
          'guid'        => $product->get_permalink()
      );

      // Creating the product variation
      $variation_id = wp_insert_post( $variation_post );

    }

    // ...

}

사용 예

// The variation data
$variation_data =  array(
    'attributes' => array(
        'size'  => 'M',
        'color' => 'Green',
    ),
    'sku'           => '',
    'regular_price' => '22.00',
    'sale_price'    => '1',
    'stock_qty'     => 1,
);

// check if variation exists
$meta_query = array();
foreach ($variation_data['attributes'] as $key => $value) {
  $meta_query[] = array(
    'key' => 'attribute_pa_' . $key,
    'value' => $value
  );
}

$variation_post = get_posts(array(
  'post_type' => 'product_variation',
  'numberposts' => 1,
  'post_parent'   => $parent_id,
  'meta_query' =>  $meta_query
));

if($variation_post) {
  $variation_data['variation_id'] = $variation_post[0]->ID;
}

create_update_product_variation( $product_id, $variation_data );

WooCommerce에서 테스트용 제품을 생성하고 싶다면 WooCommerce 자체 제작한 WooCommerce Smooth Generator를 사용하면 됩니다.

https://github.com/woocommerce/wc-smooth-generator

예:

// Generate WC_Product object and save it to database
// 70% change generated product is simple
// 30% chance generated product is variable
$product = \WC\SmoothGenerator\Generator\Product::generate();

// Returns WC_Product object of Simple product and don't save it  to database
$product = \WC\SmoothGenerator\Generator\Product::generate_simple_product();

// Returns WC_Product object of Variable Product and saves it to database
$variable_product = \WC\SmoothGenerator\Generator\Product::generate_variable_product();

Src: https://github.com/woocommerce/wc-smooth-generator/blob/master/includes/Generator/Product.php

프로그램을 통해 제품을 만들고 싶다면 필요에 따라 제품 클래스를 만들 수 있습니다.

동작하지만 약간의 수정이 필요합니다(함수 배열에 콤마 2개).필요에 따라 코드를 편집했습니다.

(wp 4.9 | wc 3.5에서 작업)

먼저 제품에 이미 속성이 생성되어 관련지어져 있어야 합니다.제 분류법은 "pa_r" 친화적인 이름 "R" 백엔드 속성 관련지어져 있습니다.

보정을 수반하는 함수

function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);

$variation_post = array(
    'post_title'  => $product->get_title(),
    'post_name'   => 'product-'.$product_id.'-variation',
    'post_status' => 'publish',
    'post_parent' => $product_id,
    'post_type'   => 'product_variation',
    'guid'        => $product->get_permalink()
);

// Creating the product variation
$variation_id = wp_insert_post( $variation_post );

// Get an instance of the WC_Product_Variation object
$variation = new WC_Product_Variation( $variation_id );

// Iterating through the variations attributes
foreach ($variation_data['attributes'] as $attribute => $term_name )
{
    $taxonomy = 'pa_'.$attribute; // The attribute taxonomy

    // If taxonomy doesn't exists we create it (Thanks to Carl F. Corneil)
    if( ! taxonomy_exists( $taxonomy ) ){
        register_taxonomy(
            $taxonomy,
            'product_variation',
            array(
                'hierarchical' => false,
                'label' => ucfirst( $taxonomy ),
                'query_var' => true,
                'rewrite' => array( 'slug' => '$taxonomy') // The base slug
            )
        );
    }

    // Check if the Term name exist and if not we create it.
    if( ! term_exists( $term_name, $taxonomy ) )
        wp_insert_term( $term_name, $taxonomy ); // Create the term

    $term_slug = get_term_by('name', $term_name, $taxonomy )->slug; // Get the term slug

    // Get the post Terms names from the parent variable product.
    $post_term_names =  wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );

    // Check if the post term exist and if not we set it in the parent variable product.
    if( ! in_array( $term_name, $post_term_names ) )
        wp_set_post_terms( $product_id, $term_name, $taxonomy, true );

    // Set/save the attribute data in the product variation
    update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}

## Set/save all other data

// SKU
if( ! empty( $variation_data['sku'] ) )
    $variation->set_sku( $variation_data['sku'] );

// Prices
if( empty( $variation_data['sale_price'] ) ){
    $variation->set_price( $variation_data['regular_price'] );
} else {
    $variation->set_price( $variation_data['sale_price'] );
    $variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );

// Stock
if( ! empty($variation_data['stock_qty']) ){
    $variation->set_stock_quantity( $variation_data['stock_qty'] );
    $variation->set_manage_stock(true);
    $variation->set_stock_status('');
} else {
    $variation->set_manage_stock(false);
}

$variation->set_weight(''); // weight (reseting)

$variation->save(); // Save the data
}

필요한 데이터를 [id_post, attribute, sku, regular_price, stock]바리에이션으로 배열했습니다.

$hijos = array(
[9623,'265/70 R16','NE-CT-CO-USA-016-005','0',53],
[9624,'235/65 R17','NE-AU-CO-EUR-017-050','189000',56]
);

그리고 내 제품의 모든 변형을 역동적으로 만들기 위한 포어치

foreach ($hijos as $vari) {
// The variation data
$variation_data =  array(
    'attributes' => array(
        'r'  => $vari[1],
    ),
    'sku'           => $vari[2],
    'regular_price' => str_replace('.', '', $vari[3]),
    'stock_qty'     => $vari[4]
);
// var_dump($variation_data);
create_product_variation( $vari[0], $variation_data );
}

제품의 분류법이 다른 곳에 미리 등록되어 있지 않으면 여기에서 문제가 발생할 수 있습니다.분류법이 존재하는지 확인하고 싶다면 Loic The Aztec의 답변에 조건을 추가할 수 있습니다.

이런 거.

foreach ($variation_data['attributes'] as $attribute => $term_name )
{
    //echo 'attribute ' . $attribute . ' term name ' . $term_name;

    $taxonomy = 'pa_' . $attribute; // The attribute taxonomy

    // Check if the Taxonomy exists, and if not we create it.

    if (! taxonomy_exists($taxonomy)){
        register_taxonomy(  
            $taxonomy,  //The name of the taxonomy. Name should be in slug form (must not contain capital letters or spaces). 
            'product',        //post type name
            array(  
                'hierarchical' => false,  
                'label' => ucfirst($taxonomy),  //Display name
                'query_var' => true,
                'rewrite' => array(
                    'slug' => $taxonomy, // This controls the base slug that will display before each term
                    'with_front' => false // Don't display the category base before 
                ),
            )  
        ); 

    }
...

위의 답변(Loic Theaztec)은 많은 도움을 주었지만 사용하는 대신 몇 가지 문제가 있었습니다.

update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );

사용방법:
update_post_meta( $variation_id, 'attribute_'.$attribute, $term_name );

분류법이 이미 수정되어 있기 때문에 이 업데이트 값을 변경한 후 포스트 메타를 갱신하는 데 문제가 발생하며 변경 후 관리 제품 변동 편집에서 자동으로 선택하지 않습니다!

커스텀 제품 속성 대신 분류법을 사용하는 Alejandro Giraldo 답변 에 이 수정된 버전을 사용할 수 있습니다.

<?php
/**
 * Create a variable product on woocommerce
 * @return int Product ID
 */
function pricode_create_product(){
    $product = new WC_Product_Variable();
    $product->set_description('T-shirt variable description');
    $product->set_name('T-shirt variable');
    $product->set_sku('test-shirt');
    $product->set_price(1);
    $product->set_regular_price(1);
    $product->set_stock_status();
    return $product->save();
}

/**
 * Create Product Attributes 
 * @param  string $name    Attribute name
 * @param  array $options Options values
 * @return Object          WC_Product_Attribute 
 */
function pricode_create_attributes( $name, $options ){
    $attributes = array();
    if(!empty($options)){
        if(is_string($options)){
            $term = wp_create_term(
                $options,
                wc_attribute_taxonomy_name($name)
            );
            if(is_array($term)){
                $attributes[] = (int)$term['term_id'];
            }
        }
        else{
            for($i = 0; $i < count($options); $i++){
                $term = wp_create_term(
                    $options[$i],
                    wc_attribute_taxonomy_name($name)
                );
                if(is_array($term)){
                    $attributes[] = (int)$term['term_id'];
                }
            }
        }
    }
    $attribute = new WC_Product_Attribute();
    /*
        Set the attribute id to the id of the taxonomy to use
        with wc_attribute_taxonomy_id_by_name you get the id of the taxonomy stored in {$wpdb->prefix}woocommerce_attribute_taxonomies
        with wc_attribute_taxonomy_name you convert the Attribute name to the attribute name woocommerce use 
        @see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_id_by_name
        @see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_name
    /*
    $attribute->set_id(wc_attribute_taxonomy_id_by_name(wc_attribute_taxonomy_name($name)));
    $attribute->set_name(wc_attribute_taxonomy_name($name));
    $attribute->set_options($attributes);
    $attribute->set_visible(true);
    $attribute->set_variation(true);
    return $attribute;
}

/**
 * [pricode_create_variations description]
 * @param  [type] $product_id [description]
 * @param  [type] $values     [description]
 * @return [type]             [description]
 */
function pricode_create_variations( $product_id, $values ){
    $variation = new WC_Product_Variation();
    $variation->set_parent_id( $product_id );
    $variation->set_attributes($values);
    $variation->set_status('publish');
    $variation->set_sku($data->sku);
    $variation->set_price($data->price);
    $variation->set_regular_price($data->price);
    $variation->set_stock_status();
    $variation->save();
    $product = wc_get_product($product_id);
    $product->save();

}
//Adding product
$product = pricode_create_product();

//Creating Attributes 
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);

//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();

//Create variations
pricode_create_variations( $product->get_id(), [wc_attribute_taxonomy_name('color') => sanitize_title('red'), wc_attribute_taxonomy_name('size') => sanitize_title('M')]);

파티에 늦게 도착하지만 새로운 변형이 선택된 속성으로 끝나지 않으면 Loic TheAztec(완벽하게 동작)의 답변에 다음 행을 저장 방법 직전에 사용합니다.

$variation->set_weight(''); //LoicTheAztec 

$variation->set_attributes($variation_data["attributes"]); // Select the attributes

$variation->save(); //LoicTheAztec 

그 받아들여진 물건은 아주 잘 팔린다.바리에이션을 작성하는 데 성공했지만 바리에이션에서 선택한 옵션이 없는 상태에서 하나의 옵션을 저장하려고 하면 이 스레드를 체크하는 것이 좋습니다.Creating WooCommerce product variation addes empty attribute valiation을 체크하면 2시간 이상 같은 문제로 고민하고 있습니다.해피 코딩

이것은 가변 제품을 생성하기 위한 쓰기 방법입니다.

// Name and image would be enough

$product = 새로운 WC_Product_Variable();

$product->set_name( 'Wizard Hat' );
$product->set_image_id( 90 );

// one available for variation attribute
$attribute = new WC_Product_Attribute();
$attribute->set_name( 'Magical' );
$attribute->set_options( array( 'Yes', 'No' ) );
$attribute->set_position( 0 );
$attribute->set_visible( true );
$attribute->set_variation( true ); // here it is
    
$product->set_attributes( array( $attribute ) );

// save the changes and go on
$product->save();

// now we need two variations for Magical and Non-magical Wizard hat
$variation = new WC_Product_Variation();
$variation->set_parent_id( $product->get_id() );
$variation->set_attributes( array( 'magical' => 'Yes' ) );
$variation->set_regular_price( 1000000 ); // yep, magic hat is quite expensive
$variation->save();

$variation = new WC_Product_Variation();
$variation->set_parent_id( $product->get_id() );
$variation->set_attributes( array( 'magical' => 'No' ) );
$variation->set_regular_price( 500 );
$variation->save();

언급URL : https://stackoverflow.com/questions/47518280/create-programmatically-a-woocommerce-product-variation-with-new-attribute-value

반응형