wordpress Woocommerce编程添加产品属性及其相应的值

guykilcj  于 2023-05-16  发布在  WordPress
关注(0)|答案(2)|浏览(293)

我正在构建一个获取产品的脚本,我被困在以编程方式添加属性的部分。所以基本上我想检查一个属性是否存在,如果不存在就添加它。然后检查它的价值是否存在,如果不存在,他们就添加它的价值,并将所有内容附加到我的产品上。
以下是我得到的产品格式:

[attributes] => Array
(
[0] => stdClass Object
    (
        [id] => 332
        [name] => Gender
        [value] => Woman
    )

[1] => stdClass Object
    (
        [id] => 333
        [name] => Wheel Size
        [value] => 28 Inch
    )

[2] => stdClass Object
    (
        [id] => 334
        [name] => Frame height
        [value] => 56 cm
    )

现在我已经尝试了2个版本,我会粘贴两个代码样本。

版本1:

foreach($product->attributes as $attribute) {
$slug = 'pa_' . strtolower($attribute->name);
$attribute_name = $attribute->name;
$attribute_value = $attribute->value;

$permalinks = get_option( 'woocommerce_permalinks' );

$taxonomy_data = array(
                    'hierarchical'          => true,
                    'update_count_callback' => '_update_post_term_count',
                    'labels'                => array(
                            'name'              => $attribute_name
                        ),
                    'show_ui'           => false,
                    'query_var'         => true,
                    'sort'              => false,
                    'public'            => true,
                    'show_in_nav_menus' => false,
                    'capabilities'      => array(
                        'manage_terms' => 'manage_product_terms',
                        'edit_terms'   => 'edit_product_terms',
                        'delete_terms' => 'delete_product_terms',
                        'assign_terms' => 'assign_product_terms',
                    )
                );

register_taxonomy( $slug, array('product'), $taxonomy_data );
// @end_Debug

}
这个版本只添加了以某种方式附加到产品的属性,但它们在Wordpress管理员的属性选项卡下不可见。我以后会想要这些属性的过滤器,所以我需要与Woocommerce属性的连接。

版本2:

foreach($product->attributes as $attribute) {
$slug = 'pa_' . strtolower($attribute->name);
$attribute_name = $attribute->name;
$attribute_value = $attribute->value;
$table = $wpdb->prefix . 'woocommerce_attribute_taxonomies';

$attr = $wpdb->get_results( "SELECT * FROM {$table} WHERE attribute_name LIKE '%{$attribute_name}%'", OBJECT );
if(count($attr) > 0) {
    //
}
else {
    /** create taxonomy */
    $data = array(
        'attribute_label'   => $attribute_name,
        'attribute_name'    => $slug,
        'attribute_type'    => 'select',
        'attribute_orderby' => 'menu_order',
        'attribute_public'  => 0, // Enable archives ==> true (or 1)
    );

    $results = $wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $data );

    if ( is_wp_error( $results ) ) {
        return new WP_Error( 'cannot_create_attribute', $results->get_error_message(), array( 'status' => 400 ) );
    }

    $id = $wpdb->insert_id;

    do_action('woocommerce_attribute_added', $id, $data);

    wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
    /* end_Create */
}

// Clean attribute name to get the taxonomy
$taxonomy = 'pa_' . wc_sanitize_taxonomy_name( $attribute_name );

$option_term_ids = array(); // Initializing

// Loop through defined attribute data options (terms values)
if( term_exists( $attribute_value, $taxonomy ) ){
    // Save the possible option value for the attribute which will be used for variation later
    wp_set_object_terms( $product_id, $attribute_value, $taxonomy, true );
    // Get the term ID
    $option_term_ids[] = get_term_by( 'name', $attribute_value, $taxonomy )->term_id;
}

    // Loop through defined attribute data
$attributes[$taxonomy] = array(
    'name'          => $taxonomy,
    'value'         => $option_term_ids, // Need to be term IDs
    'position'      => '1',
    'is_visible'    => '1',
    'is_variation'  => '1',
    'is_taxonomy'   => '1'
);

// Save the meta entry for product attributes
update_post_meta( $product_id, '_product_attributes', $attributes );

}
这一个似乎只添加他们下的产品属性选项卡,也没有添加条款值。

