I need to change the last modified date and time of all of my blog's posts in WordPress. So far i have....
add_action( 'wp', 'asd' );
function asd()
{
$post_list = get_posts( array(
'post_per_page' => '-1'
) );
foreach ( $post_list as $post ) {
// $posts[] += $post->ID;
$postID = $post->ID;
$datetime = date( 'Y-m-d H:i:s', current_time( 'timestamp', 0 ) );
echo $postID . ' ||| ' . $datetime . '<br>';
global $wpdb;
$wpdb->query( "UPDATE `$wpdb->posts` SET `post_modified` = '" . $datetime . "' WHERE ID = " . $postID);
}
}
I get no errors or whatsoever. I am using "echo" for debugging purposes. I have two problems.
I have 6 posts and i get only 5
It seems that no update is happening in the database, for the last modified field
Any help would be appreciated.
you use this code.( paste it in your theme function.php)
add_action('init','change_mypost_date');
function change_mypost_date(){
$args = array(
'post_type' => 'property_listing',
'posts_per_page' => -1
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$datetime = date( 'Y-m-d H:i:s', current_time( 'timestamp', 0 ) );
$current_post = array(
'ID' => get_the_ID(),
'post_modified' => $datetime
);
// Update the post into the database
wp_update_post( $current_post );
}
wp_reset_postdata();
}
}
You are looking to update all of your posts' date to current datetime. So, the solution is without requiring any loops:
add_action( 'init', function () {
$hook = 'run_snippet_daily';
$args = array();
if ( ! wp_next_scheduled( $hook, $args ) ) {
wp_schedule_event( time(), 'daily', $hook, $args );
}
} );
add_action( 'run_snippet_daily', function () {
$datetime = date( 'Y-m-d H:i:s', current_time( 'timestamp', 0 ) );
global $wpdb;
$wpdb->query( "UPDATE `$wpdb->posts`
SET `post_date`='{$datetime}',
`post_modified` ='{$datetime}'
WHERE `post_type`= 'post' ");
} );
Related
I am having issues with the functionality of my code. The custom post should expire after a certain number of days. At the moment it’s set to 3 days just so I can test it.
But the posts are expiring even though the expiry date is before today's date, and I can’t figure out why?!
// Setup Cron Job Function to expire posts and send out emails.
function listing_expiry_date() {
// Get the current date
date_default_timezone_set('Europe/London');
$today = date('m/d/Y');
// Custom Post Type for listings, grab published posts
$args = array(
'post_type' => array( 'post_type_listings' ),
'post_status' => array( 'Publish' ),
'posts_per_page' => -1,
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
// Get the listing ID
$post_id = get_the_ID();
// Get listing post published date (not pending date)
$published_date = get_the_date( 'm/d/Y', get_the_ID() );
$expiry_date = date( 'm/d/Y', strtotime( '+3 days', strtotime($published_date) ) );
// If todays date is equal to or greater than the expiry date...
if ( ($today == $expiry_date) || ($today > $expiry_date) ) :
// change post status to 'expired'
$postdata = array(
'ID' => $post_id,
'post_status' => 'expired',
);
// Update post data
wp_update_post($postdata);
endif;
endwhile; //endwhile The Loop
endif; //endif The Loop
}
IT seems your issue would be how you're evaluating the dates. In this case, it would be best to use a Unix timestamp to evaluate which is greater.
function listing_expiry_date() {
// Get the current date.
date_default_timezone_set( 'Europe/London' );
$today = date( 'U' );
// Custom Post Type for listings, grab published posts.
$args = array(
'post_type' => array( 'post_type_listings' ),
'post_status' => array( 'publish' ),
'posts_per_page' => -1,
);
// The Query.
$query = new WP_Query( $args );
// The Loop.
if ( $query->have_posts() ) :
while ( $query->have_posts() ) :
$query->the_post();
// Get the listing ID.
$post_id = get_the_ID();
$expiry_date = date( 'U', strtotime( '+3 days', get_the_date( 'U', $post_id ) ) );
// If Expiration date is < or = today.
if ( $expiry_date <= $today ) :
// change post status to 'expired'
$postdata = array(
'ID' => $post_id,
'post_status' => 'expired',
);
// Update post data.
wp_update_post($postdata);
endif;
endwhile; // endwhile The Loop.
endif; // endif The Loop.
}
I will try to explain what my goal is and what i already did.
I am importing a bunch of products into WooCommerce, but now i would like to add a function, that does set the product category automatically to "NEW IN" if the product is not older than 60 days. After the 60 days it should be moved out of that category again.
To be said, i am in the learning process of php with WordPress and WooCommerce, so i am sorry if i don't know certain things.
function add_product_to_new_in()
{
global $product;
// Get the date for the product published and current date
$start = date('n/h/Y', strtotime($product->get_date_created()));
$today = date('n/j/Y');
// Get the date for the start of the event and today's date
$start = new \DateTime($start);
$end = new \DateTime($today);
//FInd the difference
$difference = $start->diff($end);
$days = $difference->d;
// If the difference is less than 60, apply "NEW IN cat"
if ($days = (60 < $days)) {
wp_set_object_terms($product, 40, 'product_cat');
}
}
If you can help me in any way, i would appreciate it!
You can do this on the init hook that fires every time on page load.
First, you have to get all products.
$args = array(
'post_type' => 'product',
'posts_per_page' => -1
);
$products = new WP_Query( $args );
if ( $products->have_posts() ) { while ( $products->have_posts() ) { $products->the_post();
// your logic will go here.
} wp_reset_postdata(); }
Now calculate days.
$product = wc_get_product( get_the_ID() );
$datetime = $product->get_date_created();
$timezone = $datetime->getTimezone();
$now_time = new WC_DateTime();
$now_time->setTimezone($timezone);
$timestamp_diff = $now_time->getTimestamp() - $datetime->getTimestamp();
$data = timestamp_to_array( $timestamp_diff );
$days = $data['d'];
Then you can use wp_set_object_terms and wp_remove_object_terms to set and remove category.
// If the difference is less than 60, apply "NEW IN cat"
if ( $days < 60 ) {
wp_set_object_terms( get_the_ID(), 40, 'product_cat', true );
}else{
wp_remove_object_terms( get_the_ID(), 40, 'product_cat' );
}
Complete code. add this below code in your active theme functions.php file.
function add_category_to_product_for_certain_days(){
$args = array(
'post_type' => 'product',
'posts_per_page' => -1
);
$products = new WP_Query( $args );
if ( $products->have_posts() ) { while ( $products->have_posts() ) { $products->the_post();
$product = wc_get_product( get_the_ID() );
$datetime = $product->get_date_created();
$timezone = $datetime->getTimezone();
$now_time = new WC_DateTime();
$now_time->setTimezone($timezone);
$timestamp_diff = $now_time->getTimestamp() - $datetime->getTimestamp();
$data = timestamp_to_array( $timestamp_diff );
$days = $data['d'];
// If the difference is less than 60, apply "NEW IN cat"
if ( $days < 60 ) {
wp_set_object_terms( get_the_ID(), 40, 'product_cat', true );
}else{
wp_remove_object_terms( get_the_ID(), 40, 'product_cat' );
}
} wp_reset_postdata(); }
}
add_action( 'init', 'add_category_to_product_for_certain_days', 10, 1 );
function timestamp_to_array( $timestamp ) {
$d = floor($timestamp/86400);
$_d = ($d < 10 ? '0' : '').$d;
$h = floor(($timestamp-$d*86400)/3600);
$_h = ($h < 10 ? '0' : '').$h;
$m = floor(($timestamp-($d*86400+$h*3600))/60);
$_m = ($m < 10 ? '0' : '').$m;
$s = $timestamp-($d*86400+$h*3600+$m*60);
$_s = ($s < 10 ? '0' : '').$s;
return array('d' => $_d, 'h' => $_h, 'm' => $_m, 's' => $_s);
}
Tested and works.
I have written a bulk import script where I import posts with the wp_insert_post() function using taxonomy names. Basically there are 4000 cities, and I want to add them as posts such as:
New York to London
New York to Amsterdam
New York to Berlin
etc...
But I'm getting an internal server error after adding a few thousand posts. I expect the total posts added to be 16,000,000 [4,000 * 4,000]
Here is the code:
<?php
require_once "wp-load.php";
ini_set("memory_limit",-1);
set_time_limit(0);
ignore_user_abort(true);
$term_query = new WP_Term_Query( array( 'taxonomy' => 'cities' ) );
if ( ! empty( $term_query->terms ) ) {
wp_defer_term_counting( true );
define( 'WP_IMPORTING', true );
foreach ( $term_query ->terms as $term ) {
$city1 = $term->name;
foreach ( $term_query ->terms as $inner_city ) {
$city2 = $inner_city->name;
$postTitle = $city1 . ' to ' . $city2;
$postSlug = $city1 . '-to-' . $city2;
$LowerPostSlug = strtolower($postSlug);
$post_args = array(
'post_title' => $postTitle,
'post_status' => 'publish',
'post_name' => $postSlug,
'post_author' => $user_ID,
'post_type' => 'conversion',
);
$found_post_title = get_page_by_title( $postTitle, OBJECT, 'city_post' );
$found_post_id = $found_post_title->ID;
if ( FALSE === get_post_status( $found_post_id ) ):
$returned_post_id = wp_insert_post( $post_args );
update_field( 'city_1', $city1, $returned_post_id ); # SET CUSTOM FIELD FOR city 1
update_field( 'city_2', $city2, $returned_post_id ); # SET CUSTOM FIELD FOR city 2
echo $postTitle . '</br>';
endif;
}
}
wp_defer_term_counting( false );
}
Why can't I retrieve the data from a Woocommerce checkout field to update subscription data as the order processes?
I want to update the next renewal date based on the customers' frequency request on checkout. Here is my code:
1) Set up the checkout field:
add_action( 'woocommerce_after_order_notes', 'hgf_custom_checkout_field' );
function hgf_custom_checkout_field( $checkout ) {
global $woocommerce;
woocommerce_form_field( 'frequency', array(
'type' => 'select',
'required' => true,
'class' => array('form-row-wide'),
'label' => __('Change this any time, just email.'),
'options' => array(
'blank' => __( 'Select frequency preference', 'woocommerce' ),
1 => __( 'Every Week', 'woocommerce' ),
2 => __( 'Every Other Week' , 'woocommerce' ),
3 => __( 'Once Per Month' , 'woocommerce' )
)
), $checkout->get_value( 'frequency' ));
echo '</div>';
}
2) Update the order meta. This creates two custom fields on the customer order, as well as updates the billing interval on the subscription:
add_action( 'woocommerce_checkout_update_order_meta', 'hgf_checkout_field_update_order_meta' );
function hgf_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['frequency'] ) ) {
update_post_meta( $order_id, 'frequency', $_POST['frequency'] );
update_post_meta( $order_id, 'billing_interval', $_POST['frequency'] );
}
}
3) Update the renewal date
For the last part, I can update the renewal date with a dummy date of my choosing (for instance: $renewal date = "2018-12-15", but when I try to get it to read the 'billing_interval' field, it reverts to the else default.
add_action( 'woocommerce_checkout_create_subscription', 'hgf_next_renewal' );
function hgf_next_renewal( $subscription, $timezone='site' ) {
$billing_interval = get_post_meta( get_the_ID(), 'billing_interval', true);
if( $billing_interval == 2 ) {
$renewal_date = date( 'Y-m-d H:i:s', strtotime( "2017-10-01" ) ) /* date( 'Y-m-d H:i:s', strtotime( "+2 weeks" ) ) */ ;
} if( $billing_interval == 4 ) {
$renewal_date = date( 'Y-m-d H:i:s', strtotime( "2017-12-01" ) ) /* date( 'Y-m-d H:i:s', strtotime( "+4 weeks" ) ) */ ;
} else {
$renewal_date = date( 'Y-m-d H:i:s' ) ) /* date( 'Y-m-d H:i:s', strtotime( $renewal_date) ) */ ;
}
$subscription->update_dates( array(
'next_payment' => $renewal_date,
) );
return $subscription;
}
This is all the different ways I have tried:
1) $billing_interval = $subscription->get_billing_interval();
2) $billing_interval = get_post_meta( $subscription->get_ID(), 'billing_interval', true);
3) $billing_interval = get_post_meta( $order_id, 'billing_interval', true);
4) $subscriptions = wcs_get_users_subscriptions( $user_id );
foreach ( $subscriptions as $sub ) {
$billing_interval = get_post_meta( $sub->get_order_number(), '_billing_interval', true);
}
5) $billing_interval = $checkout->get_value( 'frequency' );
Does anyone know why I can't retrieve a value from my checkout field while in the 'woocommerce_checkout_create_subscription' action?
As you are saving your 'billing_interval' custom field in the Order meta data, you can't get this custom field through the subscription object or ID… You need to get first the Parent Order ID.
To get the parent Order ID from the subscription object you need to use the WC_Order method get_parent_id()
add_action( 'woocommerce_checkout_create_subscription', 'hgf_next_renewal' );
function hgf_next_renewal( $subscription, $timezone='site' ) {
// MISSING!: The parent order ID to set below
$order_parent_id = $subscription->get_parent_id();
$billing_interval = get_post_meta( $order_parent_id, 'billing_interval', true);
if( $billing_interval == 2 ) {
$renewal_date = date( 'Y-m-d H:i:s', strtotime( "2017-10-01" ) ) /* date( 'Y-m-d H:i:s', strtotime( "+2 weeks" ) ) */ ;
} elseif( $billing_interval == 4 ) {
$renewal_date = date( 'Y-m-d H:i:s', strtotime( "2017-12-01" ) ) /* date( 'Y-m-d H:i:s', strtotime( "+4 weeks" ) ) */ ;
} else {
$renewal_date = date( 'Y-m-d H:i:s', strtotime( "2017-09-01" ) ) /* date( 'Y-m-d H:i:s' ) */ ;
}
$subscription->update_dates( array(
'next_payment' => $renewal_date,
) );
return $subscription;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
I haven't tested your code for real, but it doesn't throw any error and should work for you this time.
I would like to filter the WP_Query to retrive all woocommerce order (post_type = shop_order) with particular status that are older than 15 minutes.
I.e. All posts that have been last modified on or before (now - 15 minutes ) // Hope I'm clear.
Below What I've tried
function filter_where($where = '') {
//posts in the last 15 minutes
$where .= " AND post_modified > '" . date('Y-m-d', strtotime('INTERVAL 15 MINUTE')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => 10,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('completed')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
print_r("<pre>");
print_r($order);
print_r("</pre>");
endwhile;
However that returns all record, Seems like have to modify the $where query, how can i achieve that ?
Do you need to filter the posts_where? Can't you just use date query parameters? In your case, specifically before.
$args = array(
'date_query' => array(
array(
'before' => '15 minutes ago'
'inclusive' => true,
),
),
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
I can't test this right now, so can't verify if it would work. If you are modifying an archive then you should definitely adjust the query via pre_get_posts in lieu of creating new query.
try this change date('Y-m-d', strtotime('INTERVAL 15 MINUTE')) to date('Y-m-d H:i:s', strtotime('-15 minutes'))
function filter_where($where = ''){
//posts in the last 15 minutes
$where .= " AND post_modified > '" . date('Y-m-d H:i:s', strtotime('-15 minutes')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');