Changeset 41839 for trunk/src/wp-includes/class-wp-customize-manager.php
- Timestamp:
- 10/12/2017 04:00:15 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-customize-manager.php
r41825 r41839 175 175 176 176 /** 177 * Whether the autosave revision of the changeset should shouldbe loaded.177 * Whether the autosave revision of the changeset should be loaded. 178 178 * 179 179 * @since 4.9.0 … … 374 374 remove_action( 'admin_init', '_maybe_update_themes' ); 375 375 376 add_action( 'wp_ajax_customize_save', array( $this, 'save' ) ); 377 add_action( 'wp_ajax_customize_trash', array( $this, 'handle_changeset_trash_request' ) ); 378 add_action( 'wp_ajax_customize_refresh_nonces', array( $this, 'refresh_nonces' ) ); 379 add_action( 'wp_ajax_customize_load_themes', array( $this, 'handle_load_themes_request' ) ); 380 add_action( 'wp_ajax_customize_dismiss_autosave', array( $this, 'handle_dismiss_autosave_request' ) ); 376 add_action( 'wp_ajax_customize_save', array( $this, 'save' ) ); 377 add_action( 'wp_ajax_customize_trash', array( $this, 'handle_changeset_trash_request' ) ); 378 add_action( 'wp_ajax_customize_refresh_nonces', array( $this, 'refresh_nonces' ) ); 379 add_action( 'wp_ajax_customize_load_themes', array( $this, 'handle_load_themes_request' ) ); 380 add_filter( 'heartbeat_settings', array( $this, 'add_customize_screen_to_heartbeat_settings' ) ); 381 add_filter( 'heartbeat_received', array( $this, 'check_changeset_lock_with_heartbeat' ), 10, 3 ); 382 add_action( 'wp_ajax_customize_override_changeset_lock', array( $this, 'handle_override_changeset_lock_request' ) ); 383 add_action( 'wp_ajax_customize_dismiss_autosave_or_lock', array( $this, 'handle_dismiss_autosave_or_lock_request' ) ); 381 384 382 385 add_action( 'customize_register', array( $this, 'register_controls' ) ); … … 630 633 $this->_changeset_uuid = $changeset_uuid; 631 634 } 635 636 $this->set_changeset_lock( $this->changeset_post_id() ); 632 637 } 633 638 … … 1107 1112 } else { 1108 1113 if ( $this->autosaved() ) { 1109 $autosave_post = wp_get_post_autosave( $changeset_post_id );1114 $autosave_post = wp_get_post_autosave( $changeset_post_id, get_current_user_id() ); 1110 1115 if ( $autosave_post ) { 1111 1116 $data = $this->get_changeset_post_data( $autosave_post->ID ); … … 2377 2382 } 2378 2383 2384 $lock_user_id = null; 2379 2385 $autosave = ! empty( $_POST['customize_changeset_autosave'] ); 2386 if ( ! $is_new_changeset ) { 2387 $lock_user_id = wp_check_post_lock( $this->changeset_post_id() ); 2388 } 2389 2390 // Force request to autosave when changeset is locked. 2391 if ( $lock_user_id && ! $autosave ) { 2392 $autosave = true; 2393 $changeset_status = null; 2394 $changeset_date_gmt = null; 2395 } 2396 2380 2397 if ( $autosave && ! defined( 'DOING_AUTOSAVE' ) ) { // Back-compat. 2381 2398 define( 'DOING_AUTOSAVE', true ); 2382 2399 } 2383 2400 2401 $autosaved = false; 2384 2402 $r = $this->save_changeset_post( array( 2385 2403 'status' => $changeset_status, … … 2389 2407 'autosave' => $autosave, 2390 2408 ) ); 2409 if ( $autosave && ! is_wp_error( $r ) ) { 2410 $autosaved = true; 2411 } 2412 2413 // If the changeset was locked and an autosave request wasn't itself an error, then now explicitly return with a failure. 2414 if ( $lock_user_id && ! is_wp_error( $r ) ) { 2415 $r = new WP_Error( 2416 'changeset_locked', 2417 __( 'Changeset is being edited by other user.' ), 2418 array( 2419 'lock_user' => $this->get_lock_user_data( $lock_user_id ), 2420 ) 2421 ); 2422 } 2423 2391 2424 if ( is_wp_error( $r ) ) { 2392 2425 $response = array( … … 2414 2447 } 2415 2448 2449 if ( 'publish' !== $response['changeset_status'] ) { 2450 $this->set_changeset_lock( $changeset_post->ID ); 2451 } 2452 2416 2453 if ( 'future' === $response['changeset_status'] ) { 2417 2454 $response['changeset_date'] = $changeset_post->post_date; … … 2421 2458 $response['next_changeset_uuid'] = wp_generate_uuid4(); 2422 2459 } 2460 } 2461 2462 if ( $autosave ) { 2463 $response['autosaved'] = $autosaved; 2423 2464 } 2424 2465 … … 2685 2726 'type' => $setting->type, 2686 2727 'user_id' => $args['user_id'], 2728 'date_modified_gmt' => current_time( 'mysql', true ), 2687 2729 ) 2688 2730 ); … … 2799 2841 2800 2842 // Delete autosave revision when the changeset is updated. 2801 $autosave_draft = wp_get_post_autosave( $changeset_post_id );2843 $autosave_draft = wp_get_post_autosave( $changeset_post_id, get_current_user_id() ); 2802 2844 if ( $autosave_draft ) { 2803 2845 wp_delete_post( $autosave_draft->ID, true ); … … 2991 3033 2992 3034 /** 3035 * Marks the changeset post as being currently edited by the current user. 3036 * 3037 * @since 4.9.0 3038 * 3039 * @param int $changeset_post_id Changeset post id. 3040 * @param bool $take_over Take over the changeset, default is false. 3041 */ 3042 public function set_changeset_lock( $changeset_post_id, $take_over = false ) { 3043 if ( $changeset_post_id ) { 3044 $can_override = ! (bool) get_post_meta( $changeset_post_id, '_edit_lock', true ); 3045 3046 if ( $take_over ) { 3047 $can_override = true; 3048 } 3049 3050 if ( $can_override ) { 3051 $lock = sprintf( '%s:%s', time(), get_current_user_id() ); 3052 update_post_meta( $changeset_post_id, '_edit_lock', $lock ); 3053 } else { 3054 $this->refresh_changeset_lock( $changeset_post_id ); 3055 } 3056 } 3057 } 3058 3059 /** 3060 * Refreshes changeset lock with the current time if current user edited the changeset before. 3061 * 3062 * @since 4.9.0 3063 * 3064 * @param int $changeset_post_id Changeset post id. 3065 */ 3066 public function refresh_changeset_lock( $changeset_post_id ) { 3067 if ( ! $changeset_post_id ) { 3068 return; 3069 } 3070 $lock = get_post_meta( $changeset_post_id, '_edit_lock', true ); 3071 $lock = explode( ':', $lock ); 3072 3073 if ( $lock && ! empty( $lock[1] ) ) { 3074 $user_id = intval( $lock[1] ); 3075 $current_user_id = get_current_user_id(); 3076 if ( $user_id === $current_user_id ) { 3077 $lock = sprintf( '%s:%s', time(), $user_id ); 3078 update_post_meta( $changeset_post_id, '_edit_lock', $lock ); 3079 } 3080 } 3081 } 3082 3083 /** 3084 * Filter heartbeat settings for the Customizer. 3085 * 3086 * @since 4.9.0 3087 * @param array $settings Current settings to filter. 3088 * @return array Heartbeat settings. 3089 */ 3090 public function add_customize_screen_to_heartbeat_settings( $settings ) { 3091 global $pagenow; 3092 if ( 'customize.php' === $pagenow ) { 3093 $settings['screenId'] = 'customize'; 3094 } 3095 return $settings; 3096 } 3097 3098 /** 3099 * Get lock user data. 3100 * 3101 * @since 4.9.0 3102 * 3103 * @param int $user_id User ID. 3104 * @return array|null User data formatted for client. 3105 */ 3106 protected function get_lock_user_data( $user_id ) { 3107 if ( ! $user_id ) { 3108 return null; 3109 } 3110 $lock_user = get_userdata( $user_id ); 3111 if ( ! $lock_user ) { 3112 return null; 3113 } 3114 return array( 3115 'id' => $lock_user->ID, 3116 'name' => $lock_user->display_name, 3117 'avatar' => get_avatar_url( $lock_user->ID, array( 'size' => 128 ) ), 3118 ); 3119 } 3120 3121 /** 3122 * Check locked changeset with heartbeat API. 3123 * 3124 * @since 4.9.0 3125 * 3126 * @param array $response The Heartbeat response. 3127 * @param array $data The $_POST data sent. 3128 * @param string $screen_id The screen id. 3129 * @return array The Heartbeat response. 3130 */ 3131 public function check_changeset_lock_with_heartbeat( $response, $data, $screen_id ) { 3132 if ( array_key_exists( 'check_changeset_lock', $data ) && 'customize' === $screen_id && current_user_can( 'customize' ) && $this->changeset_post_id() ) { 3133 $lock_user_id = wp_check_post_lock( $this->changeset_post_id() ); 3134 3135 if ( $lock_user_id ) { 3136 $response['customize_changeset_lock_user'] = $this->get_lock_user_data( $lock_user_id ); 3137 } else { 3138 3139 // Refreshing time will ensure that the user is sitting on customizer and has not closed the customizer tab. 3140 $this->refresh_changeset_lock( $this->changeset_post_id() ); 3141 } 3142 } 3143 3144 return $response; 3145 } 3146 3147 /** 3148 * Removes changeset lock when take over request is sent via Ajax. 3149 * 3150 * @since 4.9.0 3151 */ 3152 public function handle_override_changeset_lock_request() { 3153 if ( ! $this->is_preview() ) { 3154 wp_send_json_error( 'not_preview', 400 ); 3155 } 3156 3157 if ( ! check_ajax_referer( 'customize_override_changeset_lock', 'nonce', false ) ) { 3158 wp_send_json_error( array( 3159 'code' => 'invalid_nonce', 3160 'message' => __( 'Security check failed.' ), 3161 ) ); 3162 } 3163 3164 $changeset_post_id = $this->changeset_post_id(); 3165 3166 if ( empty( $changeset_post_id ) ) { 3167 wp_send_json_error( array( 3168 'code' => 'no_changeset_found_to_take_over', 3169 'message' => __( 'No changeset found to take over' ), 3170 ) ); 3171 } 3172 3173 if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->edit_post, $changeset_post_id ) ) { 3174 wp_send_json_error( array( 3175 'code' => 'cannot_remove_changeset_lock', 3176 'message' => __( 'Sorry you are not allowed to take over.' ), 3177 ) ); 3178 } 3179 3180 $this->set_changeset_lock( $changeset_post_id, true ); 3181 3182 wp_send_json_success( 'changeset_taken_over' ); 3183 } 3184 3185 /** 2993 3186 * Whether a changeset revision should be made. 2994 3187 * … … 3034 3227 * @since 4.7.0 3035 3228 * @see _wp_customize_publish_changeset() 3229 * @global wpdb $wpdb 3036 3230 * 3037 3231 * @param int $changeset_post_id ID for customize_changeset post. Defaults to the changeset for the current manager instance. … … 3039 3233 */ 3040 3234 public function _publish_changeset_values( $changeset_post_id ) { 3235 global $wpdb; 3236 3041 3237 $publishing_changeset_data = $this->get_changeset_post_data( $changeset_post_id ); 3042 3238 if ( is_wp_error( $publishing_changeset_data ) ) { … … 3176 3372 $this->_changeset_uuid = $previous_changeset_uuid; 3177 3373 3374 /* 3375 * Convert all autosave revisions into their own auto-drafts so that users can be prompted to 3376 * restore them when a changeset is published, but they had been locked out from including 3377 * their changes in the changeset. 3378 */ 3379 $revisions = wp_get_post_revisions( $changeset_post_id, array( 'check_enabled' => false ) ); 3380 foreach ( $revisions as $revision ) { 3381 if ( false !== strpos( $revision->post_name, "{$changeset_post_id}-autosave" ) ) { 3382 $wpdb->update( 3383 $wpdb->posts, 3384 array( 3385 'post_status' => 'auto-draft', 3386 'post_type' => 'customize_changeset', 3387 'post_name' => wp_generate_uuid4(), 3388 'post_parent' => 0, 3389 ), 3390 array( 3391 'ID' => $revision->ID, 3392 ) 3393 ); 3394 clean_post_cache( $revision->ID ); 3395 } 3396 } 3397 3178 3398 return true; 3179 3399 } … … 3230 3450 3231 3451 /** 3232 * Delete a given auto-draft changeset or the autosave revision for a given changeset .3452 * Delete a given auto-draft changeset or the autosave revision for a given changeset or delete changeset lock. 3233 3453 * 3234 3454 * @since 4.9.0 3235 3455 */ 3236 public function handle_dismiss_autosave_ request() {3456 public function handle_dismiss_autosave_or_lock_request() { 3237 3457 if ( ! $this->is_preview() ) { 3238 3458 wp_send_json_error( 'not_preview', 400 ); 3239 3459 } 3240 3460 3241 if ( ! check_ajax_referer( 'customize_dismiss_autosave ', 'nonce', false ) ) {3461 if ( ! check_ajax_referer( 'customize_dismiss_autosave_or_lock', 'nonce', false ) ) { 3242 3462 wp_send_json_error( 'invalid_nonce', 403 ); 3243 3463 } 3244 3464 3245 3465 $changeset_post_id = $this->changeset_post_id(); 3246 3247 if ( empty( $changeset_post_id ) || 'auto-draft' === get_post_status( $changeset_post_id ) ) { 3248 $dismissed = $this->dismiss_user_auto_draft_changesets(); 3249 if ( $dismissed > 0 ) { 3250 wp_send_json_success( 'auto_draft_dismissed' ); 3251 } else { 3252 wp_send_json_error( 'no_auto_draft_to_delete', 404 ); 3253 } 3254 } else { 3255 $revision = wp_get_post_autosave( $changeset_post_id ); 3256 3257 if ( $revision ) { 3258 if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->delete_post, $changeset_post_id ) ) { 3259 wp_send_json_error( 'cannot_delete_autosave_revision', 403 ); 3260 } 3261 3262 if ( ! wp_delete_post( $revision->ID, true ) ) { 3263 wp_send_json_error( 'autosave_revision_deletion_failure', 500 ); 3466 $dismiss_lock = ! empty( $_POST['dismiss_lock'] ); 3467 $dismiss_autosave = ! empty( $_POST['dismiss_autosave'] ); 3468 3469 if ( $dismiss_lock ) { 3470 if ( empty( $changeset_post_id ) && ! $dismiss_autosave ) { 3471 wp_send_json_error( 'no_changeset_to_dismiss_lock', 404 ); 3472 } 3473 if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->edit_post, $changeset_post_id ) && ! $dismiss_autosave ) { 3474 wp_send_json_error( 'cannot_remove_changeset_lock', 403 ); 3475 } 3476 3477 delete_post_meta( $changeset_post_id, '_edit_lock' ); 3478 3479 if ( ! $dismiss_autosave ) { 3480 wp_send_json_success( 'changeset_lock_dismissed' ); 3481 } 3482 } 3483 3484 if ( $dismiss_autosave ) { 3485 if ( empty( $changeset_post_id ) || 'auto-draft' === get_post_status( $changeset_post_id ) ) { 3486 $dismissed = $this->dismiss_user_auto_draft_changesets(); 3487 if ( $dismissed > 0 ) { 3488 wp_send_json_success( 'auto_draft_dismissed' ); 3264 3489 } else { 3265 wp_send_json_ success( 'autosave_revision_deleted');3490 wp_send_json_error( 'no_auto_draft_to_delete', 404 ); 3266 3491 } 3267 3492 } else { 3268 wp_send_json_error( 'no_autosave_revision_to_delete', 404 ); 3269 } 3270 } 3493 $revision = wp_get_post_autosave( $changeset_post_id, get_current_user_id() ); 3494 3495 if ( $revision ) { 3496 if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->delete_post, $changeset_post_id ) ) { 3497 wp_send_json_error( 'cannot_delete_autosave_revision', 403 ); 3498 } 3499 3500 if ( ! wp_delete_post( $revision->ID, true ) ) { 3501 wp_send_json_error( 'autosave_revision_deletion_failure', 500 ); 3502 } else { 3503 wp_send_json_success( 'autosave_revision_deleted' ); 3504 } 3505 } else { 3506 wp_send_json_error( 'no_autosave_revision_to_delete', 404 ); 3507 } 3508 } 3509 } 3510 3271 3511 wp_send_json_error( 'unknown_error', 500 ); 3272 3512 } … … 3818 4058 </script> 3819 4059 4060 <script type="text/html" id="tmpl-customize-changeset-locked-notification"> 4061 <li class="notice notice-{{ data.type || 'info' }} {{ data.containerClasses || '' }}" data-code="{{ data.code }}" data-type="{{ data.type }}"> 4062 <div class="notification-message customize-changeset-locked-message"> 4063 <img class="customize-changeset-locked-avatar" src="{{ data.lockUser.avatar }}" alt="{{ data.lockUser.name }}"> 4064 <p class="currently-editing"> 4065 <# if ( data.message ) { #> 4066 {{{ data.message }}} 4067 <# } else if ( data.allowOverride ) { #> 4068 <?php 4069 /* translators: %s: User who is customizing the changeset in customizer. */ 4070 printf( __( '%s is already customizing this site. Do you want to take over?' ), '{{ data.lockUser.name }}' ); 4071 ?> 4072 <# } else { #> 4073 <?php 4074 /* translators: %s: User who is customizing the changeset in customizer. */ 4075 printf( __( '%s is already customizing this site. Please wait until they are done to try customizing. Your latest changes have been autosaved.' ), '{{ data.lockUser.name }}' ); 4076 ?> 4077 <# } #> 4078 </p> 4079 <p class="notice notice-error notice-alt" hidden></p> 4080 <p class="action-buttons"> 4081 <# if ( data.returnUrl !== data.previewUrl ) { #> 4082 <a class="button customize-notice-go-back-button" href="{{ data.returnUrl }}"><?php _e( 'Go back' ); ?></a> 4083 <# } #> 4084 <a class="button customize-notice-preview-button" href="{{ data.frontendPreviewUrl }}"><?php _e( 'Preview' ); ?></a> 4085 <# if ( data.allowOverride ) { #> 4086 <button class="button button-primary wp-tab-last customize-notice-take-over-button"><?php _e( 'Take over' ); ?></button> 4087 <# } #> 4088 </p> 4089 </div> 4090 </li> 4091 </script> 4092 3820 4093 <?php 3821 4094 /* The following template is obsolete in core but retained for plugins. */ … … 4189 4462 'preview' => wp_create_nonce( 'preview-customize_' . $this->get_stylesheet() ), 4190 4463 'switch_themes' => wp_create_nonce( 'switch_themes' ), 4191 'dismiss_autosave' => wp_create_nonce( 'customize_dismiss_autosave' ), 4464 'dismiss_autosave_or_lock' => wp_create_nonce( 'customize_dismiss_autosave_or_lock' ), 4465 'override_lock' => wp_create_nonce( 'customize_override_changeset_lock' ), 4192 4466 'trash' => wp_create_nonce( 'trash_customize_changeset' ), 4193 4467 ); … … 4232 4506 if ( ! $this->saved_starter_content_changeset && ! $this->autosaved() ) { 4233 4507 if ( $changeset_post_id ) { 4234 $autosave_revision_post = wp_get_post_autosave( $changeset_post_id );4508 $autosave_revision_post = wp_get_post_autosave( $changeset_post_id, get_current_user_id() ); 4235 4509 } else { 4236 4510 $autosave_autodraft_posts = $this->get_changeset_posts( array( … … 4276 4550 } else { 4277 4551 $initial_date = current_time( 'mysql', false ); 4552 } 4553 4554 $lock_user_id = false; 4555 if ( $this->changeset_post_id() ) { 4556 $lock_user_id = wp_check_post_lock( $this->changeset_post_id() ); 4278 4557 } 4279 4558 … … 4289 4568 'publishDate' => $initial_date, 4290 4569 'statusChoices' => $status_choices, 4570 'lockUser' => $lock_user_id ? $this->get_lock_user_data( $lock_user_id ) : null, 4291 4571 ), 4292 4572 'initialServerDate' => current_time( 'mysql', false ),
Note: See TracChangeset
for help on using the changeset viewer.