Adding availabilities programmatically to a bookable product on Woocommerce Bookings - php

I have a form on a website that allows users to create bookable products. However, I can't find how to create a availability interval using Woocommerce php functions. Does anyone have an idea?
Here's how I create my product
$post_id = wp_insert_post( array(
'post_title' => $_POST["title"],
'post_content' => $_POST["description"],
'post_status' => 'publish',
'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'booking', 'product_type' );
In another part of this same project, I use the get_post_meta function to get the availabilities. I get that the availabilities are meta data from the post but I'm not exacly sure how to change these. I tried using the usual add_post_meta( $post_id, '_wc_booking_availability', $availability ); but that didn't work. Is there something I'm missing about Woocommerce availabilities?
On a side note, is there a more detailed documentation of Woocommerce Booking?
The developer documentation on their website only covers the basics of creating a product programmatically.

I found an answer if anyone else needs it.
//This is the array that will contain all the availabilities
$availabilities = array();
//Create an array that contains the required fields (from_date and to_date are not necessary in some types of availabilities)
$availability = array(
'type' => 'time:range', //Replace time:range with the type you need
'bookable' => 'yes',
'priority' => 10,
'from' => wc_booking_sanitize_time( "01:00" ),
'to' => wc_booking_sanitize_time( "03:00" ),
'from_date' => wc_clean( "2018-10-02" ),
'to_date' => wc_clean( "2018-10-02" )
);
//If you need to add more than one availability, make a loop and push them all into an array
array_push($availabilities, $availability);
add_post_meta( $post_id, '_wc_booking_availability', $availabilities );
I found it here but I modified it for my needs
https://wordpress.stackexchange.com/questions/233904/how-to-add-date-range-in-woocommerce-with-code

Related

How do I create a product with variations?

I'm trying to create a product in php with variations. I've gotten the product creation but I can't seem to figure out how to create variations for it. Googling only returns adding variations to existing products, but I'm trying to create a product completely from scratch, give it an attribute, and using that attribute to make variations from an array of strings.
$team = get_post();
$post_id = wp_insert_post(
array( 'post_title' => $team->post_title,
'post_type' => 'product',
'post_status' => 'publish'
)
);
wp_set_object_terms( $post_id, 'simple', 'variable' );
update_post_meta( $post_id, '_sku', 'FEES-'.$team->ID );
This is what I have so far.
I think you need to use "WC_Product_Variation"class for registering variations and wp_insert_post for creating the product variable.
have a look at this example, it might help you or give an idea.
Create WooCommerce Variable Product with Attributes
See more info in woocommerce docs: WC_Product_Variation

Using update_post_meta when creating a subscription product in WooCommerce

I am currently creating a plugin that collects data from their license plate. Everything works just fine. The post gets created, I receive the ID of the created post and etc. But at the very end of my function.. I'd like to update post meta doing so:
update_post_meta($product_id, '_regular_price', '0');
update_post_meta($product_id, '_subscription_period_interval', '1');
update_post_meta($product_id, '_subscription_period', 'week');
But nothing happens. I've tried running the function again placing the code above somewhere else and that I've tried multiple places inside my code. Even tried creating a whole new function for those 3 lines itself. Still no luck.
I tried returning the post meta from the post that I just created. Looking inside the returned data I see my post_meta was set, but when visiting the post from the WordPress post type archive, the post meta was reset/ignored.
Here's what I'm facing:
As you can see, the post meta is being set but when looking inside my archive... Not set.
I even tried with sleep(3) to make sure the post was created before update_post_meta. No luck.
Any ideas or tips for how I can resolve this?
I'd like to add that by taking these 3 lines and adding them to example: functions.php, and then hardcoding id's then it will work. So the short version is that when creating the post, the 3 lines do nothing even if the id is set correctly. So it has to be something to when creating the post etc...
Edit
You asked to see where the product_id is being set:
$post_data = array(
'post_author' => $author,
'post_name' => $postname,
'post_title' => $data['title'],
'post_content' => $data['content'],
'post_excerpt' => $data['excerpt'],
'post_status' => 'draft',
'ping_status' => 'closed',
'post_type' => 'product',
);
// Creating the product (post data)
$product_id = wp_insert_post( $post_data );
WordPress #WooCommerce
First it seems that you are trying to create a simple subscription product… So you forgot to set the product type which is subscription and also some other things related to product subscription price.:
$post_data = array(
'post_author' => $author,
'post_name' => $postname,
'post_title' => $data['title'],
'post_content' => $data['content'],
'post_excerpt' => $data['excerpt'],
'post_status' => 'draft',
'ping_status' => 'closed',
'post_type' => 'product',
);
// Creating the product (from post data)
$product_id = wp_insert_post( $post_data );
// Set the product type <==== <==== <==== Missing
wp_set_object_terms( $product_id, 'subscription', 'product_type' ); // <== Missing
$product_price = 0;
update_post_meta($product_id, '_regular_price', $product_price);
update_post_meta($product_id, '_price', $product_price); // <== <== <== Missing
update_post_meta($product_id, '_subscription_price', $product_price); // <== Missing
update_post_meta($product_id, '_subscription_period', 'week');
update_post_meta($product_id, '_subscription_period_interval', '1');
It should better work now.

WooCommerce products widget for a specific category - set category array per widget

I had the same question as Quadie as answered in the following thread.
The code as provided by LoicTheAztec works great...
add_filter( 'woocommerce_products_widget_query_args', function( $query_args ){
// Set HERE your product category slugs
$categories = array( 'music', 'posters' );
$query_args['tax_query'] = array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $categories,
));
return $query_args;
}, 10, 1 );
... but I would like to know if there is an option to extend this code to be able to set the categories per seperate widget. E.g. I want a products widget for category 1 on a page x, while I want a products widget for category 2 somewhere else on page x.
I was thinking about using a shortcode & specifying the category as an array for this shortcode, but not sure on how to implement this.
Any thoughts on this issue?
This is the shortcode I tried to use:
[productsbycat cat1="broodjes"]
& it triggers the following code:
function productsbycat_func( $atts ) {
$categories = shortcode_atts( array(
'cat1' => 'something',
'cat2' => 'something else',
), $atts );
add_filter( 'woocommerce_products_widget_query_args', function ( $query_args ){
$query_args['tax_query'] = array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $categories,
));
return $query_args;
}, 10, 1 );
}
add_shortcode( 'productsbycat', 'productsbycat_func' );
However, it does not generate anything yet.
Is not possible to extend my code "to be able to set the categories per seperate widget".
For your shortcode only I think that you don't need any code customization for that.
I you look to the WooCommerce Official documentation related to WooCommerce Shortcodes, you will see on section "Product category" this short code: [product_category], which main argument is category
You can add one product category slugs this way:
[product_category category="clothing"] // One product category
Or for many product categories slugs (coma separated) this way:
[product_category category="posters,music"]
The default arguments settings (that you can change) are:
$args = array(
'per_page' => "12",
'columns' => "4",
'orderby' => 'title', // or by "menu_order"
'order' => "asc", // or "desc"
'category' => "" // Always only product category slugs
'operator' => "IN" // Possible values are "IN", "NOT IN", "AND".
);
But it will not work as you would like in your product widgets as it will display the product grid loop for the defined categories
You should need to build your own widgets.

