Created
June 18, 2018 06:29
-
-
Save quasel/fbf9552fa057126faceb79381dea9fd2 to your computer and use it in GitHub Desktop.
Heartbeat API example usage for Post Locking on frontend
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Add display name / role for post locking dialogs. | |
| * | |
| * @param array $response The Heartbeat response. | |
| * @param array $data The $_POST data sent. | |
| * @param string $screen_id The screen id. | |
| * | |
| * @return array The Heartbeat response. | |
| */ | |
| function post_lock_add_display_name_role( $response, $data, $screen_id ) { | |
| if ( ! empty( $response['wp-refresh-post-lock']['lock_error'] ) ) { | |
| $post_id = absint( $data['wp-refresh-post-lock']['post_id'] ); | |
| $user_id = wp_check_post_lock( $post_id ); | |
| if ( ! $user_id ) { | |
| return $response; | |
| } | |
| $display_name_role = post_lock_get_display_name_role( $user_id ); | |
| $response['wp-refresh-post-lock']['lock_error']['display_name'] = esc_html( $display_name_role['display_name'] ); | |
| $response['wp-refresh-post-lock']['lock_error']['role'] = esc_html( $display_name_role['role'] ); | |
| } | |
| return $response; | |
| } | |
| add_filter( 'heartbeat_received', 'post_lock_add_display_name_role', 11, 3 ); | |
| /** | |
| * Get Display Name / Role text from user. | |
| * | |
| * @param int $user_id User ID. | |
| * | |
| * @return array|false Display name and role of user, false if user not found. | |
| */ | |
| function post_lock_get_display_name_role( $user_id ) { | |
| $user = get_userdata( $user_id ); | |
| if ( ! $user ) { | |
| return false; | |
| } | |
| $roles = array(); | |
| // Loop through the roles and convert them to labels. | |
| foreach ( $user->roles as $role ) { | |
| $roles[] = ucwords( str_replace( array( '-', '_' ), ' ', $role ) ); | |
| } | |
| // Combine multiple roles into one string. | |
| $role_text = implode( ', ', $roles ); | |
| $display_name_role = array( | |
| 'display_name' => $user->display_name, | |
| 'role' => $role_text, | |
| ); | |
| return $display_name_role; | |
| } | |
| /** | |
| * Get notice text if a post is locked. | |
| * | |
| * @param int $post_id Post ID. | |
| * | |
| * @return string|false Notice text if post is locked, false if it is not locked. | |
| */ | |
| function post_lock_get_display_name_role_from_post( $post_id ) { | |
| /** | |
| * Check if the post is locked. | |
| * | |
| * @param int|string $post_id Post ID. | |
| * | |
| * @return string|false User ID who is currently editing or false if the post is not locked. | |
| */ | |
| $user_id = wp_check_post_lock( $post_id ); | |
| if ( ! $user_id ) { | |
| return false; | |
| } | |
| return post_lock_get_display_name_role( $user_id ); | |
| } | |
| /** | |
| * Render the post locking frontend notice. | |
| * | |
| * @param int $post_id Post ID. | |
| * | |
| * @return bool Whether the post is currenty locked by another user. | |
| */ | |
| function post_lock_frontend_notice( $post_id ) { | |
| wp_enqueue_script( 'heartbeat', '', array(), false, true ); | |
| // Include necessary files. | |
| require_once ABSPATH . 'wp-admin/includes/post.php'; | |
| require_once ABSPATH . 'wp-admin/includes/misc.php'; | |
| require_once ABSPATH . 'wp-admin/includes/admin-filters.php'; | |
| // Get the display name / role for post lock (if there is one). | |
| $display_name_role = post_lock_get_display_name_role_from_post( $post_id ); | |
| $hidden = 'hidden'; | |
| $is_locked = false; | |
| $active_post_lock = array(); | |
| if ( false !== $display_name_role ) { | |
| $hidden = ''; | |
| $is_locked = true; | |
| } else { | |
| $display_name_role = array( | |
| 'display_name' => '', | |
| 'role' => '', | |
| ); | |
| if ( is_user_logged_in() ) { | |
| $active_post_lock = wp_set_post_lock( $post_id ); | |
| } | |
| } | |
| ?> | |
| <div id="post-lock-dialog" class="<?php echo esc_attr( $hidden ); ?>"> | |
| <?php | |
| printf( | |
| '<span class="user-display-name">%1$s</span> (<span class="user-role">%2$s</span>) is editing.', | |
| esc_html( $display_name_role['display_name'] ), | |
| esc_html( $display_name_role['role'] ) | |
| ); | |
| ?> | |
| </div> | |
| <input type="hidden" id="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( 'heartbeat-nonce' ) ); ?>" /> | |
| <input type="hidden" id="post_ID" value="<?php echo esc_attr( $post_id ); ?>" /> | |
| <input type="hidden" id="active_post_lock" value="<?php echo esc_attr( implode( ':', $active_post_lock ) ); ?>" /> | |
| <?php | |
| return $is_locked; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*********************************************** | |
| * This CSS is needed in the theme because of how | |
| * the notice renders. The notice element is | |
| * always on the page, it is updated and shown/ | |
| * hidden depending on the circumstance. | |
| ***********************************************/ | |
| .hidden { | |
| display: none; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*********************************************** | |
| * This JS handles all of the heartbeat API calls | |
| * and post locking integration. | |
| ***********************************************/ | |
| (function($) { | |
| // Check every 15 seconds for post lock changes. | |
| var heartbeat_interval = 15; | |
| $(document).on( 'heartbeat-send.refresh-lock', function( e, data ) { | |
| /** | |
| * Heartbeat locks. | |
| * | |
| * Used to lock editing of an object by only one user at a time. | |
| * | |
| * When the user does not send a heartbeat in a heartbeat-time | |
| * the user is no longer editing and another user can start editing. | |
| */ | |
| var lock = $('#active_post_lock').val(), | |
| post_id = $('#post_ID').val(), | |
| send = {}; | |
| if ( ! post_id || ! $('#post-lock-dialog').length ) { | |
| return; | |
| } | |
| send.post_id = post_id; | |
| if ( lock ) { | |
| send.lock = lock; | |
| } | |
| data['wp-refresh-post-lock'] = send; | |
| }).on( 'heartbeat-tick.refresh-lock', function( e, data ) { | |
| // Post locks: update the lock string or show the dialog if somebody has taken over editing. | |
| var received, wrap; | |
| if ( data['wp-refresh-post-lock'] ) { | |
| received = data['wp-refresh-post-lock']; | |
| if ( received.lock_error ) { | |
| // Show "editing taken over" message. | |
| wrap = $('#post-lock-dialog'); | |
| if ( wrap.length ) { | |
| // Show wrap if it is hidden. | |
| if ( wrap.hasClass('hidden') ) { | |
| wrap.removeClass( 'hidden' ); | |
| } | |
| // Set user fields. | |
| $('.user-display-name', wrap).text( received.lock_error.display_name ); | |
| $('.user-role', wrap).text( received.lock_error.role ); | |
| } | |
| } else if ( received.new_lock ) { | |
| // Save current active lock. | |
| $('#active_post_lock').val( received.new_lock ); | |
| } | |
| } | |
| }).ready( function() { | |
| // Set the heartbeat interval. | |
| if ( typeof wp !== 'undefined' && wp.heartbeat ) { | |
| wp.heartbeat.interval( heartbeat_interval ); | |
| } | |
| }); | |
| }(jQuery)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php get_header(); ?> | |
| <div class="wrap"> | |
| <div id="primary" class="content-area"> | |
| <main id="main" class="site-main" role="main"> | |
| <!--******************************************** | |
| * Start of Heartbeat API example code. | |
| *********************************************--> | |
| <?php | |
| $is_locked = post_lock_frontend_notice( get_the_ID() ); | |
| if ( ! $is_locked ) { | |
| // Show an edit form. | |
| } | |
| ?> | |
| <!--******************************************** | |
| * End of Heartbeat API example code. | |
| *********************************************--> | |
| </main><!-- #main --> | |
| </div><!-- #primary --> | |
| <?php get_sidebar(); ?> | |
| </div><!-- .wrap --> | |
| <?php | |
| get_footer(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment