I want to make a notification bar in my Wordpress website, that will be displayed when there is a new post published. Unfortunately, I have some problems with getting the code work.
GOAL
What the goal is, is to let the user know that there are new posts available for them on the website with a notification bar. So the code should check if the amount of posts is increased. If yes, I want to show the notification bar on the website for two days.
THE PROBLEM
The following code will only outputs the total number of posts from each post type that I have specified in the $post_types
array. The if statement doesn’t work correctly. When I publish a new post, delete it and post another, it will not update the number in the database. Only if I post after I delete an older one, the value will increase.
MY CODE
The code below will now only echos the post type name and number of posts.
$args = array(
'public' => true,
'_builtin' => false
);
$post_types = array( 'post', 'roosters', 'downloads', 'reglements', 'alv' );
foreach ( $post_types as $post_type ) {
// variable
$postCountTotal = wp_count_posts( $post_type )->publish;
echo '<strong>' . $post_type . '</strong>';
echo ' has total posts of : ' . $postCountTotal;
echo '<br>';
// First read the previous post count value from the databse so we can compare the old value with the new one
// EDIT: use 0 as the default value if no data in database - first run
$previousCount = get_option( 'post_count_total', 0 );
if ( $postCountTotal != $previousCount ) {
//echo 'New post detected';
update_option( 'post_count_total', $postCountTotal );
} elseif ( '' == $postCountTotal && $previousCount ) {
delete_option( 'post_count_total', $previousCount );
}
}
echo $postCountTotal;
Counting posts to determine if there is a new post is wasting resources and not accurate as a transition in post status can influence the count. For example, as you said, if a post is deleted and a new one is published, the count will stay the same
To make this work, we need to follow the following worksflow
WORKSFLOW
We need to determine when a post is published. This can be done via the transition_post_status
action hook. This hook is fired every time a post's status is changed. Even if a post is updated, it's status is changed.
We should only do something when a new post is published, so we need to check the post's status before and after it is published ( the 'new' status here does not work as I have expected it to work, so I scrapped that idea).
Next will be to save the new post object in the wp_options
table where we can get it later in a template and use it to display the notification bar. The functions to use here would be add_option()
to create our option if it does not exist and update_option()
if the option already exist.
The post object is now saved in the wp_options
table. We must now retrieve that option in an function or template file. We will use get_option()
. From the post object saved we will need to get the post_date_gmt
in order to use it for comaprison and we need to determine the exact time 2 days later
We also need the current time which we can get with current_time()
In the final stretch, we can now compare the dates and if the dates we are comparing is less than two days, we need to make things happen, show the notification bar, if the comparison is more than two days, we either shows nothing or something else
THE CODE
Here is the final code. I have commented it well so that you can follow it
In your functions.php, add the following
add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{
//Check if our post status then execute our code
if ( $new_status == 'publish' && $old_status != 'publish' ) {
if ( get_option( 'new_post_notification' ) !== false ) {
// The option already exists, so we just update it.
update_option( 'new_post_notification', $post );
} else {
add_option( 'new_post_notification', $post );
}
}
}, 10, 3 );
Now, in your template or in a custom function if you wish, add the following
// Get the new_post_notification which holds the newest post
$notification = get_option( 'new_post_notification' );
if( false != $notification ) {
//Get the post's gmt date. This can be changed to post_date
$post_date = strtotime( $notification->post_date_gmt );
//Get the current gmt time
$todays_date = current_time( 'timestamp', true );
//Set the expiry time to two days after the posts is published
$expiry_date = strtotime('+2 day', $post_date);
if( $expiry_date > $todays_date ) {
// Display your notification if two days has not been passed
}
}
There is built-in WP function for that:
<?php
$count_posts = wp_count_posts();
?>
Good documentation available on the WP Codex:
http://codex.wordpress.org/Function_Reference/wp_count_posts
You should be able to simplify your code if you only want the total of all posts.
I Needed to count the posts in the current language. Here's my code:
$allpost_arg = array(
'numberposts' => -1,
'post_type' => 'post',
'suppress_filters' => 0,
);
$allposts = get_posts( $allpost_arg );
if($allposts){
$count_the_posts = 0;
foreach ($allposts as $allpost){
$count_the_posts++;
}
}
echo $count_the_posts;