t30tvxxf

t30tvxxf1#

好吧,这是一个相当复杂的任务,但这是我通过查看其他人的源代码并根据需要进行修改而获得的代码。
首先,您需要这些helper函数。
1.要创建全局属性,您需要使用以下函数为每个属性(性别、车轮大小等)创建一个分类:

function create_global_attribute($name, $slug)
{

    $taxonomy_name = wc_attribute_taxonomy_name( $slug );

    if (taxonomy_exists($taxonomy_name))
    {
        return wc_attribute_taxonomy_id_by_name($slug);
    }

    //logg("Creating a new Taxonomy! `".$taxonomy_name."` with name/label `".$name."` and slug `".$slug.'`');

    $attribute_id = wc_create_attribute( array(
        'name'         => $name,
        'slug'         => $slug,
        'type'         => 'select',
        'order_by'     => 'menu_order',
        'has_archives' => false,
    ) );

    //Register it as a wordpress taxonomy for just this session. Later on this will be loaded from the woocommerce taxonomy table.
    register_taxonomy(
        $taxonomy_name,
        apply_filters( 'woocommerce_taxonomy_objects_' . $taxonomy_name, array( 'product' ) ),
        apply_filters( 'woocommerce_taxonomy_args_' . $taxonomy_name, array(
            'labels'       => array(
                'name' => $name,
            ),
            'hierarchical' => true,
            'show_ui'      => false,
            'query_var'    => true,
            'rewrite'      => false,
        ) )
    );

    //Clear caches
    delete_transient( 'wc_attribute_taxonomies' );

    return $attribute_id;
}

1.现在把这些应用到你的产品上,我假设你使用的是变量产品,每个产品都有变化?父变量产品需要将其attribute属性设置为一个特殊格式的属性数组。此函数创建该数组,如果没有找到每个属性,则为它们创建全局分类法。

//$rawDataAttributes must be in the form of array("Color"=>array("blue", "red"), "Size"=>array(12,13,14),... etc.)
function generate_attributes_list_for_product($rawDataAttributes)
{
    $attributes = array();

    $pos = 0;

    foreach ($rawDataAttributes as $name => $values)
    {
        if (empty($name) || empty($values)) continue;

        if (!is_array($values)) $values = array($values);

        $attribute = new WC_Product_Attribute();
        $attribute->set_id( 0 );
        $attribute->set_position($pos);
        $attribute->set_visible( true );
        $attribute->set_variation( true );

        $pos++;

        //Look for existing attribute:
        $existingTaxes = wc_get_attribute_taxonomies();

        //attribute_labels is in the format: array("slug" => "label / name")
        $attribute_labels = wp_list_pluck( $existingTaxes, 'attribute_label', 'attribute_name' );
        $slug = array_search( $name, $attribute_labels, true );

        if (!$slug)
        {
            //Not found, so create it:
            $slug = wc_sanitize_taxonomy_name($name);
            $attribute_id = create_global_attribute($name, $slug);
        }
        else
        {
            //Otherwise find it's ID
            //Taxonomies are in the format: array("slug" => 12, "slug" => 14)
            $taxonomies = wp_list_pluck($existingTaxes, 'attribute_id', 'attribute_name');

            if (!isset($taxonomies[$slug]))
            {
                //logg("Could not get wc attribute ID for attribute ".$name. " (slug: ".$slug.") which should have existed!");
                continue;
            }

            $attribute_id = (int)$taxonomies[$slug];
        }

        $taxonomy_name = wc_attribute_taxonomy_name($slug);

        $attribute->set_id( $attribute_id );
        $attribute->set_name( $taxonomy_name );
        $attribute->set_options($values);

        $attributes[] = $attribute;
    }

    return $attributes;
}