WP_Query and WooCommerce orders with pending status issue

I can't get order objects with status of wc-pending / Pending Payment. It simply returns ALL the order objects:
$my_course_query = new WP_Query( array(
'post_type' => 'shop_order',
'post_status' => 'wc-pending',
'posts_per_page' => -1
) );
Your code Is just working perfectly as expected, in frontend, I have test it and it output only orders with **pending status. So I can't tell what is your issue as your question is not detailed.
I have found this note on WordPress WP_Query reference that could be useful:
Note: Ticket #18408 For querying posts in the admin, consider using get_posts() as wp_reset_postdata() might not behave as expected.
In general, I don't use WP_Query() for customer orders but wc_get_orders() (or get_posts() too) this way:
$customer_orders = wc_get_orders( array(
'limit' => -1,
'status' => 'pending'
) );
// Iterating through each Order with pending status
foreach ( $customer_orders as $order ) {
// Going through each current customer order items
foreach($order->get_items() as $item_id => $item_values){
$product_id = $item_values['product_id']; // product ID
// Order Item meta data
$item_meta_data = wc_get_order_item_meta( $item_id );
// Some output
echo '<p>Line total for '.wc_get_order_item_meta( $item_id, '_line_total', true ).'</p><br>';
}
}
This works also just to get the orders objects.
Related documentation: wc_get_orders and WC_Order_Query
I fixed this weird issue by simply using custom query.
Somehow adding 'post_status' => 'wc-pending' doesn't actually change the query, but if I use 'post_status' => 'pending', the query changes.
So what I did was using that custom query and modify pending to wc-pending.
I do have the same issue (returning ALL Orders) while debugging.
Wrapping the debug-code into an action helped outputting the expected data:
add_action( 'init', 'debug_init' );
function debug_init() {
$custom_query_args = array(
"fields" => "ids",
"post_type" => "shop_order",
"post_status" => array('wc-processing'),
"posts_per_page" => "-1",
"offset" => "0",
"date_query" => [
"before" => "2020-09-10 23:59",
"after" => "1970-01-01 00:00",
"inclusive" => "1"
],
"order" => "DESC"
);
$debugQuery = new WP_Query( $custom_query_args );
$order_ids = $debugQuery->posts;
print_r($order_ids);
die();
}

automatically inserted woocommerce product still needs update?

In Wordpress, I have a function which allows me to automatically add a woocommerce product by adding a new post of a custom post type called 'daily_cartoon'.
This the code of the function:
function convert_daily_cartoon_into_product($post_id){
if( ( $_POST['post_status'] == 'publish' ) && ( $_POST['original_post_status'] != 'publish' ) ) {
// Create post object
$post = array(
'post_title' => $_POST['post_title'],
'post_type' => 'product',
'post_status' => 'publish',
'tax_input' => array( 'product_cat' => 14 )
);
// Insert the post into the database
$new_print = wp_insert_post( $post );
update_post_meta( $new_print, '_thumbnail_id', get_post_thumbnail_id( $post_id ) );
update_post_meta( $new_print, '_regular_price', 5 );
update_post_meta( $new_print, '_price', 5 );
}
}
add_action('publish_daily_cartoon', 'convert_daily_cartoon_into_product');
The new product shows up nicely in the admin area, with all the data there - i.e. price, category, published, etc.
But for some reason it doesn't show up on the website shop page until I open the new product to edit and click update.
Anybody?
Make sure you set the _visibility meta of the product to visible
For those comming here
Don't forget to check your datas, I got a similar problem and it's because WP sanitize datas once you update them manually from the dashboard. That's why it worked for those updated manually.
Into my database, my datas got some hidden spaces (example : "Paris" / " Paris").
In case you need to import products, consider to use the wp function sanitize_text_field()

Categories