WordPress admin check if content changed using Heartbeat

Heartbeat

When creating a WordPress admin panel it is common to want to refresh the page based on real-time content changes. The most straightforward way of doing that is by hooking into the WP Heartbeat API.

Using the Heartbeat API you can have almost real-time updates to the admin content.

What is the WordPress Heartbeat API?

It was introduced in WordPress version 3.6 and basically it does a regular Ajax call. It does so in order to check if the user is still logged in or if someone else is editing a post. This way it can show you the whole “someone else is editing this post” screen which you can “Take over”.

The Ajax call is, by default, being triggered based on user activity and at a certain interval but we can also change that to a more “stable” call at a given interval.

But first, the data update!

When you are ready to update the data in your admin panel ( or another plugin’s admin panel ) there are 2 steps to follow:

  1. You add a piece of JavaScript that adds your custom variable
  2. You filter the value of “heartbeat_received” and populate the data which will also be used in the script you added above.

Here’s an example of doing that:

add_filter( 'heartbeat_received', 'm_add_heartbeat_data'), 10, 2 );
function m_add_heartbeat_data( $response, $data ) {
   if ( isset($data['daed_version']) && $data['daed_version']=='dashboard_editorial' ) {
      $response['daed_version'] = $this->get_version();
   }
   return $response;
}
add_action( 'admin_print_footer_scripts', 'm_heartbeat_footer_js');
function m_heartbeat_footer_js() {
   global $pagenow;
   // check the page you are on, maybe you don't want to run this on all the admin pages
   if( 'admin.php' != $pagenow )
      return;
   ?>
   <script>
      (function($){
         $(document).on('heartbeat-send', function(e, data) {
            // add your custom variable which will be populated in the ajax request
            data['m_sales'] = 'yes_send';
         });
         $(document).on( 'heartbeat-tick', function(e, data) {
            // don't run the script if the custom variable is not present
            if ( ! data['m_sales'] )
               return;
            if ( data['m_sales'] ) {
               $('#m_sales_count').text(data['m_sales']);
            }
         });
         // set the heartbeat interval - explained below
         wp.heartbeat.interval( 'slow' );
      }(jQuery));
   </script>
   <?php
}

If you’re asking yourself “why not add this in a separate js file?” – the answer is, because it will get cached and maybe you want to pass some variables to it.

Changing the interval

You can change the Heartbeat interval either by hooking into the “heartbeat_settings” filter using PHP and changing the “interval” value:

function m_heartbeat_settings( $settings ) {
   $settings['interval'] = 60; //only values between 15 and 60 seconds allowed
   return $settings;
}
add_filter( 'heartbeat_settings', 'm_heartbeat_settings' );

Or by using the JavaScript functions as I have done above using one of the 3 available values: fast, slow or standard.

// 5 seconds but no more than 2 and a half minutes
wp.heartbeat.interval( 'fast' );
// 60 seconds
wp.heartbeat.interval( 'slow' );
// 15 seconds
wp.heartbeat.interval( 'standard' );