Check post locks with heartbeat and display modal notifications when a post is locked or a user takes over editing, props dh-shredder, see #23697
git-svn-id: http://core.svn.wordpress.org/trunk@23661 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
4c85664703
commit
edb9333d40
|
@ -3407,6 +3407,46 @@ td.plugin-title p {
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#notification-dialog {
|
||||||
|
position: fixed;
|
||||||
|
top: 30%;
|
||||||
|
left: 50%;
|
||||||
|
width: 450px;
|
||||||
|
margin-left: -225px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 1000005;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-dialog-background {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
filter: alpha(opacity=50);
|
||||||
|
z-index: 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-dialog .post-locked-message,
|
||||||
|
#notification-dialog .post-taken-over {
|
||||||
|
margin: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-dialog .post-locked-message a.button-primary {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-dialog .post-locked-avatar {
|
||||||
|
float: left;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-dialog .currently-editing {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
11.1 - Custom Fields
|
11.1 - Custom Fields
|
||||||
|
|
|
@ -1057,6 +1057,7 @@ function wp_ajax_autosave() {
|
||||||
$_POST['post_status'] = 'draft';
|
$_POST['post_status'] = 'draft';
|
||||||
|
|
||||||
if ( $last = wp_check_post_lock( $post->ID ) ) {
|
if ( $last = wp_check_post_lock( $post->ID ) ) {
|
||||||
|
// This will change after we have per-user autosaves
|
||||||
$do_autosave = $do_lock = false;
|
$do_autosave = $do_lock = false;
|
||||||
|
|
||||||
$last_user = get_userdata( $last );
|
$last_user = get_userdata( $last );
|
||||||
|
@ -1064,7 +1065,6 @@ function wp_ajax_autosave() {
|
||||||
$data = __( 'Autosave disabled.' );
|
$data = __( 'Autosave disabled.' );
|
||||||
|
|
||||||
$supplemental['disable_autosave'] = 'disable';
|
$supplemental['disable_autosave'] = 'disable';
|
||||||
$alert .= sprintf( __( '%s is currently editing this article. If you update it, you will overwrite the changes.' ), esc_html( $last_user_name ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'page' == $post->post_type ) {
|
if ( 'page' == $post->post_type ) {
|
||||||
|
@ -1094,11 +1094,6 @@ function wp_ajax_autosave() {
|
||||||
$id = $post->ID;
|
$id = $post->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $do_lock && empty( $_POST['auto_draft'] ) && $id && is_numeric( $id ) ) {
|
|
||||||
$lock_result = wp_set_post_lock( $id );
|
|
||||||
$supplemental['active-post-lock'] = implode( ':', $lock_result );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $nonce_age == 2 ) {
|
if ( $nonce_age == 2 ) {
|
||||||
$supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
|
$supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
|
||||||
$supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
|
$supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
|
||||||
|
@ -1777,7 +1772,7 @@ function wp_ajax_wp_remove_post_lock() {
|
||||||
if ( $active_lock[1] != get_current_user_id() )
|
if ( $active_lock[1] != get_current_user_id() )
|
||||||
wp_die( 0 );
|
wp_die( 0 );
|
||||||
|
|
||||||
$new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ) + 5 ) . ':' . $active_lock[1];
|
$new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', 120 ) + 5 ) . ':' . $active_lock[1];
|
||||||
update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
|
update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
|
||||||
wp_die( 1 );
|
wp_die( 1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,3 +586,44 @@ function wp_check_locked_posts( $response, $data ) {
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 2 );
|
add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 2 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check lock status on the New/Edit Post screen and refresh the lock
|
||||||
|
*
|
||||||
|
* @since 3.6
|
||||||
|
*/
|
||||||
|
function wp_refresh_post_lock( $response, $data, $screen_id ) {
|
||||||
|
if ( 'post' == $screen_id && array_key_exists( 'wp-refresh-post-lock', $data ) ) {
|
||||||
|
$received = $data['wp-refresh-post-lock'];
|
||||||
|
$send = array();
|
||||||
|
|
||||||
|
if ( !$post_id = absint( $received['post_id'] ) )
|
||||||
|
return $response;
|
||||||
|
|
||||||
|
if ( !current_user_can('edit_post', $post_id) )
|
||||||
|
return $response;
|
||||||
|
|
||||||
|
if ( $user_id = wp_check_post_lock( $post_id ) ) {
|
||||||
|
$user = get_userdata( $user_id );
|
||||||
|
|
||||||
|
$error = array(
|
||||||
|
'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $avatar = get_avatar( $user->ID, 64 ) ) {
|
||||||
|
if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) )
|
||||||
|
$error['avatar_src'] = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$send['lock_error'] = $error;
|
||||||
|
} else {
|
||||||
|
if ( $new_lock = wp_set_post_lock( $post_id ) )
|
||||||
|
$send['new_lock'] = implode( ':', $new_lock );
|
||||||
|
}
|
||||||
|
|
||||||
|
$response['wp-refresh-post-lock'] = $send;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );
|
||||||
|
|
|
@ -1162,7 +1162,7 @@ function wp_check_post_lock( $post_id ) {
|
||||||
$time = $lock[0];
|
$time = $lock[0];
|
||||||
$user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
|
$user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
|
||||||
|
|
||||||
$time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 );
|
$time_window = apply_filters( 'wp_check_post_lock_window', 120 );
|
||||||
|
|
||||||
if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
|
if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
|
||||||
return $user;
|
return $user;
|
||||||
|
@ -1192,31 +1192,61 @@ function wp_set_post_lock( $post_id ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs the notice message to say that someone else is editing this post at the moment.
|
* Outputs the HTML for the notice to say that someone else is editing or has taken over editing of this post.
|
||||||
*
|
*
|
||||||
* @since 2.8.5
|
* @since 2.8.5
|
||||||
* @return none
|
* @return none
|
||||||
*/
|
*/
|
||||||
function _admin_notice_post_locked() {
|
function _admin_notice_post_locked() {
|
||||||
$post = get_post();
|
global $post_ID;
|
||||||
$lock = explode( ':', get_post_meta( $post->ID, '_edit_lock', true ) );
|
|
||||||
$user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
|
|
||||||
$last_user = get_userdata( $user );
|
|
||||||
$last_user_name = $last_user ? $last_user->display_name : __('Somebody');
|
|
||||||
|
|
||||||
switch ($post->post_type) {
|
if ( !empty( $post_ID ) && ( $user = wp_check_post_lock( $post_ID ) ) ) {
|
||||||
case 'post':
|
$user = get_userdata( $user );
|
||||||
$message = __( 'Warning: %s is currently editing this post' );
|
$locked = apply_filters( 'show_post_locked_dialog', true, $post_ID, $user );
|
||||||
break;
|
} else {
|
||||||
case 'page':
|
$locked = false;
|
||||||
$message = __( 'Warning: %s is currently editing this page' );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$message = __( 'Warning: %s is currently editing this.' );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = sprintf( $message, esc_html( $last_user_name ) );
|
?>
|
||||||
echo "<div class='error'><p>$message</p></div>";
|
<div id="notification-dialog-wrap"<?php if ( ! $locked ) echo ' style="display:none"'; ?>>
|
||||||
|
<div id="notification-dialog-background"></div>
|
||||||
|
<div id="notification-dialog">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ( $locked ) {
|
||||||
|
?>
|
||||||
|
<div class="post-locked-message">
|
||||||
|
<div class="post-locked-avatar"><?php echo get_avatar( $user->ID, 64 ); ?></div>
|
||||||
|
<p><?php esc_html_e( sprintf( __( 'This content is currently locked. If you take over, %s will be blocked from continuing to edit.' ), $user->display_name ) ); ?></p>
|
||||||
|
<p>
|
||||||
|
<a class="button" href="<?php echo esc_url( wp_get_referer() ); ?>"><?php _e('Go back'); ?></a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Allow plugins to prevent some users taking over
|
||||||
|
if ( apply_filters( 'post_lock_take_over', true, $post_ID, $user ) ) {
|
||||||
|
?>
|
||||||
|
<a class="button button-primary" href="<?php echo esc_url( add_query_arg( 'get-post-lock', '1', get_edit_post_link( $post_ID, 'url' ) ) ); ?>"><?php _e('Take over'); ?></a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<div class="post-taken-over">
|
||||||
|
<div class="post-locked-avatar"></div>
|
||||||
|
<p class="currently-editing"></p>
|
||||||
|
<p><a class="button button-primary" href="<?php echo esc_url( admin_url('edit.php') ); ?>"><?php _e('Go to All Posts'); ?></a></p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -251,7 +251,49 @@ WPRemoveThumbnail = function(nonce){
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
})(jQuery);
|
$(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
|
||||||
|
var lock = $('#active_post_lock').val(), post_id = $('#post_ID').val(), send = {};
|
||||||
|
|
||||||
|
if ( !post_id )
|
||||||
|
return;
|
||||||
|
|
||||||
|
send['post_id'] = post_id;
|
||||||
|
|
||||||
|
if ( lock )
|
||||||
|
send['lock'] = lock;
|
||||||
|
|
||||||
|
data['wp-refresh-post-lock'] = send;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
|
||||||
|
var received, wrap, avatar;
|
||||||
|
|
||||||
|
if ( data['wp-refresh-post-lock'] ) {
|
||||||
|
received = data['wp-refresh-post-lock'];
|
||||||
|
|
||||||
|
if ( received.lock_error ) {
|
||||||
|
// show "editing taken over" message
|
||||||
|
wrap = $('#notification-dialog-wrap');
|
||||||
|
|
||||||
|
if ( ! wrap.is(':visible') ) {
|
||||||
|
autosave();
|
||||||
|
wrap.find('p.currently-editing').text( received.lock_error.text );
|
||||||
|
|
||||||
|
if ( received.lock_error.avatar_src && /^https?:\/\/[a-z0-9]+?\.gravatar\.com\/avatar/.test( received.lock_error.avatar_src ) ) {
|
||||||
|
avatar = $('<img class="avatar avatar-64 photo" width="64" height="64" />').attr( 'src', received.lock_error.avatar_src.replace(/&/g, '&') );
|
||||||
|
wrap.find('div.post-locked-avatar').empty().append( avatar );
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( received['new_lock'] )
|
||||||
|
$('#active_post_lock').val( received['new_lock'].replace(/[^0-9:]+/, '') );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(jQuery));
|
||||||
|
|
||||||
jQuery(document).ready( function($) {
|
jQuery(document).ready( function($) {
|
||||||
var stamp, visibility, sticky = '', last = 0, co = $('#content');
|
var stamp, visibility, sticky = '', last = 0, co = $('#content');
|
||||||
|
|
|
@ -147,6 +147,12 @@ case 'edit':
|
||||||
if ( 'trash' == $post->post_status )
|
if ( 'trash' == $post->post_status )
|
||||||
wp_die( __('You can’t edit this item because it is in the Trash. Please restore it and try again.') );
|
wp_die( __('You can’t edit this item because it is in the Trash. Please restore it and try again.') );
|
||||||
|
|
||||||
|
if ( !empty( $_GET['get-post-lock'] ) ) {
|
||||||
|
wp_set_post_lock( $post_id );
|
||||||
|
wp_redirect( get_edit_post_link( $post_id, 'url' ) );
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
$post_type = $post->post_type;
|
$post_type = $post->post_type;
|
||||||
if ( 'post' == $post_type ) {
|
if ( 'post' == $post_type ) {
|
||||||
$parent_file = "edit.php";
|
$parent_file = "edit.php";
|
||||||
|
@ -165,15 +171,15 @@ case 'edit':
|
||||||
$post_new_file = "post-new.php?post_type=$post_type";
|
$post_new_file = "post-new.php?post_type=$post_type";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $last = wp_check_post_lock( $post->ID ) ) {
|
if ( ! wp_check_post_lock( $post->ID ) ) {
|
||||||
add_action('admin_notices', '_admin_notice_post_locked' );
|
|
||||||
} else {
|
|
||||||
$active_post_lock = wp_set_post_lock( $post->ID );
|
$active_post_lock = wp_set_post_lock( $post->ID );
|
||||||
|
|
||||||
if ( 'attachment' !== $post_type )
|
if ( 'attachment' !== $post_type )
|
||||||
wp_enqueue_script('autosave');
|
wp_enqueue_script('autosave');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_action( 'admin_footer', '_admin_notice_post_locked' );
|
||||||
|
|
||||||
$title = $post_type_object->labels->edit_item;
|
$title = $post_type_object->labels->edit_item;
|
||||||
$post = get_post($post_id, OBJECT, 'edit');
|
$post = get_post($post_id, OBJECT, 'edit');
|
||||||
|
|
||||||
|
@ -217,6 +223,11 @@ case 'trash':
|
||||||
if ( !current_user_can($post_type_object->cap->delete_post, $post_id) )
|
if ( !current_user_can($post_type_object->cap->delete_post, $post_id) )
|
||||||
wp_die( __('You are not allowed to move this item to the Trash.') );
|
wp_die( __('You are not allowed to move this item to the Trash.') );
|
||||||
|
|
||||||
|
if ( $user_id = wp_check_post_lock( $post_id ) ) {
|
||||||
|
$user = get_userdata( $user_id );
|
||||||
|
wp_die( sprintf( __( 'You cannot move this item to the Trash. %s is currently editing.' ), $user->display_name ) );
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! wp_trash_post($post_id) )
|
if ( ! wp_trash_post($post_id) )
|
||||||
wp_die( __('Error in moving to Trash.') );
|
wp_die( __('Error in moving to Trash.') );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue