WordPress.org

Make WordPress Core

Changeset 23661


Ignore:
Timestamp:
03/12/2013 03:22:30 AM (7 years ago)
Author:
azaozz
Message:

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

Location:
trunk/wp-admin
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/css/wp-admin.css

    r23640 r23661  
    34083408}
    34093409
     3410#notification-dialog {
     3411    position: fixed;
     3412    top: 30%;
     3413    left: 50%;
     3414    width: 450px;
     3415    margin-left: -225px;
     3416    background: #fff;
     3417    z-index: 1000005;
     3418}
     3419
     3420#notification-dialog-background {
     3421    position: fixed;
     3422    top: 0;
     3423    left: 0;
     3424    right: 0;
     3425    bottom: 0;
     3426    background: #000;
     3427    opacity: 0.5;
     3428    filter: alpha(opacity=50);
     3429    z-index: 1000000;
     3430}
     3431
     3432#notification-dialog .post-locked-message,
     3433#notification-dialog .post-taken-over {
     3434    margin: 25px;
     3435}
     3436
     3437#notification-dialog .post-locked-message a.button-primary {
     3438    margin: 0 10px;
     3439}
     3440
     3441#notification-dialog .post-locked-avatar {
     3442    float: left;
     3443    margin-right: 20px;
     3444}
     3445
     3446#notification-dialog .currently-editing {
     3447    margin-bottom: 20px;
     3448}
     3449
    34103450
    34113451/*------------------------------------------------------------------------------
  • trunk/wp-admin/includes/ajax-actions.php

    r23639 r23661  
    10581058
    10591059    if ( $last = wp_check_post_lock( $post->ID ) ) {
     1060        // This will change after we have per-user autosaves
    10601061        $do_autosave = $do_lock = false;
    10611062
     
    10651066
    10661067        $supplemental['disable_autosave'] = 'disable';
    1067         $alert .= sprintf( __( '%s is currently editing this article. If you update it, you will overwrite the changes.' ), esc_html( $last_user_name ) );
    10681068    }
    10691069
     
    10931093        else
    10941094            $id = $post->ID;
    1095     }
    1096 
    1097     if ( $do_lock && empty( $_POST['auto_draft'] ) && $id && is_numeric( $id ) ) {
    1098         $lock_result = wp_set_post_lock( $id );
    1099         $supplemental['active-post-lock'] = implode( ':', $lock_result );
    11001095    }
    11011096
     
    17781773        wp_die( 0 );
    17791774
    1780     $new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ) + 5 ) . ':' . $active_lock[1];
     1775    $new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', 120 ) + 5 ) . ':' . $active_lock[1];
    17811776    update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
    17821777    wp_die( 1 );
  • trunk/wp-admin/includes/misc.php

    r23584 r23661  
    587587}
    588588add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 2 );
     589
     590/**
     591 * Check lock status on the New/Edit Post screen and refresh the lock
     592 *
     593 * @since 3.6
     594 */
     595function wp_refresh_post_lock( $response, $data, $screen_id ) {
     596    if ( 'post' == $screen_id && array_key_exists( 'wp-refresh-post-lock', $data ) ) {
     597        $received = $data['wp-refresh-post-lock'];
     598        $send = array();
     599
     600        if ( !$post_id = absint( $received['post_id'] ) )
     601            return $response;
     602
     603        if ( !current_user_can('edit_post', $post_id) )
     604            return $response;
     605
     606        if ( $user_id = wp_check_post_lock( $post_id ) ) {
     607            $user = get_userdata( $user_id );
     608
     609            $error = array(
     610                'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name )
     611            );
     612           
     613            if ( $avatar = get_avatar( $user->ID, 64 ) ) {
     614                if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) )
     615                    $error['avatar_src'] = $matches[1];
     616            }
     617
     618            $send['lock_error'] = $error;
     619        } else {
     620            if ( $new_lock = wp_set_post_lock( $post_id ) )
     621                $send['new_lock'] = implode( ':', $new_lock );
     622        }
     623
     624        $response['wp-refresh-post-lock'] = $send;
     625    }
     626
     627    return $response;
     628}
     629add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );
  • trunk/wp-admin/includes/post.php

    r23578 r23661  
    11631163    $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
    11641164
    1165     $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 );
     1165    $time_window = apply_filters( 'wp_check_post_lock_window', 120 );
    11661166
    11671167    if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
     
    11931193
    11941194/**
    1195  * Outputs the notice message to say that someone else is editing this post at the moment.
     1195 * Outputs the HTML for the notice to say that someone else is editing or has taken over editing of this post.
    11961196 *
    11971197 * @since 2.8.5
     
    11991199 */
    12001200function _admin_notice_post_locked() {
    1201     $post = get_post();
    1202     $lock = explode( ':', get_post_meta( $post->ID, '_edit_lock', true ) );
    1203     $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
    1204     $last_user = get_userdata( $user );
    1205     $last_user_name = $last_user ? $last_user->display_name : __('Somebody');
    1206 
    1207     switch ($post->post_type) {
    1208         case 'post':
    1209             $message = __( 'Warning: %s is currently editing this post' );
    1210             break;
    1211         case 'page':
    1212             $message = __( 'Warning: %s is currently editing this page' );
    1213             break;
    1214         default:
    1215             $message = __( 'Warning: %s is currently editing this.' );
    1216     }
    1217 
    1218     $message = sprintf( $message, esc_html( $last_user_name ) );
    1219     echo "<div class='error'><p>$message</p></div>";
     1201    global $post_ID;
     1202
     1203    if ( !empty( $post_ID ) && ( $user = wp_check_post_lock( $post_ID ) ) ) {
     1204        $user = get_userdata( $user );
     1205        $locked = apply_filters( 'show_post_locked_dialog', true, $post_ID, $user );
     1206    } else {
     1207        $locked = false;
     1208    }
     1209
     1210    ?>
     1211    <div id="notification-dialog-wrap"<?php if ( ! $locked ) echo ' style="display:none"'; ?>>
     1212    <div id="notification-dialog-background"></div>
     1213    <div id="notification-dialog">
     1214    <?php
     1215
     1216    if ( $locked ) {
     1217        ?>
     1218        <div class="post-locked-message">
     1219        <div class="post-locked-avatar"><?php echo get_avatar( $user->ID, 64 ); ?></div>
     1220        <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>
     1221        <p>
     1222        <a class="button" href="<?php echo esc_url( wp_get_referer() ); ?>"><?php _e('Go back'); ?></a>
     1223        <?php
     1224
     1225        // Allow plugins to prevent some users taking over
     1226        if ( apply_filters( 'post_lock_take_over', true, $post_ID, $user ) ) {
     1227            ?>
     1228            <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>
     1229            <?php
     1230        }
     1231
     1232        ?>
     1233        </p>
     1234        </div>
     1235        <?php
     1236    } else {
     1237        ?>
     1238        <div class="post-taken-over">
     1239            <div class="post-locked-avatar"></div>
     1240            <p class="currently-editing"></p>
     1241            <p><a class="button button-primary" href="<?php echo esc_url( admin_url('edit.php') ); ?>"><?php _e('Go to All Posts'); ?></a></p>
     1242        </div>
     1243        <?php
     1244    }
     1245
     1246    ?>
     1247    </div>
     1248    </div>
     1249    <?php
    12201250}
    12211251
  • trunk/wp-admin/js/post.js

    r23587 r23661  
    252252};
    253253
    254 })(jQuery);
     254$(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
     255    var lock = $('#active_post_lock').val(), post_id = $('#post_ID').val(), send = {};
     256
     257    if ( !post_id )
     258        return;
     259
     260    send['post_id'] = post_id;
     261
     262    if ( lock )
     263        send['lock'] = lock;
     264
     265    data['wp-refresh-post-lock'] = send;
     266});
     267
     268$(document).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
     269    var received, wrap, avatar;
     270
     271    if ( data['wp-refresh-post-lock'] ) {
     272        received = data['wp-refresh-post-lock'];
     273
     274        if ( received.lock_error ) {
     275            // show "editing taken over" message
     276            wrap = $('#notification-dialog-wrap');
     277
     278            if ( ! wrap.is(':visible') ) {
     279                autosave();
     280                wrap.find('p.currently-editing').text( received.lock_error.text );
     281               
     282                if ( received.lock_error.avatar_src && /^https?:\/\/[a-z0-9]+?\.gravatar\.com\/avatar/.test( received.lock_error.avatar_src ) ) {
     283                    avatar = $('<img class="avatar avatar-64 photo" width="64" height="64" />').attr( 'src', received.lock_error.avatar_src.replace(/&amp;/g, '&') );
     284                    wrap.find('div.post-locked-avatar').empty().append( avatar );
     285                }
     286
     287                wrap.show();
     288            }
     289        }
     290
     291        if ( received['new_lock'] )
     292            $('#active_post_lock').val( received['new_lock'].replace(/[^0-9:]+/, '') );
     293    }
     294});
     295
     296}(jQuery));
    255297
    256298jQuery(document).ready( function($) {
  • trunk/wp-admin/post.php

    r23445 r23661  
    148148        wp_die( __('You can&#8217;t edit this item because it is in the Trash. Please restore it and try again.') );
    149149
     150    if ( !empty( $_GET['get-post-lock'] ) ) {
     151        wp_set_post_lock( $post_id );
     152        wp_redirect( get_edit_post_link( $post_id, 'url' ) );
     153        exit();
     154    }
     155
    150156    $post_type = $post->post_type;
    151157    if ( 'post' == $post_type ) {
     
    166172    }
    167173
    168     if ( $last = wp_check_post_lock( $post->ID ) ) {
    169         add_action('admin_notices', '_admin_notice_post_locked' );
    170     } else {
     174    if ( ! wp_check_post_lock( $post->ID ) ) {
    171175        $active_post_lock = wp_set_post_lock( $post->ID );
    172176
     
    174178            wp_enqueue_script('autosave');
    175179    }
     180
     181    add_action( 'admin_footer', '_admin_notice_post_locked' );
    176182
    177183    $title = $post_type_object->labels->edit_item;
     
    217223    if ( !current_user_can($post_type_object->cap->delete_post, $post_id) )
    218224        wp_die( __('You are not allowed to move this item to the Trash.') );
     225
     226    if ( $user_id = wp_check_post_lock( $post_id ) ) {
     227        $user = get_userdata( $user_id );
     228        wp_die( sprintf( __( 'You cannot move this item to the Trash. %s is currently editing.' ), $user->display_name ) );
     229    }
    219230
    220231    if ( ! wp_trash_post($post_id) )
Note: See TracChangeset for help on using the changeset viewer.