Ask your WordPress questions! Pay money and get answers fast! (more info)

Write and help me set up a cron job on my host

  • SOLVED

My posts are published via the https://wedevs.com/products/plugins/wp-user-frontend-pro/ plugin. Most of these posts are scheduled to be published at a future date, however I use the "[[LINK href="https://wordpress.org/plugins/no-future-posts/"]]No Future Posts[[/LINK]]" plugin to show these scheduled posts immediately (This plugin makes scheduled posts act like current posts and therefore able to be viewed before their publish date).

This is what I'd like...
1. A cron job set up on my host (cpanel) to trash all posts (of a specific post type) X hours after their publish date.
2. I also need help to set this up on my host (i'll show you screenshots only no ftp admin access)

* I would also like a WP version of this that I can insert into my functions.php (I understand the cron in WP only runs when the website is visited)


Answers (2)

2016-05-07

Rempty answers:

You can use a wp cron
use this code in your functions.php


add_action( 'wp', 'cronpost_activation' );
add_action( 'change_post_status', 'change_post_status_action' );

function cronpost_activation() {
if ( !wp_next_scheduled( 'change_post_status' ) ) {
wp_schedule_event( time(), 'hourly', 'change_post_status' );
}
}

function change_post_status_action() {
$cpt="post";
$curr_date = date("Y-m-d H:i:s");

global $wpdb;

$post_ids = $wpdb->get_results( "SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_type='".$cpt."' AND DATE_ADD(post_date, INTERVAL 1 HOUR) <= '".$curr_date."'" );

foreach($post_ids as $pp){
$current_post = get_post( $pp->ID, 'ARRAY_A' );
$current_post['post_status'] = 'draft';
wp_update_post($current_post);
}
}

$cpt= the post type


pjeaje comments:

Where do I set the X hours after?


Rempty comments:

In the SQL
SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_type='".$cpt."' AND DATE_ADD(post_date, INTERVAL 1 HOUR) <= '".$curr_date."'"

"DATE_ADD(post_date, INTERVAL 1 HOUR)"

I am adding 1 hour to the post_date and comparing with the current date, when the post_date + 1 hour is < of the current datetime, select the id and change status to draft


pjeaje comments:

Can I change it to minutes?


Rempty comments:

Also you can change the time of the cron execution

wp_schedule_event( time(), 'hourly', 'change_post_status' );

change "hourly", to "15minutes" or "15seconds",


Rempty comments:

If you want the post published after 15 minutes
SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_type='".$cpt."' AND DATE_ADD(post_date, INTERVAL 15 MINUTE) <= '".$curr_date."'"

Don't forget to change the cron execution time according with your publish time limit


pjeaje comments:

<blockquote>Don't forget to change the cron execution time according with your publish time limit</blockquote>

What does this mean?


Rempty comments:

There is 2 times:
The cron excecution time

wp_schedule_event( time(), 'hourly', 'change_post_status' );

This time the recurrence of the execution of the cron script, each 1hour(hourly), 15 minutes(15minutes),etc the script will be activate and search posts.

And the time of your posts will be active before changed to draft:

SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_type='".$cpt."' AND DATE_ADD(post_date, INTERVAL 15 MINUTE) <= '".$curr_date."'"


Rempty comments:

Here the code trash posts after 90min of published

add_action( 'wp', 'cronpost_activation' );
add_action( 'change_post_status', 'change_post_status_action' );

function cronpost_activation() {
if ( !wp_next_scheduled( 'change_post_status' ) ) {
wp_schedule_event( time(), '5minutes', 'change_post_status' );
}
}

function change_post_status_action() {
$cpt="post";
$expiration_date = date("Y-m-d H:i:s");

global $wpdb;

$post_ids = $wpdb->get_results( "SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_type='".$cpt."' AND DATE_ADD(post_date, INTERVAL 90 MINUTE) <= '".$expiration_date."'" );

foreach($post_ids as $pp){
$current_post = get_post( $pp->ID, 'ARRAY_A' );
$current_post['post_status'] = 'trash';
wp_update_post($current_post);
}
}


pjeaje comments:

let me test it

2016-05-07

dimadin answers:

Here is a quick example using native WordPress functions:



function md_fiveminutes_activation() {
if ( ! wp_next_scheduled( 'md_fiveminutes_event' ) ) {
wp_schedule_event( time(), 'fiveminutes', 'md_fiveminutes_event');
}
}
add_action( 'wp', 'md_fiveminutes_activation' );

function md_add_fiveminutes_interval( $schedules ) {
$schedules['fiveminutes'] = array(
'interval' => 300,
'display' => __( 'Once Every Five Minutes' )
);

return $schedules;
}
add_filter( 'cron_schedules', 'md_add_fiveminutes_interval' );

function md_fiveminutes_event() {
$args = array(
'posts_per_page' => -1,
'fields' => 'ids',
'date_query' => array(
'before' => date_i18n( 'c', strtotime( '-5 hours' ) ),
),
);

$posts = get_posts( $args );

if ( $posts ) {
foreach ( $posts as $post_id ) {
wp_trash_post( $post_id );
}
}
}
add_action( 'md_fiveminutes_event', 'md_fiveminutes_event' );


dimadin comments:

@pjeaje You just change '-5 hours'. Please note that WordPress you might want to change this if it uses time zone.

Also note that this cron runs every five minutes but you can also change it if you change '300' interval.


pjeaje comments:

What is the -5 hours for?
Where do I set the CPT?


dimadin comments:

Also, I forgot to note that by default this works only for 'post' post type, while you can easily change it: http://codex.wordpress.org/Class_Reference/WP_Query#Type_Parameters

Also note that once you add cron you can remove line

add_action( 'wp', 'md_fiveminutes_activation' );


dimadin comments:

For custom post type, you just modify $arg so it looks like:

$args = array(
'posts_per_page' => -1,
'post_type' => 'custom_post_type',
'fields' => 'ids',
'date_query' => array(
'before' => date_i18n( 'c', strtotime( '-5 hours' ) ),
),
);


'-5 hours' in code means that it only searches for posts older than 5 hours. This can be changed.


pjeaje comments:

<blockquote>Also note that once you add cron you can remove line

add_action( 'wp', 'md_fiveminutes_activation' );</blockquote>

Why? Do I need to? What If I don't?


dimadin comments:

@pjeaje

<blockquote>Can I change it to minutes?</blockquote>

Yes, you can change '-5 hours' to something like '-5 minutes' in my code example, see more example: http://php.net/manual/en/function.strtotime.php#example-2562


dimadin comments:

Why? Do I need to? What If I don't?

No, you don't have to, it is unnecessary after first run since you are checking if cron exists on every page load, but you can leave it, there are no problems.


dimadin comments:

Also note that my code example uses native WordPress function to move post to trash, like if you trashed it from WordPress dashboard.


pjeaje comments:

SO... what would the final code be to trash all posts 90 minutes after their publish date? Apart from copying and pasteing this into my functions.php what else do I need to do?


pjeaje comments:

in CPT "XYZ"


dimadin comments:

OK, so this runs every five minutes:


function md_fiveminutes_activation() {
if ( ! wp_next_scheduled( 'md_fiveminutes_event' ) ) {
wp_schedule_event( time(), 'fiveminutes', 'md_fiveminutes_event');
}
}
add_action( 'wp', 'md_fiveminutes_activation' );


function md_add_fiveminutes_interval( $schedules ) {
$schedules['fiveminutes'] = array(
'interval' => 300,
'display' => __( 'Once Every Five Minutes' )
);


return $schedules;
}
add_filter( 'cron_schedules', 'md_add_fiveminutes_interval' );


function md_fiveminutes_event() {
$args = array(
'posts_per_page' => -1,
'post_type' => 'custom_post_type',
'fields' => 'ids',
'date_query' => array(
'before' => date_i18n( 'c', strtotime( '-90 minutes' ) ),
),
);


$posts = get_posts( $args );


if ( $posts ) {
foreach ( $posts as $post_id ) {
wp_trash_post( $post_id );
}
}
}
add_action( 'md_fiveminutes_event', 'md_fiveminutes_event' );


You only need to change '-90 minutes' for one or more hours if your installation uses different time zone, so it can be '-150 minutes', '-210 minutes' etc, but this <strong>doesn't</strong> have to be.


pjeaje comments:

<blockquote> if your installation uses different time zone</blockquote>
if my users post from different time zones? (no they don't)


pjeaje comments:

Can you check the code syntax, it crashes my admin.


dimadin comments:

I have just checked it and there are no errors with error logging on. Have you added <?php at start of the file (if you don't have anything other in it?

Also I have checked, this should cover you for time zone difference so there should be no modifications,


pjeaje comments:

Still crashes, this is my functions.php

[[LINK href="http://pastebin.com/CHdtfCQ9"]]http://pastebin.com/CHdtfCQ9[[/LINK]]


pjeaje comments:

ok it doesn't crash :)


dimadin comments:

Do you have errors logged somewhere? If not, place this in your wp-config.php:


define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);


and then look what is save in wp-content/debug.log (you can remove this after).


dimadin comments:

Ah, no worries then. ;)


pjeaje comments:

let me test it


pjeaje comments:

let me test it