first of all I know that there are already some answered questions about this topic, however I can't find a way that works well in my specific scenario.
My Wordpress theme is using Woocommerce products as events. Below you can see the admin page of the Events menu.
Green square is the part that works. I can add a new product and show it in the table.
Red square is the part where I can add table rows on a button click, and collect it's input values for the AJAX request. These rows represent product variations.
Orange underlines showing the products variations. As you can see I can list them, but these are all added through the Products menu, and not this view.
And there's my problem:
I want the product variations to be updated once the save button on the top was clicked. Below is the code behind the save button, and some comments where I can't proceed.
Note: I always need only one attribute, with a fixed name, and also all variations must be enabled to use "stock".
function empire_ajax_add_post() {
if(!isset($_POST['date']) || !isset($_POST['title'])) {
wp_die();
}
$post = [
'post_author' => get_current_user_id(),
'post_content' => '',
'post_status' => "publish",
'post_title' => $_POST['date'] . ' | ' . $_POST['title'],
'post_parent' => '',
'post_type' => "product",
];
$post_id = wp_insert_post($post, $wp_error);
wp_set_object_terms($post_id, 'variable', 'product_type');
update_post_meta($post_id, '_visibility', 'visible' );
update_post_meta($post_id, '_stock_status', 'instock');
update_post_meta($post_id, 'total_sales', '0');
update_post_meta($post_id, '_downloadable', 'no');
update_post_meta($post_id, '_virtual', 'no');
update_post_meta($post_id, '_regular_price', "1" );
update_post_meta($post_id, '_sale_price', "1" );
update_post_meta($post_id, '_purchase_note', "" );
update_post_meta($post_id, '_featured', "no" );
update_post_meta($post_id, '_weight', "" );
update_post_meta($post_id, '_length', "" );
update_post_meta($post_id, '_width', "" );
update_post_meta($post_id, '_height', "" );
update_post_meta($post_id, '_sku', "");
update_post_meta($post_id, '_sale_price_dates_from', "" );
update_post_meta($post_id, '_sale_price_dates_to', "" );
update_post_meta($post_id, '_price', "1" );
update_post_meta($post_id, '_sold_individually', "" );
update_post_meta($post_id, '_manage_stock', "no" );
update_post_meta($post_id, '_backorders', "no" );
update_post_meta($post_id, '_stock', "" );
wp_set_object_terms($post_id, [], 'pa_idopont');
update_post_meta($post_id, '_product_attributes', [
'idopont' => [
'name' => 'Időpont',
'value' => '',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1',
],
]);
// The array key is always the ID of the parent product ($event)
foreach($_POST['times'] as $event => $data) {
// $data contains the values for variation name, price, and stock
// How to update or insert them here?
}
wp_die();
}
EDIT: I spent about 6 hours to get it to work, finally with success. The linked answer was close enough, however I need to make these changes (Original comments removed for clarity):
function create_product_variation( $product_id, $variation_data ){
$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()
);
$variation_id = wp_insert_post( $variation_post );
$variation = new WC_Product_Variation( $variation_id );
foreach ($variation_data['attributes'] as $attribute => $term_name )
{
// FIRST CHANGE : 'pa_' removed
$taxonomy = $attribute;
if( ! term_exists( $term_name, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy );
$term_slug = get_term_by('name', $term_name, $taxonomy )->slug;
$post_term_names = wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );
// SECOND CHANGE : The next in_array will fail if it's not an array but an object of WP_Error
if(is_wp_error($post_term_names)) {
$post_term_names = [];
}
if( ! in_array( $term_name, $post_term_names ) )
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
// THIRD CHANGE: Save the name instead of the generated slug (which is an empty string in all of my cases)
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_name );
}
## Set/save all other data
// Everything else is correct.
}