Although I do not understand the motivation for truncating posts, I think this exercise is valuable for you to understand how to use cron + WordPress.
Create a function to truncate posts
This can be used for both methods below WP-cron or UNIX cron.
function foobar_truncate_posts(){
global $wpdb;
# Set your threshold of max posts and post_type name
$threshold = 50;
$post_type="foobar";
# Query post type
$query = "
SELECT ID FROM $wpdb->posts
WHERE post_type="$post_type"
AND post_status="publish"
ORDER BY post_modified DESC
";
$results = $wpdb->get_results($query);
# Check if there are any results
if(count($results)){
foreach($result as $post){
$i++;
# Skip any posts within our threshold
if($i <= $threshold)
continue;
# Let the WordPress API do the heavy lifting for cleaning up entire post trails
$purge = wp_delete_post($post->ID);
}
}
}
Here are the two basic approaches to scheduling events in WordPress.
Approach #1: Using WP-Cron
Since this is the WP way of doing this, we’ll look at this approach first. Please note, WP Cron is not true cron, and it’s oft called psuedo-cron. It is not consistent if you have low traffic on a site as it is based on requests to the server. If no requests come in, then your scheduled event runs late.
Schedule your event
if(!wp_next_scheduled( 'foobar_truncate_posts_schedule')){
wp_schedule_event(time(), 'daily', 'foobar_truncate_posts_schedule');
}
Hook into your schedule action
add_action('foobar_truncate_posts_schedule', 'foobar_truncate_posts');
If you find that WP-Cron is missing your schedule, publishing scheduled posts, etc…, you can automate it further with a UNIX cron. Here’s a great article to show you how to ping wp-cron.php at specified intervals. Here’s what they recommend to keep wp-cron on-time using a UNIX cron.
wget http://www.server.com/wp-cron.php > /dev/null 2>&1
Approach #2: Using a UNIX cron
You can use true UNIX crons with native admin-ajax.php functionality.
Verify cURL on your server
This approach uses cURL which should be installed on your server. If not and you’re using Apache, sudo apt-get install php5-curl
and then sudo /etc/init.d/apache2 restart
.
Create an AJAX hook
Make sure to set it to nopriv as your server wont be authenticating with WP.
add_action('wp_ajax_nopriv_truncate_posts', 'foobar_truncate_posts_cron');
function foobar_truncate_posts_cron(){
# We use the user-agent as a shared key
$shared_user_agent="FooBar TruncatePostsCron/1.0";
# Block unwanted IP addresses
$whitelisted_ips = array( //IPs allowed to run this operation
'192.168.1.1',
'127.0.0.1'
);
# Retrive Request Information
$request_user_agent = $_SERVER['HTTP_USER_AGENT'];
$request_ip = $_SERVER['REMOTE_ADDR'];
# Authenticate
if($request_user_agent === $shared_user_agent && in_array($request_ip, $whitelisted_ips))
echo foobar_truncate_posts(); // Reusable function
else
echo 'Authentication failed for post trucation cron.';
exit;
}
Add your Crontab
This config will run one time per day consistently. -A
sets the shared user agent secret -o
specifies an output file, action=truncate_posts
is relative to your ajax hook action. Verify /user/bin/curl
is a proper path for executing a cURL command. You might be able to just use curl
instead.
0 0 * * * /usr/bin/curl -A 'FooBar TruncatePostsCron/1.0' -o ~/truncate_posts.log http://yourdomain.com/wp-admin/admin-ajax.php?action=truncate_posts
And finally, always make sure you set register_globals=off
in your php.ini to prevent spoofing of any sort.
And, Finally…
These are the two main approaches to WordPress + cron (whether true or not). There are many ways to skin a cat with your specific use case in foobar_truncate_posts()
. I’m sure you can tweak it from here. Hope this helps you out!