0

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;
Pieter Goosen
  • 9,768
  • 5
  • 35
  • 55
Caspert
  • 4,271
  • 15
  • 59
  • 104
  • What's the relation to `css`? – LcSalazar Dec 03 '14 at 16:29
  • You will really have to look into the the `transition_post_status` hook for this – Pieter Goosen Dec 03 '14 at 18:38
  • I think this one you mean: http://snippi.com/s/tbicojs @PieterGoosen – Caspert Dec 03 '14 at 19:11
  • @PieterGoosen, There is a very limited documentation about `transition_post_status` function. I trying to get it work, but notting is gonna be happen. Can you help me a little further? - I came to the following inside my `functions.php`: http://snippi.com/s/i5sx2hm I look out to your response. – Caspert Dec 04 '14 at 07:53
  • @PieterGoosen If there is a possibility if you can help me tonight, that would be very nice. I hear from you. Thank you in advance for your time – Caspert Dec 04 '14 at 08:06
  • No need to add 'Solved" to your title, you have accepted an answer, so this will show that the problem is solved :-) – Pieter Goosen Dec 04 '14 at 17:16
  • 1
    Okay I see that you have edit it already. Thanks!! – Caspert Dec 04 '14 at 17:17

4 Answers4

3

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
    }

}
Pieter Goosen
  • 9,768
  • 5
  • 35
  • 55
  • I am really happy with this detailed answer! Thank you very much, only I get an error: `Trying to get property of non-object on line 55`. That is this snippet of code `$post_date = strtotime( $notification->post_date_gmt );` The first block of code I placed, as you said in `functions.php` and the last block in my `header.php` file - maybe later in a function is better. – Caspert Dec 04 '14 at 16:39
  • OK, then get_option is empty, not yet set. Did not keep that in mind, will correct now – Pieter Goosen Dec 04 '14 at 16:41
  • I do not know how grateful I am to you. It works perfect and by your explanation, I follow your flow and understand the code to a great extent. So thank you so much for your answer and time! Hope I can help you another time. Thanks Casper :) – Caspert Dec 04 '14 at 16:56
  • 1
    My pleasure, really glad it worked out for you as expected. Enjoy :-) – Pieter Goosen Dec 04 '14 at 16:57
  • I am so happy with it, but I have one question left. In my notification bar, there is a close button and what I want is, if the user clicks on the close button, it will be closed until the time we set with `expiry_date` is expired. so the user is not always confronted as he refreshed the browser. Do you know how I can do that? I like to hear from you. Thanks in advance! – Caspert Dec 06 '14 at 18:19
  • You should ask this as a new question. I'm not quite sure at this stage what will be a good approach here :-), so it would be really interesting to see replies/answers to that question. Will also see if I can come up with something in the mean time – Pieter Goosen Dec 06 '14 at 18:23
  • You’re right. I have posted a new question. Thank you for helping me! – Caspert Dec 06 '14 at 18:43
0

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.

jdm2112
  • 145
  • 1
  • 8
  • Yes that function I used above for getting only the amount of posts from the array `$post_type`. That is working, but now I also want to get the total of all post types that are stored in the array. – Caspert Dec 03 '14 at 16:28
  • I believe I misunderstood your challenge. When you say "I also want to get the total of all post types" do you mean only the types specified or all WP posts, regardless of type? – jdm2112 Dec 03 '14 at 16:30
  • `$count_posts += wp_count_posts();`? – rnevius Dec 03 '14 at 16:30
  • @jdm2112 I mean the total only from the specified types of post_types. I will make my question also better. – Caspert Dec 03 '14 at 16:31
0

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;
0

Copy and paste the following code to your theme’s functions.php file or a site-specific plugin to create a shortcode:

function wpb_total_posts() { 
    $total = wp_count_posts()->publish;
    return $total; 
} 
add_shortcode('total_posts','wpb_total_posts');

Now you can use the shortcode [total_posts] to display the total number of posts in any posts, pages, or sidebar widgets.

mikelplhts
  • 1,181
  • 3
  • 11
  • 32