Update custom field with Cron Job in WordPress - wordpress

I am trying to setup a cron job for a custom post type (Job Listings), that contains two ACF custom fields.
Datepicker – User can choose closing date of the job ( ‘job_listing_closing_date’ )
Radio field – Open & Closed choices. ( ‘job_listing_status’ )
I need the radio field to change from ‘Open’ to ‘Closed’ in the backend post edit screen if the job_listing_closing_date has passed. Here is my code at the moment which is located within ‘/wp-content/themes/themename/assets/functions/cpt-job-listings.php file.
I’ve added the below to code to the website but nothing happens.
Maybe the query is wrong or the ACF fields aren’t available in the file I have coded in?
// Create a cron job in order to check the custom field of 'job_listing_closing_date' against today's date. If the date has passed, set the job status to 'closed' and display different content on front-end.
// Scheduled Action Hook
function check_job_end_date( ) {
// WP_Query arguments
$listings = array (
'post_type' => 'job_listings',
'posts_per_page' => -1,
'meta_key' => 'job_listing_closing_date',
'meta_query' => array(
'key' => 'job_listing_closing_date',
'value' => date( 'Ymd' ),
'compare' => '<',
'type' => 'NUMERIC',
)
);
global $post;
if ($listings->have_posts()) {
while ($listings->have_post()) {
$listings->the_post();
update_field('job_listing_job_status', 'Closed');
//update_post_meta($post->ID, 'job_listing_job_status', 'Closed');
}
wp_reset_postdata();
}
}
// Schedule Cron Job Event
function job_listing_cron_job() {
if ( ! wp_next_scheduled( 'check_job_end_date' ) ) {
wp_schedule_event( date( 'Ymd' ), 'daily', 'check_job_end_date' );
}
}

I ended up rewriting most of the code and this is what worked:
// Create a cron job in order to check the custom field of 'job_listing_closing_date' against today's date. If the date has passed, set the job status to 'closed' and display different content on front-end.
// Scheduled Action Hook
function check_job_end_date( ) {
global $post;
$args = array(
'post_type' => 'job_listings',
'posts_per_page' => -1,
);
$listings = get_posts( $args );
foreach($listings as $post) : setup_postdata($post);
$today = date( 'Ymd' );
$expire = get_field( 'job_listing_closing_date', false, false );
$status = get_field( 'job_listing_job_status' );
if ( $expire < $today ) :
$status = 'Closed';
update_field( 'job_listing_job_status', $status );
endif;
endforeach;
}
// Schedule Cron Job Event
if ( ! wp_next_scheduled( 'job_listing_cron_job' ) ) {
wp_schedule_event( date( 'Ymd' ), 'daily', 'job_listing_cron_job' );
}
add_action( 'job_listing_cron_job', 'check_job_end_date' );

Try this:
$listings = array (
'post_type' => 'job_listings',
'posts_per_page' => -1,
'meta_key' => 'job_listing_closing_date',
'meta_query' => array(
'key' => 'job_listing_closing_date',
'value' => date( 'Ymd' ),
'compare' => '<',
'type' => 'DATE',
)
);
And sure is the correct date format date( 'Ymd' )

Related

Automatic deletion of published WordPress posts

