Is it possible to leverage WooCommerece API in a seperate, independant PHP file? For example, I want to run a php script that will tally all the sales for the day. The file will reside in the WooCommerence folder but have no connection to the WordPress or WooCommerence install:
e.g. salesTally.php
<?php
//How to include?
global $woocommerce, $post;
$order = new WC_Order($post->ID);
//Do Stuff To Order
?>
Thank you to silver.
Possible solution:
include_once('wp-load.php');
global $woocommerce;
//Search for complete wc_bookings, return a maximum of 200
$orders = get_posts( array(
'post_type' => 'wc_booking',
'post_status' => 'complete',
'posts_per_page' => 200
) );
print_r($orders);
Related
I'm facing the issue in route change by click the apply button, while selecting the move to trash.
NOTE: move to trash and apply process is working by selecting some posts. Bulkly, I trying to move to trash is facing the issue.
url : https://abcd.com/blog/probs/wp-admin/edit.php
After selecting move to trash without selecting any posts and click the apply button url changes to
Incase of delete all posts, I got a route like this
changed url : https://abcd.com/probs//wp-admin/edit.php?paged=1
For this you can try it programmatically by creating your code.
for trashing all the post you try this code:
function move_all_posts_to_trash() {
$args = array(
'post_type' => 'post', // Change this to the post type you want to move to trash
'posts_per_page' => -1, // Get all posts
'post_status' => 'publish' // Only get posts that are published
);
$posts = get_posts( $args );
foreach ( $posts as $post ) {
wp_trash_post( $post->ID ); // Move post to trash
}
}
// If you want to move single post or page you can used by default wordpress function
Basic Example
Trash the default WordPress Post, “Hello World,” which has an ID of ‘1’.
<?php wp_trash_post( $post_id = 1 ); ?>
// For Multiple Posts using WP_Query using while loop.
You can used as per requirement like create shortcode or fire hooks.
function trash_custom_posts() {
$args = array (
'post_type' => 'custom_post_type_slug',
'post_status' => 'publish',
'posts_per_page' => -1
);
$query = new WP_Query( $args );
while( $query->have_posts() ) {
$query->the_post();
$post_id = get_the_ID();
wp_trash_post( $post_id );
}
wp_reset_postdata();
}
add_action( 'init', 'trash_custom_posts' );
The problem
I'm making a plugin. I have a function which goal is to loop throught every post of a given post_type, and store a given metafield value in a different table, along with the ID of the post and the date of the day. To give you some context, it's to keep tracks of products prices.
The function works perfectly when called "manually" with the admin_menu hook, I got my table populated with all the data.
Now I want this function to run once every day so I set up a CRON JOB with wp_schedule_events. WP controls shows the schedule CRON JOB, but the callback function is never executed, and there's no errors, no log whatsoever :/
The Code
The way I scheduled the CRON JOB
function schedule_price_curve_update( $args ) {
if ( ! wp_next_scheduled( 'update_product_price_curve') ) {
$time=time();
$time=$time+60;
wp_schedule_event($time, 'daily', 'update_product_price_curve', $args );
}
}
My callback function to insert data to the dedicated table, and the hook for the CRON Job.
function bulk_update_product_price_curve( $setup_table_name) {
$args = array(
'post_type' => 'bons-plans',
'posts_per_page' => -1,
'post_status' => 'publish',
);
$posts_array = get_posts( $args );
global $wpdb;
$table_name = $wpdb->prefix . $setup_table_name;
$date = date('Y/d/m');
foreach( $posts_array as $post_array ){
$price = get_post_meta( $post_array->ID, 'prix-promo', true);
$wpdb->insert($table_name, array('product_id' => $post_array->ID, 'date' => $date, 'product_price' => $price));;
}
}
add_action( 'update_product_price_curve', 'bulk_update_product_price_curve' );
The $table_name will be setup by user in the admin setting page of the plugin. As of now I set the $arg of the schedule_price_curve_update( $args ) manually. No probleme on this part. Again, WP Control assure me the job is scheduled with the right arguments.
If anyone have any idea of why my callback function is not firing ? That's kind of frustrating as there's no error or nothing to give me any hint on why this isn't working... So there's also that : how can I debug this ?
I'm writing what I thought was a simple series of functions to assign a "deletion date" to media, then auto-delete those expired media when the site is visited.
The post_meta for deletion date is set for the images via an online form when the images are uploaded (using formidable pro forms and the "after_create_entry" hook. I can confirm that the meta field is created successfully, and the deletion date is assigned properly (called 'mtp_deletiondate'. To test, I did a wp_query on a custom page and each image has a properly set deletion date.
Next, I wanted to run a function that checked for expired images (set to be 21 days after date of upload), and if they are expired, to delete them. I want to trigger this function whenever I access the admin, because I figure I get in there at least once a month to run updates, and it's a good time to clean out the old images. For this situation, I decided not to do a cron job since I can reliably visit the site once a month anyway.
The issue is the function doesn't seem to be triggering, and I don't know if it's because the function is broken or because I'm using the wrong action, or both. Some research tells me to use the admin_init, but I've also tried "wp", and "wp-footer". It might be that I'm just misunderstanding the process. My function (in my theme's functions.php):
function drick_delete_expired_uploads() {
// WP_Query arguments
$args = array (
'post_status' => 'any',
'post_type' => array( 'Attachment' ),
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'mtp_deletiondate',
),
),
);
// The Query
$mediaquery = new WP_Query( $args );
// The Loop
if ( $mediaquery->have_posts() ) {
while ( $mediaquery->have_posts() ) {
$mediaquery->the_post();
date_default_timezone_set('America/Denver');
$CurrentDate = date('Y-m-d h:i');
$CurrentDateStr = strtotime($CurrentDate);
$DeletionDate = get_post_meta( $post->ID, 'mtp_deletiondate', true );
$DeletionDateStr = strtotime($DeletionDate);
if ( isset($DeletionDateStr) ) {
if ( $DeletionDateStr < $CurrentDateStr ) {
wp_delete_attachment( $post->ID, true );
}
}
}
} else {
// no posts found
} // IF HAVE POSTS
// Restore original Post Data
wp_reset_postdata();
}
add_action('admin_init', 'drick_delete_expired_uploads');
If I save my functions.php, then reload the Wordpress dashboard, then check my media, the expired images are still there. HOWEVER, if I add this function to an actual page then visit the page, it does work. So I believe the function is doing what it's supposed to, it's just not getting triggered properly? I also added a quick wp_mail() to the function in my functions.php, and when I visited the admin it did trigger the email, so I guess the function is firing.
I would appreciate any insight, thank you!
So I think I figured it out, but I don't know that I have an explanation as to why it works. Essentially it looks like wp_delete_attachment wasn't working, but wp_delete_post DOES work. I've tested and confirmed with three additional images that the function auto delete is triggered when accessing the admin dashboard. I also changed the way the query arguments are structured by only querying the expired images, rather than querying ALL images that have a mtp_deletiondate meta then running a conditional statement within the query. Don't know if that's related or not. The final working function:
function drick_delete_expired_uploads() {
// WP_Query arguments
date_default_timezone_set('America/Denver');
$CurrentDate = date('Y-m-d h:i');
$args = array (
'post_status' => 'any',
'post_type' => array( 'Attachment' ),
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'mtp_deletiondate',
'value' => $CurrentDate,
'compare' => '<',
'type' => 'DATE',
),
),
);
// The Query
$mediaquery = new WP_Query( $args );
// The Loop
if ( $mediaquery->have_posts() ) {
while ( $mediaquery->have_posts() ) {
$mediaquery->the_post();
wp_delete_post(get_the_ID());
}
} else {
// no posts found
} // IF HAVE POSTS
// Restore original Post Data
wp_reset_postdata();
}
add_action('admin_init', 'drick_delete_expired_uploads');
Still look forward to any feedback from someone in the know that can tell me why the previous version wasn't working (looking to learn here). Thanks!
I would like to enable review checkbox permanently for all existing products and for newly added products too. I have looked in WooCommerce settings, but thatís not possible. I have search over internet, and I didnít find anything.
How can I bulk edit all existing products to get reviews Enabled?
When we add a new product it should be automatically checked too.
Is there a way to do it?
Is it possible?
Thanks in advance.
This is possible, but you will need 2 functions. One to update all existing products inn your shop, that you will use only one time, and the other for all newly published products.
Step 1 - Use this just once on function.php and go to front-end and navigate to any page. Once done comment this code or remove it. All your existing products have been updated.
// Updating all products that have a 'comment_status' => 'closed' to 'open'
function updating_existing_products_once(){
$args = array(
// WC product post type
'post_type' => 'product',
// all posts
'numberposts' => -1,
'comment_status' => 'closed',
'post_status' => 'publish',
);
$shop_products = get_posts( $args );
foreach( $shop_products as $item){
$product = new WC_Product($item->ID);
wp_update_post( array(
'ID' => $item->ID,
'comment_status' => 'open',
) );
}
}
// After usage comment this line below
updating_existing_products_once();
Step 2 - This function will update new created products that have a 'comment_status' => 'closed' to 'open' (reviews on WooCommerce)…
add_action('transition_post_status', 'creating_a_new_product', 10, 3);
function creating_a_new_product($new_status, $old_status, $post) {
if( $old_status != 'publish' && $new_status == 'publish' && !empty($post->ID) && in_array( $post->post_type, array( 'product') ) ) {
if ($post->comment_status != 'open' ){
$product = new WC_Product($post->ID);
wp_update_post( array(
'ID' => $post->ID,
'comment_status' => 'open',
) );
}
}
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
In addition to LoicTheAztec's excellent answer, I'd like to add a different option for "Step 1".
You could just run a simple query that doesn't require iterating over a loop:
global $wpdb;
$wpdb->query("UPDATE {$wpdb->posts} SET comment_status = 'open' WHERE post_type = 'product'");
Note the intentional omission of the comment_status and post_status in the WHERE clause. It would not matter that unpublished products have an open comment status, nor would it matter that products that already have comment_status set to open are being re-set to open.
Just add the above code to the bottom of your theme's functions.php file, and then comment them out after it has been run once:
// Commented out so it won't run
// global $wpdb;
// $wpdb->query("UPDATE {$wpdb->posts} SET comment_status = 'open' WHERE post_type = 'product'");
I know it's old question but function below could help someone if LoicTheAztec's answer won't work (like for me). It will check reviews' checkbox by default by using jQuery on "Add product" page. I hope help someone, cheers! :-)
add_action( 'woocommerce_product_options_advanced', 'enable_reviews_by_default' );
function enable_reviews_by_default() {
?>
<script>
(function($){
$('input[name=comment_status]').prop('checked', true);
})(jQuery);
</script>
<?php
}
By the way a dirty method of fixing things immediately (reversable). All credits to a guy Evgeniy
https://developer.wordpress.org/reference/functions/comments_open/
While the original thread discusses how to disable comments everywhere, I reversed the effect :)
This disables the possibility for you to decide on a per-product basis, because overrides the checkbox site-wide!
Disclaimer: do at your own risk!
add_filter( 'comments_open', '__return_true' );
I want to display 3 related product on single page in tabs. I have made a custom custom query like this:
$postid = array(1,2,3);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'post__in' => array_column($postid, 'ID'),
);
$loop = new WP_QUERY($args);
This query works and executes 3 times as well. But in loop I call a another template
wc_get_template_part( 'content', 'single-product-meta-side' );
In content-single-product-meta-side.php the $post variable is reset and returns only the original query post variable.
global $product, $post;
echo $post_id = get_the_ID(); // old/original post id returns
I also tried to setup_postdata( $post ); just after while loop but nothing happens.
Any ideas whats going wrong.
Another query how do I setup the global $product variable.
The function wc_get_template_part uses load_template. This last, requires the template file with some global variables available to ensure that the WordPress environment is available from within the function:
global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
So, either you use the above global variables, or you can locate the file and include it in your scope:
include(locate_template('single-product-meta-side.php'));//Don't forget to set the right path for your file.
I hope this will help you.