1.我们几乎已经准备好将属性应用于产品,但是主变量产品及其变体需要像任何Wordpress分类一样为其分配分类术语。因此,如果您有一个名为“Wheel Size”的分类,其中包含术语“28 Inch”和“30 Inch”,则父产品需要为其分配所有“28 Inch”和“30 Inch”术语,并且变体需要为其分配各自的术语,因此“28 Inch”表示一个,“30 Inch”表示另一个。为了帮助实现这一点,我们使用此函数来获取和/或创建这些术语(如果它们不存在):

function get_attribute_term($value, $taxonomy)
{
    //Look if there is already a term for this attribute?
    $term = get_term_by('name', $value, $taxonomy);

    if (!$term)
    {
        //No, create new term.
        $term = wp_insert_term($value, $taxonomy);
        if (is_wp_error($term))
        {
            //logg("Unable to create new attribute term for ".$value." in tax ".$taxonomy."! ".$term->get_error_message());
            return array('id'=>false, 'slug'=>false);
        }
        $termId = $term['term_id'];
        $term_slug = get_term($termId, $taxonomy)->slug; // Get the term slug
    }
    else
    {
        //Yes, grab it's id and slug
        $termId = $term->term_id;
        $term_slug = $term->slug;
    }

    return array('id'=>$termId, 'slug'=>$term_slug);
}

好了,现在我们可以使用上面的方法将属性应用到我们的产品中。
对于主变量产品:

$yourRawAttributeList = array("Gender" => array("Woman", "Man"), "Wheel Size" => array("28 Inch","30 Inch","32 Inch"));
$attribs = generate_attributes_list_for_product($yourRawAttributeList);

$p = new WC_Product_Variable($postID);

$p->set_props(array(
    'attributes'        => $attribs,
    //Set any other properties of the product here you want - price, name, etc.
));

$postID = $p->save();

if ($postID <= 0) return "Unable to create / update product!";

//Attribute Terms: These need to be set otherwise the attributes dont show on the admin backend:
foreach ($attribs as $attrib)
{
    /** @var WC_Product_Attribute $attrib */
    $tax = $attrib->get_name();
    $vals = $attrib->get_options();

    $termsToAdd = array();

    if (is_array($vals) && count($vals) > 0)
    {
        foreach ($vals as $val)
        {
            //Get or create the term if it doesnt exist:
            $term = get_attribute_term($val, $tax);

            if ($term['id']) $termsToAdd[] = $term['id'];
        }
    }

    if (count($termsToAdd) > 0)
    {
        wp_set_object_terms($postID, $termsToAdd, $tax, true);
    }
}

对于该产品的每个变体:

//This is an array of input attributes in the form: array("Color"=>"Navy", "Size"=>"25")
$theseAttributes = array("Gender" => array("Woman"), "Wheel Size" => array("28 Inch"));

//This is the final list of attributes that we are calculating below.
$theseAttributesCalculated = array();

//logg("Want to add these attributes to the variation: ".print_r($theseAttributes, true));

$existingTax = wc_get_attribute_taxonomies();

foreach ($theseAttributes as $name => $value)
{
    if (strlen($name) == 0 || strlen($value) == 0)
    {
        //logg("Attribute array had a blank value for product variant ".$sku.': '.print_r($theseAttributes, true));
        return "Attribute array had a blank value.";
    }

    $tax = '';
    $slug = '';

    //Look for an existing taxonomy to match this attribute's $name
    //$thistax->attribute_name = slug of the taxonomy
    //$thistax->attribute_label = name of the taxonomy

    foreach ($existingTax as $thistax)
    {
        if ($thistax->attribute_label == $name)
        {
            $slug = $thistax->attribute_name;
            $tax = wc_attribute_taxonomy_name($slug);
            break;
        }
    }

    if (empty($tax))
    {
        $slug = wc_sanitize_taxonomy_name($name);
        //Taxonomy not found, so create it...
        if (create_global_attribute($name, $slug) > 0)
        {
            $tax = wc_attribute_taxonomy_name($slug);
        }
        else
        {
            //logg("Unable to create new attribute taxonomy ".$slug." for attribute ".$name."found in variable product ".$sku);
            continue;
        }
    }

    //logg("Want to add attribute ".$name. " value ".$value. " which is term ".$term_slug." (".$termId.") to post ".$parentID);

    $term = get_attribute_term($value, $tax);

    if ($term['id'])
    {
        // Set/save the attribute data in the product variation
        $theseAttributesCalculated[$tax] = $term['slug'];
    }
    else
    {
        //logg("Warning! Unable to create / get the attribute ".$value." in Taxonomy ".$tax);
    }
}