I have created a custom post similar to WordPress posts that I want to delete automatically every time (for example, every day or every week).
Is there a function for this?
I know that you can delete trash posts with the following function
define('EMPTY_TRASH_DAYS', 10 );
But what about custom created posts?
Thanks for your help
I think, this code will full fill your requirements.
// Define the custom post type that you want to delete automatically
$custom_post_type = 'your_custom_post_type';
// Function to delete the custom post type posts
function delete_custom_post_type_posts() {
// Get all published posts of the custom post type
$current_date = current_time('Y-m-d');
$yesterday_date = date('Y-m-d', strtotime('-1 day', strtotime($current_date)));
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
'after' => $yesterday_date,
'before' => $current_date,
'inclusive' => true
)
);
$my_posts = get_posts( $args );
// Loop through the posts and delete them
foreach ( $my_posts as $my_post ) {
wp_delete_post( $my_post->ID, true );
}
}
// Schedule the event to run every week
if ( ! wp_next_scheduled( 'delete_custom_post_type_posts_event' ) ) {
wp_schedule_event( time(), 'twicedaily', 'delete_custom_post_type_posts_event' );
}
// Hook the function to the scheduled event
add_action( 'delete_custom_post_type_posts_event', 'delete_custom_post_type_posts' );```
You can delete published posts every week by setting up a wp_schedule_event
Hope this code helps
// Define the custom post type that you want to delete automatically
$custom_post_type = 'your_custom_post_type';
// Function to delete the custom post type posts
function delete_custom_post_type_posts() {
// Get all published posts of the custom post type
$current_date = current_time('Y-m-d');
$last_week_date = date('Y-m-d', strtotime('-1 week', strtotime($current_date)));
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
'after' => $last_week_date,
'before' => $current_date,
'inclusive' => true
)
);
$posts = get_posts( $args );
// Loop through the posts and delete them
foreach ( $posts as $post ) {
wp_delete_post( $post->ID, true );
}
}
// Schedule the event to run every week
if ( ! wp_next_scheduled( 'delete_custom_post_type_posts_event' ) ) {
wp_schedule_event( time(), 'weekly', 'delete_custom_post_type_posts_event' );
}
// Hook the function to the scheduled event
add_action( 'delete_custom_post_type_posts_event', 'delete_custom_post_type_posts' );

Sort products by most viewed

I'm using a plugin that already count product views and store it in a table called 'mwb_wpr_data'.
The query to list the product views is:
SELECT DISTINCT('productid') FROM 'mwb_wpr_data' WHERE 'action' = 'view'
The productid field is a FK to Woocomerce products.
How can I modify the Woocommerce default sorting, so it will display products by order of most views based in the table 'mwb_wpr_data'?
Current code using the plugin Post View Counter:
add_action( 'pre_get_posts', 'my_view_filter' );
function my_view_filter($query){
if (
$query->is_main_query() &&
( $query->is_home() || $query->is_archive() || $query->is_search() )
) {
$query->set('suppress_filters', 'false');
$query->set('orderby', 'post_views');
$query->set('order', 'DESC');
}
}
According to me you have set the correct pre_get_post but problem is in your if condition.
You have set the current_user_can which not correct filter is for every user so if you are not login in with administrator role than your query will not work.
current_user_can('administrator')
Remove this above one from the condition.
add_action( 'pre_get_posts', 'my_view_filter' );
function my_view_filter($query){
if ($query->is_main_query() && ( $query->is_home() || $query->is_archive() || $query->is_search() )
) {
$query->set('suppress_filters', 'false');
$query->set('orderby', 'post_views');
$query->set('order', 'DESC');
}
}
Ok, so the RIGHT way to do this would be
Change how your post view counts are stored, so that they are stored as postmeta of each product (post) in a field like _post_views_count.
Use meta_key & orderby in wp_query like this
$args = array(
'meta_key' => '_post_views_count',
'orderby' => 'meta_value_num',
'order' => 'ASC'
);
< EDIT >
IF you want to use the same plugin for recording your product views, I'd set up a function that fires every time a post view is added to the table that updates a postmeta field of the product.
Is it elegant? No.
Will it work? Yes.
Not sure about the plugin you're using (it would be great if you give additional info about it) but I've been using Post Views Counter for years and it works really well.
It even has a query parameter for WP_Query (to query posts by post views):
EDIT: This query parameter won't work without the Post Views Counter plugin as it's not a WordPress default parameter.
More info about this plugin API here:
https://dfactory.eu/docs/post-views-counter/developers-api/
$query_args = array(
'posts_per_page' => 12,
'order' => 'DESC',
'suppress_filters' => false, //required param
'orderby' => 'post_views', //required param
);
$query = new WP_Query( $query_args );
if ( $query->have_posts() ):
while ( $query->have_posts() ): $query->the_post();
//Post content here
echo get_the_title();
endwhile;
endif;
I hope this helps,
Cheers!
According to the plugins documentation you are required to pass the post_type as well in order for this to work, i.e.
$args = array(
'order' => 'asc',
'post_type' => 'event',
// required by PVC
'suppress_filters' => false,
'orderby' => 'post_views',
'fields' => ''
);
$most_viewed = get_posts( $args );
That code is in the post that #Marounm linked to in comment higher up.
Try passing the post_type arg as well i.e.
$query->set('post_type', 'product');
If you want to showing the the products which was most viewed , so you can follow these below steps .
Steps :1 I have add menu in admin panel using (add_menu_page) function. in function file
function admin_manage_users22(){
add_menu_page('My Page Title', 'MVP', 'manage_options', 'MVP_backend_view',
'MVP_backend_view' );
}
add_action('admin_menu', 'admin_manage_users22');
Step :2 Get product details after user view product it's +1 counter value in wp_postmeta with post id. default value set 1
function MVP_product_details($product ) {
$post_id = get_the_ID();
$count_key = 'AK_product_view_count';
$count = get_post_meta( $post_id, $count_key, true );
if ( empty( $count ) ) {
delete_post_meta( $post_id, $count_key );
update_post_meta( $post_id, $count_key, '1' );
echo "count null";
}else{
$count ++;
update_post_meta( $post_id, $count_key, (string) $count );
}
}
add_filter( 'woocommerce_quantity_input_args', 'MVP_product_details', 10, 2 );
Step :3 Now you can get most viewed product details simply using below code.
function MVP_backend_view(){
$count_key = 'AK_product_view_count';
$query_args = array(
'posts_per_page' => 3,
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => $count_key,
);
$query_args['meta_query'] = array(
array(
'key' => $count_key,
'value' => '0',
'type' => 'numeric',
'compare' => '>',
),
);
$zwcmvp_query = new WP_Query( $query_args );

2 pre_get_posts functions to filter by custom fields

EDIT: See the last (3rd) code snippet, it's the working one.
I have an "Actions" page (an archive for a custom post type called Actions), which is an equivalent to "events".
I used this tutorial to filter them with custom fields: ville (city), action (type of action) and date and it works perfectly.
Then I created another function to filter by "date range": past, future actions. And it also works. But they "accumulate". When I select "Past" actions and a city, it shows me ALL past actions + ALL actions that happened or will happen in a city.
So these two functions work, but I don't know how to set their relation to AND or something that makes them work together instead of "accumulating".
Can someone please help me figure this out ?
Thank you.
Function to filter by Type/City/Date custom fields:
// array of filters (field key => field name)
$GLOBALS['my_query_filters'] = array(
'action' => 'action',
'ville' => 'ville',
'date' => 'date',
);
// action
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);
function my_pre_get_posts( $query ) {
// bail early if is in admin
if( is_admin() ) return;
// bail early if not main query
// - allows custom code / plugins to continue working
if( !$query->is_main_query() ) return;
// get meta query
$meta_query = $query->get('meta_query');
// loop over filters
foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: http://www.website.com/events?city=melbourne,sydney
$value = explode(',', $_GET[ $name ]);
// append meta query
$meta_query[] = array(
'key' => $name,
'value' => $value,
'compare' => 'IN',
);
}
$query->set( 'orderby', array( 'date' => 'DESC' ) );
// update meta query
$query->set('meta_query', $meta_query);
return;
}
?>
Function for Future/Past actions:
<?php
add_action('pre_get_posts', 'future_past_actions', 10, 1);
function future_past_actions( $query ) {
// bail early if is in admin
if( is_admin() ) return;
// bail early if not main query
// - allows custom code / plugins to continue working
if( !$query->is_main_query() ) return;
// get meta query
$meta_query = $query->get('meta_query');
if( isset($_GET['range']) ) {
$range = explode(',', $_GET['range']);
$meta_query[] = array(
'key' => 'range',
'value' => $range,
'compare' => 'IN',
);
if( $query->get( 'range' ) == 'future' ) {
$meta_query[] = array(
'key' => 'date',
'value' => date("Ymd"),
'compare' => '>',
);
$meta_query['relation'] = 'OR';
}
elseif( $query->get( 'range' ) == 'past' ) {
$meta_query[] = array(
'key' => 'date',
'value' => date("Ymd"),
'compare' => '<',
);
$meta_query['relation'] = 'OR';
}
elseif( $query->get( 'range' ) == 'toutes' ) {
return;
}
}
$query->set( 'meta_key', 'date' );
$query->set( 'orderby', array( 'date' => 'DESC' ) );
$query->set('meta_query', $meta_query);
return;
}
?>
The final merged and working code:
<?php
// array of filters (field key => field name)
$GLOBALS['my_query_filters'] = array(
'action' => 'action',
'ville' => 'ville',
'date' => 'date'
);
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);
function my_pre_get_posts( $query ) {
// bail early if is in admin
if( is_admin() ) return;
// bail early if not main query
// - allows custom code / plugins to continue working
if( !$query->is_main_query() ) return;
if( ! is_post_type_archive( 'actions' ) ) return;
// CITY/TYPE/DATE filters
// loop over filters
foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) { continue; }
// get the value for this filter
// eg: http://www.website.com/events?city=melbourne,sydney
$value = explode(',', $_GET[ $name ]);
// append meta query
$meta_query[] = array(
'key' => $name,
'value' => $value,
'compare' => 'IN',
);
}
// FUTURE/PAST/ALL filters
if( isset($_GET['range']) ) {
$range = $_GET['range'];
if($range != "toutes") {
// Select what kind of compare you need
if($range == "past") {
$comparer = '<';
} else if($range == "future") {
$comparer = '>=';
}
// If you need to filter by date add this to meta_query array
$meta_query[] = array(
'key' => 'date',
'value' => date("Ymd"),
'compare' => $comparer,
);
}
}
// update meta query
$query->set('meta_query', $meta_query);
$query->set( 'meta_key', 'date' );
$query->set( 'orderby', array( 'date' => 'DESC' ) );
$query->set('posts_per_page', '20');
}
?>
In this case best solution in my opinion is to have one action and check query arguments inside of it and then decide what kind of logic you want to do.
$query variable has all the arguments you assign, so your code might look something like this:
Editing considering the comments on situation, you have to use AND relation between two meta fields. Code inside action should look like this:
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);
function my_pre_get_posts( $query ) {
$meta_query = array(
'relation' => 'AND',
array(
'key' => 'ville',
'value' => '$value',
'compare' => '=',
)
);
// Select what kind of compare you need
if($range == "past") {
$compare = ">";
} else if($range == "future") {
$compare = "<";
}
if($range != "all") {
// If you need to filter by date add this to meta_query array
$date_query = array(
'key' => 'date',
'value' => 'date(\"Ymd\"),',
'compare' => $compare,
);
$meta_query[] = $date_query;
}
$query->set( 'orderby', array( 'date' => 'DESC' ) );
// update meta query
$query->set('meta_query', $meta_query);
}
Because what you do now, you set query arguments multiple times.
If you need more parameters to filter out you can add them conditionally to $meta_query variable considering what kind of parameters you get.
I think if I understand correctly this kind of meta query should return needed results.

wordpress how to get yesterday published post ids

Is there any function to get yesterday published all post ids?
I always need yesterday or specific days post ids.
Example: today is: 01/04/2017 , i need all published post ids which published on 31/03/2017
Try this code.
<?php
$today = getdate();
$y_posts_ids = array();
$agrs = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'year' => $today['year'],
'month' => $today['mon'],
'day' => $today['mday'] - 1,
),
),
);
$loop = new WP_Query( $agrs );
if( $loop->have_posts() ) :
while( $loop->have_posts() ) : $loop->the_post();
$y_posts_ids[] = get_the_ID();
endwhile;
endif;
wp_reset_postdata();
?>
You can use the date parameters of get_posts to find this:
<?php
// Get the date pieces using the timezone you set in WordPress, minus one day
$yesterday = getdate( current_time() - DAY_IN_SECONDS );
// Query for posts from yesterday
$yesterdays_posts = get_posts( array(
'date_query' => array(
array(
'year' => $yesterday[ 'year' ],
'month' => $yesterday[ 'mon' ],
'day' => $yesterday[ 'mday' ]
)
),
'nopaging' => true
) );
This will give you an array of post objects from yesterday. nopaging means "give me all of them". Now, you can iterate through the results. If you just need the IDs, you can add them to an array like this:
<?php
$yesterdays_posts_ids = array();
if( $yesterdays_posts ){
foreach( $yesterdays_posts as $yesterdays_post ){
$yesterdays_posts_ids[] = $yesterdays_post->ID;
}
}

Group Posts by meta_query

I'm trying to group my posts by a meta value, and can't seem to figure it out. My query below just returns "featured" posts. I would like the query to return all posts, but have the "featured" results before the rest.
Any ideas?
$args = array(
'posts_per_page' => '20',
'paged' => $current_page,
'meta_query' => array(
array(
'key' => 'tags',
'value' => 'featured',
'compare' => 'like'
)
),
'order_by' => 'date',
'order' => 'DESC'
);
Your answer is rewind_posts(). Run your query to get all the posts, run your loop and filter out all posts which is not featured, rewind the loop, rerun the loop and filter out featured posts.
Something like this will do
$args = [
// Your query arguments to get all postst
];
$q = new WP_Query( $args );
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
if ( get_post_meta( $post->ID, 'tags', true ) == 'featured' ) {
// Run your loop for featured posts
}
}
$q->rewind_posts(); // Rewind the loop to rerun it
while ( $q->have_posts() ) {
$q->the_post();
if ( get_post_meta( $post->ID, 'tags', true ) != 'featured' ) {
// Run your loop for non featured posts
}
}
wp_reset_postdata();
}

Resources