php - Cree programáticamente una variación de producto de WooCommerce con nuevos valores de atributo



wordpress variations (4)

Actualización de septiembre de 2018: Manejo de la creación de taxonomías (Gracias a Carl F. Corneil)

A partir de una ID de producto variable definida, encontrará a continuación, una función personalizada que agregará (creará) una variación de Producto. El producto primario variable necesita tener establecidos los atributos necesarios.

Deberá proporcionar cierta información como:

  • la matriz de atributos / valores
  • el Sku, precios y stock ...

Estos datos deben almacenarse en una matriz multidimensional formateada (vea un ejemplo al final) .

Esta función verificará si los valores de los atributos (nombre del término) ya existen y, de no ser así: - lo crea para el atributo del producto - lo establece en la variable producto principal.

El código de función personalizado:

/**
 * 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_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( $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
}

El código va en el archivo function.php de su tema secundario activo (o tema) o también en cualquier archivo de complemento.

Uso (ejemplo con 2 atributos):

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

Probado y funciona.

Parte 2: cree mediante programación un producto variable y dos nuevos atributos en Woocommerce

Obtendrá esto en el backend:

Y funcionará perfectamente en la parte delantera.

Relacionado: Cree programáticamente un producto utilizando métodos CRUD en Woocommerce 3

He creado un producto variable (producto "padre") en WooCommerce versión 3+. Desde un complemento de WordPress, me gustaría crear mediante programación las variaciones del producto (producto "secundario") con nuevos valores de atributo.

Los atributos de variación ya están establecidos en WooCommerce.
Por lo tanto, cada vez que se crea una variación, los valores del nuevo atributo también deben crearse mediante programación y establecerse en el producto Variable principal.

¿Cómo se puede hacer esto? ¿Es posible?

Actualización: había escrito más líneas de códigos sobre esto que deseaba, e intenté muchas cosas para resolverlo, usando objetos de woocommerce, y agregué datos faltantes sobre términos, termmeta, la relación de término con publicación, en la base de datos usando la base de datos de WordPress objeto, pero nada ha sido suficiente para que funcione. Y no pude precisar dónde me equivoqué, es por eso que no pude proporcionar un problema más limitado, cosas para las cuales el stackoverflow está más hecho.


Answer #1

Ampliando la respuesta de LoicTheAztec, puede verificar si la combinación de atributos existe con la siguiente modificación a su código.

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

    }

    // ...

}

Ejemplo de uso

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

Answer #2

Si desea generar productos para probar en WooCommerce, puede usar WooCommerce Smooth Generator , creado por el propio WooCommerce.

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

Ejemplo:

// 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

Si desea crear productos mediante programación, puede Clase de producto con sus necesidades.


Answer #3

Solo voy a lanzar esto, ya que no pude lograr que ninguno de los ejemplos anteriores funcionara. No me preguntes por qué otras personas parecen tener éxito. Entonces, tomé el enfoque minimalista y traté de descubrir lo esencial para un atributo del producto + variación (creándolo manualmente en wp y mirando el db) y se me ocurrió esto.

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

    }
...

Esto no está utilizando atributos globales del producto, sino específicos del artículo. Espero que ayude a alguien, ya que estaba a punto de arrancarme el cabello antes de hacerlo funcionar.





variations