//logg("Finished gathering. Results: ".print_r($theseAttributesCalculated, true));

$variation  = new \WC_Product_Variation($postID);

$variation->set_props( array(
    'attributes'        => $theseAttributesCalculated,
));

$postID = $variation->save();

if ($postID <= 0) return "Unable to create product variation!";
oyxsuwqo

oyxsuwqo2#

如果有人正在寻找解决方案来创建属性,并且在产品上创建或更新相应的值,则这里是代码的修改版本。

// Create Product attributes if not exist 
function create_product_attribute( $label_name ){
    global $wpdb;

    $slug = sanitize_title( $label_name );

    if ( strlen( $slug ) >= 28 ) {
        return new WP_Error( 'invalid_product_attribute_slug_too_long', sprintf( __( 'Name "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) );
    } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) {
        return new WP_Error( 'invalid_product_attribute_slug_reserved_name', sprintf( __( 'Name "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) );
    } elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $label_name ) ) ) {
        return new WP_Error( 'invalid_product_attribute_slug_already_exists', sprintf( __( 'Name "%s" is already in use. Change it, please.', 'woocommerce' ), $label_name ), array( 'status' => 400 ) );
    }

    $data = array(
        'attribute_label'   => $label_name,
        'attribute_name'    => $slug,
        'attribute_type'    => 'select',
        'attribute_orderby' => 'menu_order',
        'attribute_public'  => 0, // Enable archives ==> true (or 1)
    );

    $results = $wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $data );

    if ( is_wp_error( $results ) ) {
        return new WP_Error( 'cannot_create_attribute', $results->get_error_message(), array( 'status' => 400 ) );
    }

    $id = $wpdb->insert_id;

    do_action('woocommerce_attribute_added', $id, $data);

    wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );

    delete_transient('wc_attribute_taxonomies');
}

//take attributes array with values and attached with the products 
function pswc_attach_terms_value_with_product($product_id, $attributes){
    
    $_the_att_data = array();
    foreach($attributes as $attribute_k => $attribute_v){
        
        if($attribute_v !==''){

            $_att_name = 'pa_'.$attribute_k;

            //check and Create attribute if not exist by providing attribute name 
            create_product_attribute( $attribute_k);
            
            $term_taxonomy_ids = wp_set_object_terms( $product_id, $attribute_v, $_att_name, true );
           //build array of attribute with name and values
            $_the_att_data[$_att_name] = array(
               'name'=>$_att_name,
               'value'=>$attribute_v,
               'is_visible' => '1',
               'is_taxonomy' => '1'
             );
        }
    }
    //Update Product attributes array with the product
    update_post_meta( $product_id,'_product_attributes',$_the_att_data); 
}

    //create product 
    // Get the product ID from the Created Woo Product 

    //set product attribute Names with Terms 
    $attributes = array('color'=>'red','size'=>'small','delivery'=>'express','design'=>'yes',);
    
    // Provide Product_id and attributes array with name as key and option value as value to save with product
    pswc_attach_terms_value_with_product($product_id, $attributes);

提供Product_id和属性数组,以名称为键,选项值为值,与产品一起保存。如果属性存在或不存在,此函数将触发上述两个函数的第一次检查。如果不是,则将注册并创建一个,之后第二个函数将从属性数组中获取值,并与产品一起保存/附加

//设置产品属性名称和术语值

$attributes = array('color'=>'red','size'=>'small','delivery'=>'express','design'=>'yes'); 
//Function to Pass the Product ID and Attribute key value array 
pswc_attach_terms_value_with_product($product_id, $attributes);

您可以在apifixer博客上阅读全文Read the Full Artcicle

相关问题