Wordpress Woocommerce - use update_post_meta to add product attributes
Right so it took me a while to figure it out myself but I finally managed to do this by writing the following function:
// @param int $post_id - The id of the post that you are setting the attributes for
// @param array[] $attributes - This needs to be an array containing ALL your attributes so it can insert them in one go
function wcproduct_set_attributes($post_id, $attributes) {
$i = 0;
// Loop through the attributes array
foreach ($attributes as $name => $value) {
$product_attributes[$i] = array (
'name' => htmlspecialchars( stripslashes( $name ) ), // set attribute name
'value' => $value, // set attribute value
'position' => 1,
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 0
);
$i++;
}
// Now update the post with its new attributes
update_post_meta($post_id, '_product_attributes', $product_attributes);
}
// Example on using this function
// The attribute parameter that you pass along must contain all attributes for your product in one go
// so that the wcproduct_set_attributes function can insert them into the correct meta field.
$my_product_attributes = array('hdd_size' => $product->hdd_size, 'ram_size' => $product->ram_size);
// After inserting post
wcproduct_set_attributes($post_id, $my_product_attributes);
// Woohay done!
I hope this function will help other people if they need to import multiple attributes pro-grammatically in WooCommerce!
Adding multiple product attributes to Woocommerce
I found the solution on https://stackoverflow.com/a/45475863/12092133.
I took my form variables and threw them into an array, and then ran this foreach and it did the trick.
$my_product_attributes['condition'] = $_POST['condition'];
$my_product_attributes['genre'] = $_POST['genre'];
$my_product_attributes['authors'] = $_POST['author'];
foreach ($my_product_attributes as $key => $value) {
$key = 'pa_' . $key;
$attribute_values = explode(",", $value);
wp_set_object_terms($product_id, $attribute_values, $key, false);
$thedata[sanitize_title($key)] = Array(
'name' => wc_clean($key),
'value' => $attribute_values,
'postion' => '0',
'is_visible' => '1',
'is_variation' => '0',
'is_taxonomy' => '1'
);
update_post_meta($product_id, '_product_attributes', $thedata);
}
WooCommerce: Add a product attribute to the existing ones in a product
You need to get existing product attributes first and insert your new product attribute in the array before saving it. Also I have added 2 missing arguments in the array…
So your code should be:
$product_id = get_the_ID();
$taxonomy = 'pa_keywords';
$clean_keywords = array('cake','cup cakes');
$term_taxonomy_ids = wp_set_object_terms( $product_id, $clean_keywords, $taxonomy, true );
// Get existing attributes
$product_attributes = get_post_meta( $product_id, '_product_attributes', true);
// get the count of existing attributes to set the "position" in the array
$count = count($product_attributes);
// Insert new attribute in existing array of attributes (if there is any)
$product_attributes[$taxonomy] = array(
'name' => $taxonomy,
'value' => '',
'position' => $count, // added
'is_visible' => '0',
'is_variation' => '0', // added (set the right value)
'is_taxonomy' => '1'
);
// Save the data
update_post_meta( $product_id, '_product_attributes', $product_attributes );
This should work now without removing existing data.
WooCommerce: Add attribute to product on save if it's not set
First $post is not object. Will return ID which is fine.
add_action('woocommerce_update_product', 'save_product_region');
function save_product_region( $product_id ) {
//Get product object from the ID
$_product = wc_get_product($product_id);
$attributes = $_product->get_attributes();
$add_option = wp_set_object_terms( $product_id, 'canada', 'pa_region', true );
$curr_options = $attributes['pa_region']['options'];
//Check if we have this attribute set already
if(!in_array($add_option,$curr_options)):
$updated_options = array_push($curr_options,$add_option);
$data = array(
'pa_region' => array(
'name'=>'pa_region',
'options'=> $updated_options,
'is_visible' => '1',
'is_variation' => '0',
'is_taxonomy' => '1'
)
);
//First getting the Post Meta
$_product_attributes = get_post_meta($product_id, '_product_attributes', TRUE);
//Updating the Post Meta
update_post_meta($product_id, '_product_attributes', array_merge($_product_attributes, $data));
endif;
}
Add Product Attributes with values to a product in Woocommerce
There is some mistakes in your code. Your main mistake: The attribute terms to save as product meta data (at the end) need to be an array of term IDs (instead of term names).
Try the following revisited code:
$product_id = 11874;
$attributes_data = array(
array('name'=>'Size', 'options'=>array('S', 'L', 'XL', 'XXL'), 'visible' => 1, 'variation' => 1 ),
array('name'=>'Color', 'options'=>array('Red', 'Blue', 'Black', 'White'), 'visible' => 1, 'variation' => 1 )
);
if( sizeof($attributes_data) > 0 ){
$attributes = array(); // Initializing
// Loop through defined attribute data
foreach( $attributes_data as $key => $attribute_array ) {
if( isset($attribute_array['name']) && isset($attribute_array['options']) ){
// Clean attribute name to get the taxonomy
$taxonomy = 'pa_' . wc_sanitize_taxonomy_name( $attribute_array['name'] );
$option_term_ids = array(); // Initializing
// Loop through defined attribute data options (terms values)
foreach( $attribute_array['options'] as $option ){
if( term_exists( $option, $taxonomy ) ){
// Save the possible option value for the attribute which will be used for variation later
wp_set_object_terms( $product_id, $option, $taxonomy, true );
// Get the term ID
$option_term_ids[] = get_term_by( 'name', $option, $taxonomy )->term_id;
}
}
}
// Loop through defined attribute data
$attributes[$taxonomy] = array(
'name' => $taxonomy,
'value' => $option_term_ids, // Need to be term IDs
'position' => $key + 1,
'is_visible' => $attribute_array['visible'],
'is_variation' => $attribute_array['variation'],
'is_taxonomy' => '1'
);
}
// Save the meta entry for product attributes
update_post_meta( $product_id, '_product_attributes', $attributes );
}
Tested and works.
Note: All product attributes and their values need to be defined (with your actual code)
Related: Create new product attribute programmatically in Woocommerce
How update product attributes programmatically?
You could simply backup your DB content before updating, like this:
$tmpBk = get_post_meta($post_id, '_product_attributes',true);
update_post_meta($post_id, '_product_attributes', array_merge(tmpBk,$product_attributes) );
that should be enough to save your previously stored values
Related Topics
PHP E-Mail Form Sender Name Instead of E-Mail
PHP Switch Case More Than One Value in the Case
PHP Password_Hash and Password_Verify Issues No Match
Conditional Statements in PHP Code Between HTML Code
Updating Column So That It Contains the Row Position
Certificate Error Using Imap in PHP
Using '$This' in an Anonymous Function in PHP Pre 5.4.0
How to Send the Values of an Array of Checkboxes Through Ajax Using Jquery
Pdo Bindparam into One Statement
Search and Replace Value in PHP Array
Xml Parser Error: Entity Not Defined