Autosave: refactor autosave.js, use heartbeat for transport and move all "Add/Edit Post" related functionality to post.js. See #25272.
Built from https://develop.svn.wordpress.org/trunk@26995 git-svn-id: http://core.svn.wordpress.org/trunk@26872 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
@@ -1089,68 +1089,6 @@ function wp_ajax_add_user( $action ) {
|
||||
$x->send();
|
||||
}
|
||||
|
||||
function wp_ajax_autosave() {
|
||||
define( 'DOING_AUTOSAVE', true );
|
||||
|
||||
check_ajax_referer( 'autosave', 'autosavenonce' );
|
||||
|
||||
if ( ! empty( $_POST['catslist'] ) )
|
||||
$_POST['post_category'] = explode( ',', $_POST['catslist'] );
|
||||
if ( $_POST['post_type'] == 'page' || empty( $_POST['post_category'] ) )
|
||||
unset( $_POST['post_category'] );
|
||||
|
||||
$data = '';
|
||||
$supplemental = array();
|
||||
$id = $revision_id = 0;
|
||||
|
||||
$post_id = (int) $_POST['post_id'];
|
||||
$_POST['ID'] = $_POST['post_ID'] = $post_id;
|
||||
$post = get_post( $post_id );
|
||||
if ( empty( $post->ID ) || ! current_user_can( 'edit_post', $post->ID ) )
|
||||
wp_die( __( 'You are not allowed to edit this post.' ) );
|
||||
|
||||
if ( 'page' == $post->post_type && ! current_user_can( 'edit_page', $post->ID ) )
|
||||
wp_die( __( 'You are not allowed to edit this page.' ) );
|
||||
|
||||
if ( 'auto-draft' == $post->post_status )
|
||||
$_POST['post_status'] = 'draft';
|
||||
|
||||
if ( ! empty( $_POST['autosave'] ) ) {
|
||||
if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
|
||||
// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
|
||||
$id = edit_post();
|
||||
} else {
|
||||
// Non drafts or other users drafts are not overwritten. The autosave is stored in a special post revision for each user.
|
||||
$revision_id = wp_create_post_autosave( $post->ID );
|
||||
if ( is_wp_error($revision_id) )
|
||||
$id = $revision_id;
|
||||
else
|
||||
$id = $post->ID;
|
||||
}
|
||||
|
||||
if ( ! is_wp_error($id) ) {
|
||||
/* translators: draft saved date format, see http://php.net/date */
|
||||
$draft_saved_date_format = __('g:i:s a');
|
||||
/* translators: %s: date and time */
|
||||
$data = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $_POST['auto_draft'] ) )
|
||||
$id = 0; // This tells us it didn't actually save
|
||||
else
|
||||
$id = $post->ID;
|
||||
}
|
||||
|
||||
// @todo Consider exposing any errors, rather than having 'Saving draft...'
|
||||
$x = new WP_Ajax_Response( array(
|
||||
'what' => 'autosave',
|
||||
'id' => $id,
|
||||
'data' => $data,
|
||||
'supplemental' => $supplemental
|
||||
) );
|
||||
$x->send();
|
||||
}
|
||||
|
||||
function wp_ajax_closed_postboxes() {
|
||||
check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
|
||||
$closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
|
||||
|
||||
@@ -734,7 +734,6 @@ function wp_refresh_post_nonces( $response, $data, $screen_id ) {
|
||||
if ( 2 === wp_verify_nonce( $received['post_nonce'], 'update-post_' . $post_id ) ) {
|
||||
$response['wp-refresh-post-nonces'] = array(
|
||||
'replace' => array(
|
||||
'autosavenonce' => wp_create_nonce('autosave'),
|
||||
'getpermalinknonce' => wp_create_nonce('getpermalink'),
|
||||
'samplepermalinknonce' => wp_create_nonce('samplepermalink'),
|
||||
'closedpostboxesnonce' => wp_create_nonce('closedpostboxes'),
|
||||
@@ -768,3 +767,29 @@ function wp_heartbeat_set_suspension( $settings ) {
|
||||
return $settings;
|
||||
}
|
||||
add_filter( 'heartbeat_settings', 'wp_heartbeat_set_suspension' );
|
||||
|
||||
/**
|
||||
* Autosave with heartbeat
|
||||
*
|
||||
* @since 3.9
|
||||
*/
|
||||
function heartbeat_autosave( $response, $data ) {
|
||||
if ( ! empty( $data['wp_autosave'] ) ) {
|
||||
$saved = wp_autosave( $data['wp_autosave'] );
|
||||
|
||||
if ( is_wp_error( $saved ) ) {
|
||||
$response['wp_autosave'] = array( 'success' => false, 'message' => $saved->get_error_message() );
|
||||
} elseif ( empty( $saved ) ) {
|
||||
$response['wp_autosave'] = array( 'success' => false, 'message' => __( 'Error while saving.' ) );
|
||||
} else {
|
||||
/* translators: draft saved date format, see http://php.net/date */
|
||||
$draft_saved_date_format = __( 'g:i:s a' );
|
||||
/* translators: %s: date and time */
|
||||
$response['wp_autosave'] = array( 'success' => true, 'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
// Run later as we have to set DOING_AUTOSAVE for back-compat
|
||||
add_filter( 'heartbeat_received', 'heartbeat_autosave', 500, 2 );
|
||||
|
||||
@@ -79,9 +79,14 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $post_data['post_status'] ) )
|
||||
if ( ! empty( $post_data['post_status'] ) ) {
|
||||
$post_data['post_status'] = sanitize_key( $post_data['post_status'] );
|
||||
|
||||
// No longer an auto-draft
|
||||
if ( 'auto-draft' == $post_data['post_status'] )
|
||||
$post_data['post_status'] = 'draft';
|
||||
}
|
||||
|
||||
// What to do based on which button they pressed
|
||||
if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
|
||||
$post_data['post_status'] = 'draft';
|
||||
@@ -190,9 +195,6 @@ function edit_post( $post_data = null ) {
|
||||
$post_data = _wp_translate_postdata( true, $post_data );
|
||||
if ( is_wp_error($post_data) )
|
||||
wp_die( $post_data->get_error_message() );
|
||||
if ( ( empty( $post_data['action'] ) || 'autosave' != $post_data['action'] ) && 'auto-draft' == $post_data['post_status'] ) {
|
||||
$post_data['post_status'] = 'draft';
|
||||
}
|
||||
|
||||
if ( isset($post_data['visibility']) ) {
|
||||
switch ( $post_data['visibility'] ) {
|
||||
@@ -1335,22 +1337,30 @@ function _admin_notice_post_locked() {
|
||||
* @uses _wp_translate_postdata()
|
||||
* @uses _wp_post_revision_fields()
|
||||
*
|
||||
* @return unknown
|
||||
* @param mixed $post_data Associative array containing the post data or int post ID.
|
||||
* @return mixed The autosave revision ID. WP_Error or 0 on error.
|
||||
*/
|
||||
function wp_create_post_autosave( $post_id ) {
|
||||
$translated = _wp_translate_postdata( true );
|
||||
if ( is_wp_error( $translated ) )
|
||||
return $translated;
|
||||
function wp_create_post_autosave( $post_data ) {
|
||||
if ( is_numeric( $post_data ) ) {
|
||||
$post_id = $post_data;
|
||||
$post_data = &$_POST;
|
||||
} else {
|
||||
$post_id = (int) $post_data['post_ID'];
|
||||
}
|
||||
|
||||
$post_data = _wp_translate_postdata( true, $post_data );
|
||||
if ( is_wp_error( $post_data ) )
|
||||
return $post_data;
|
||||
|
||||
$post_author = get_current_user_id();
|
||||
|
||||
// Store one autosave per author. If there is already an autosave, overwrite it.
|
||||
if ( $old_autosave = wp_get_post_autosave( $post_id, $post_author ) ) {
|
||||
$new_autosave = _wp_post_revision_fields( $_POST, true );
|
||||
$new_autosave = _wp_post_revision_fields( $post_data, true );
|
||||
$new_autosave['ID'] = $old_autosave->ID;
|
||||
$new_autosave['post_author'] = $post_author;
|
||||
|
||||
// If the new autosave is the same content as the post, delete the old autosave.
|
||||
// If the new autosave has the same content as the post, delete the autosave.
|
||||
$post = get_post( $post_id );
|
||||
$autosave_is_different = false;
|
||||
foreach ( array_keys( _wp_post_revision_fields() ) as $field ) {
|
||||
@@ -1362,14 +1372,14 @@ function wp_create_post_autosave( $post_id ) {
|
||||
|
||||
if ( ! $autosave_is_different ) {
|
||||
wp_delete_post_revision( $old_autosave->ID );
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return wp_update_post( $new_autosave );
|
||||
}
|
||||
|
||||
// _wp_put_post_revision() expects unescaped.
|
||||
$post_data = wp_unslash( $_POST );
|
||||
$post_data = wp_unslash( $post_data );
|
||||
|
||||
// Otherwise create the new autosave as a special post revision
|
||||
return _wp_put_post_revision( $post_data, true );
|
||||
@@ -1395,58 +1405,82 @@ function wp_create_post_autosave( $post_id ) {
|
||||
function post_preview() {
|
||||
|
||||
$post_ID = (int) $_POST['post_ID'];
|
||||
$status = get_post_status( $post_ID );
|
||||
if ( 'auto-draft' == $status )
|
||||
wp_die( __('Preview not available. Please save as a draft first.') );
|
||||
|
||||
if ( isset($_POST['catslist']) )
|
||||
$_POST['post_category'] = explode(",", $_POST['catslist']);
|
||||
|
||||
if ( isset($_POST['tags_input']) )
|
||||
$_POST['tags_input'] = explode(",", $_POST['tags_input']);
|
||||
|
||||
if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
|
||||
unset($_POST['post_category']);
|
||||
|
||||
$_POST['ID'] = $post_ID;
|
||||
$post = get_post($post_ID);
|
||||
|
||||
if ( 'page' == $post->post_type ) {
|
||||
if ( ! current_user_can('edit_page', $post_ID) )
|
||||
wp_die( __('You are not allowed to edit this page.') );
|
||||
if ( ! $post = get_post( $post_ID ) )
|
||||
wp_die( __('You attempted to preview a non existing item.') );
|
||||
|
||||
if ( ! current_user_can( 'edit_post', $post->ID ) )
|
||||
wp_die( __('You are not allowed to preview this item.') );
|
||||
|
||||
$is_autosave = false;
|
||||
|
||||
if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'draft' == $post->post_status || 'auto-draft' == $post->post_status ) ) {
|
||||
$saved_post_id = edit_post();
|
||||
} else {
|
||||
if ( ! current_user_can('edit_post', $post_ID) )
|
||||
wp_die( __('You are not allowed to edit this post.') );
|
||||
$is_autosave = true;
|
||||
|
||||
if ( 'auto-draft' == $_POST['post_status'] )
|
||||
$_POST['post_status'] = 'draft';
|
||||
|
||||
$saved_post_id = wp_create_post_autosave( $post->ID );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$locked = wp_check_post_lock( $post->ID );
|
||||
if ( ! $locked && 'draft' == $post->post_status && $user_id == $post->post_author ) {
|
||||
$id = edit_post();
|
||||
} else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
|
||||
$id = wp_create_post_autosave( $post->ID );
|
||||
if ( ! is_wp_error($id) )
|
||||
$id = $post->ID;
|
||||
}
|
||||
if ( is_wp_error( $saved_post_id ) )
|
||||
wp_die( $saved_post_id->get_error_message() );
|
||||
|
||||
if ( is_wp_error($id) )
|
||||
wp_die( $id->get_error_message() );
|
||||
$query_args = array( 'preview' => 'true' );
|
||||
|
||||
if ( ! $locked && $_POST['post_status'] == 'draft' && $user_id == $post->post_author ) {
|
||||
$url = add_query_arg( 'preview', 'true', get_permalink($id) );
|
||||
} else {
|
||||
$nonce = wp_create_nonce('post_preview_' . $id);
|
||||
$args = array(
|
||||
'preview' => 'true',
|
||||
'preview_id' => $id,
|
||||
'preview_nonce' => $nonce,
|
||||
);
|
||||
if ( $is_autosave && $saved_post_id ) {
|
||||
$query_args['preview_id'] = $post->ID;
|
||||
$query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $post->ID );
|
||||
|
||||
if ( isset( $_POST['post_format'] ) )
|
||||
$args['post_format'] = empty( $_POST['post_format'] ) ? 'standard' : sanitize_key( $_POST['post_format'] );
|
||||
|
||||
$url = add_query_arg( $args, get_permalink($id) );
|
||||
$query_args['post_format'] = empty( $_POST['post_format'] ) ? 'standard' : sanitize_key( $_POST['post_format'] );
|
||||
}
|
||||
|
||||
$url = add_query_arg( $query_args, get_permalink( $post->ID ) );
|
||||
return apply_filters( 'preview_post_link', $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a post submitted with XHR
|
||||
*
|
||||
* Intended for use with heartbeat and autosave.js
|
||||
*
|
||||
* @since 3.9
|
||||
*
|
||||
* @param $post_data Associative array of the submitted post data.
|
||||
* @return mixed The value 0 or WP_Error on failure. The saved post ID on success.
|
||||
* Te ID can be the draft post_id or the autosave revision post_id.
|
||||
*/
|
||||
function wp_autosave( $post_data ) {
|
||||
// Back-compat
|
||||
if ( ! defined( 'DOING_AUTOSAVE' ) )
|
||||
define( 'DOING_AUTOSAVE', true );
|
||||
|
||||
$post_id = (int) $post_data['post_id'];
|
||||
$post_data['ID'] = $post_data['post_ID'] = $post_id;
|
||||
|
||||
if ( false === wp_verify_nonce( $post_data['_wpnonce'], 'update-post_' . $post_id ) )
|
||||
return new WP_Error( 'invalid_nonce', __('ERROR: invalid post data.') );
|
||||
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! current_user_can( 'edit_post', $post->ID ) )
|
||||
return new WP_Error( 'edit_post', __('You are not allowed to edit this item.') );
|
||||
|
||||
if ( 'auto-draft' == $post->post_status )
|
||||
$post_data['post_status'] = 'draft';
|
||||
|
||||
if ( $post_data['post_type'] != 'page' && ! empty( $post_data['catslist'] ) )
|
||||
$post_data['post_category'] = explode( ',', $post_data['catslist'] );
|
||||
|
||||
if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
|
||||
// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
|
||||
return edit_post( $post_data );
|
||||
} else {
|
||||
// Non drafts or other users drafts are not overwritten. The autosave is stored in a special post revision for each user.
|
||||
return wp_create_post_autosave( $post_data );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user