Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close a notification bar with cookies and expiry date from php?

In my previous question I was searching for a way to create a notification message on my WordPress site, when there is a new post published. After a great answer, this is working very well. I can change the settings of how long this message should be displayed after the time of when the post was published. When the time is expired, the message will disappear.

Goal

So it is working absolute fine, special thanks for Pieter Goosen, but if the user has seen the message once, I want to give the ability to close the notification bar and to ensure that it no longer appears to the user in order to refresh the page not telksens returns the message, provided of course a new post again published.

Question

How can I make this happen? I was thinking about javascript. For the function, of course there should be one function that controls the close button, I think that there should be also a function for cookies, to check if the user has closed the message or not and checked within the time expires the timer so that both sync with each other.

My previous question for the notification you can find here:

How to count the total number of posts from the selected post types?

[UPDATE] I just sit down and try to get the structure of the notification bar clear, so I put it in a nutshell, to see if it will work, so the code of PieterGoosen checked if there is a new post available in WordPress and show the notification bar. Then the bar should be closed after the time is expired or when the user has clicked on the close button. So the code should check that too. If the user clicks on the close button == YES, then a cookie must set (cookie should synch with the time that is set in PHP), so it will delete the cookie, whenever there is a new post available. If the user doesn't click on the close button then do noting and If the time expired > delete also the cookie.

like image 939
Caspert Avatar asked Dec 06 '14 18:12

Caspert


1 Answers

I have a solution. I have tested the code as much as possible with as much scenarios as I could think of.

I have use the same code as I have used in this answer to this question. So I'm not going to tackle that section again

WORKSFLOW PART 1

We are going to make use of jquery to hide the notification bar, and a cookie which will have two purposes, to save the latest post ID and keep the notification hidden till a new post is published or when the expiry time expires

To accomplish this, we will use the hide() function in jquery to hide the notification bar when a hide button is clicked by the user. You can customize this button as needed or use any other type of symbol.

We now need to use some method to keep the button hidden till a new post is published. This will be done by setting a cookie when the hide button is clicked. The cookie is set to expire in 2 days, so if no new post is published within this two days, then the cookie will automatically expire. To set the cookie, we need to download the jquery-cookie plugin. This plugin will also force cookie deletion when a new post is published when a cookie is still set.

This section heavily relies on the post ID set in our new_post_notification. The problem is, you can't pass php variables directly to jquery. Luckily Wordpress has a function called wp_localize_script which we can use to pass the post ID to the jquery script where we will use it to it as the cookie value.

This is the end of section 1, lets get coding

LETS CODE SECTION 1

First, download the plugin, extract it and copy the jquery.cookie.js file to your theme's js folder. Next, create a new file in your js folder and name it hide.notification.bar.js. Open this newly created file and paste the following code in there and save it

jQuery(document).ready(function($) {

    $("#notification_hide_button").click(function(){
        $(this).hide();
        $(".notifications_bar").hide();

        if ($.cookie( 'hide_post_cookie' ) ) { 
            $.cookie( 'hide_post_cookie', null ) 
        }
        var post_id = parseInt( cookie_Data.post_id, 10 );

        $.cookie( 'hide_post_cookie', post_id, { expires: 2, path: '/' } );

    });

});

This is the code used to hide the notification bar and which sets the cookie. var post_id = parseInt( cookie_Data.post_id, 10 ); will hold the post ID which is the most important piece of info here

We now need to register and enqueue these two js files and set the post ID to the wp_localize_script function. Open your functions.php and paste the following in there. If you already have a wp_enqueue_scripts hook in your theme, just strip the relevant code from here and paste it into your funtion

function enqueue_cookie_scripts() {

    wp_enqueue_script( 'jquery-cookie', get_template_directory_uri() . '/js/jquery.cookie.js', array( 'jquery' ), '' , true );
    wp_register_script( 'set-cookie-option', get_template_directory_uri() . '/js/hide.notification.bar.js', array( 'jquery', 'jquery-cookie'), '' , true );

    $cookie_data = array(
        'post_id' => get_option( 'new_post_notification' )->ID
    );
    wp_localize_script( 'set-cookie-option', 'cookie_Data', $cookie_data ); // this one do the magic

    wp_enqueue_script( 'set-cookie-option' );

}

add_action( 'wp_enqueue_scripts', 'enqueue_cookie_scripts' );

You can also copy and paste the function which sets the new_post_notification option when a new post is published. For reference on how this code works, check it out here. This code goes into functions.php

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

WORKSFLOW PART 2

We now have everything in place for the jquery to work, we now need to set the function which will display the notification bar, and display the hide button and delete the cookie if a new post is set if the cookie hasn't expired yet.

This code have been well commented, so you will have now trouble in following it. The most important sections here is getting the cookie's value which is stored in a global variable and can be retrieved with $_COOKIE['hide_post_cookie']. This is in fact a post ID, this will be checked against the post stored in get_option( 'new_post_notification' )->ID

The hide button will hide anything within <div class="notifications_bar"></div>, so you will add the notification bar inside that div. Customize as needed.

I have added all the code inside a function which you can call in your header as follows

echo get_new_post_notification_bar(); 

SECTION 2 CODE

This code also goes into your functions.php

function get_new_post_notification_bar() {

    // Get the new_post_notification which holds the newest post
    $notification   = get_option( 'new_post_notification' );

    // Get the post ID saved in the cookie
    $cookie_post_ID = isset( $_COOKIE['hide_post_cookie'] ) ? (int) $_COOKIE['hide_post_cookie'] : false; 

    $output = '';
    if( false != $notification ) {

        //First check if we have a cookie, if not, show the notification bar
        // If a cookie is set, do not display the notification bar
        if( false === $cookie_post_ID ) {

            //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 );

            //Show the notification bar if the expiry date is not yet reached
            if( $expiry_date > $todays_date ) { 

                $output .= '<div class="notifications_bar">';
                $output .= 'If you click on the "Hide" button, I will disappear.';
                $output .= '</div>';
                $output .= '<button id="notification_hide_button">';
                $output .= 'Hide';
                $output .= '</button>';

            }

        }else{

            /**
             * If a cookie is set, check the cookie value against the post id set as last post
             * If the two don't match, delete the cookie and show the notification bar if a new post is published
             * This code only run once, that is when a cookie is still set, and new post is published within the time
             * in which the cookie is still set
            */ 
            if( (int) $notification->ID !== $cookie_post_ID ) {

                ?>
                    <script>
                        jQuery(document).ready(function($) {

                            $.removeCookie('hide_post_cookie', { path: '/' });

                        });
                    </script>
                <?php

                $output .= '<div class="notifications_bar">';
                $output .= 'If you click on the "Hide" button, I will disappear.';
                $output .= '</div>';
                $output .= '<button id="notification_hide_button">';
                $output .= 'Hide';
                $output .= '</button>';

            }

        }   

    }

    return $output;

}
like image 168
Pieter Goosen Avatar answered Oct 20 '22 00:10

Pieter Goosen