public function test_is_autosave_dont_flush_cache()
 {
     $post = $this->factory->post->create_and_get();
     $revision_id = _wp_put_post_revision($post, true);
     $salt = $this->obj->cache_salt;
     $revision = get_post($revision_id);
     $this->obj->clean_post_cache($revision->ID, $revision);
     $this->assertsame($salt, $this->obj->cache_salt);
 }
 /**
  * Update an autosave for a post.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return WP_Error|WP_REST_Response
  */
 public function update_item($request)
 {
     $parent = get_post($request['id']);
     $autosave = wp_get_post_autosave($parent->ID, get_current_user_id());
     $post_data = (array) $this->prepare_item_for_database($request);
     if (!$autosave) {
         $autosave_id = _wp_put_post_revision($post_data, true);
     } else {
         $post_data['ID'] = $autosave->ID;
         /**
          * Fires before an autosave is stored.
          *
          * @since 4.1.0
          *
          * @param array $new_autosave Post array - the autosave that is about to be saved.
          */
         do_action('wp_creating_autosave', $post_data);
         wp_update_post($post_data);
         $autosave_id = $autosave->ID;
     }
     return $this->prepare_item_for_response(get_post($autosave_id), $request);
 }
Example #3
0
/**
 * Saves an already existing post as a post revision.
 *
 * Typically used immediately prior to post updates.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @uses _wp_put_post_revision()
 *
 * @param int $post_id The ID of the post to save as a revision.
 * @return mixed Null or 0 if error, new revision ID, if success.
 */
function wp_save_post_revision($post_id)
{
    // We do autosaves manually with wp_create_post_autosave()
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    // WP_POST_REVISIONS = 0, false
    if (!WP_POST_REVISIONS) {
        return;
    }
    if (!($post = get_post($post_id, ARRAY_A))) {
        return;
    }
    if (!post_type_supports($post['post_type'], 'revisions')) {
        return;
    }
    $return = _wp_put_post_revision($post);
    // WP_POST_REVISIONS = true (default), -1
    if (!is_numeric(WP_POST_REVISIONS) || WP_POST_REVISIONS < 0) {
        return $return;
    }
    // all revisions and (possibly) one autosave
    $revisions = wp_get_post_revisions($post_id, array('order' => 'ASC'));
    // WP_POST_REVISIONS = (int) (# of autosaves to save)
    $delete = count($revisions) - WP_POST_REVISIONS;
    if ($delete < 1) {
        return $return;
    }
    $revisions = array_slice($revisions, 0, $delete);
    for ($i = 0; isset($revisions[$i]); $i++) {
        if (false !== strpos($revisions[$i]->post_name, 'autosave')) {
            continue;
        }
        wp_delete_post_revision($revisions[$i]->ID);
    }
    return $return;
}
/**
 * Creates a revision for the current version of a post.
 *
 * Typically used immediately after a post update, as every update is a revision,
 * and the most recent revision always matches the current post.
 *
 * @since 2.6.0
 *
 * @param int $post_id The ID of the post to save as a revision.
 * @return int|WP_Error|void Void or 0 if error, new revision ID, if success.
 */
function wp_save_post_revision($post_id)
{
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (!($post = get_post($post_id))) {
        return;
    }
    if (!post_type_supports($post->post_type, 'revisions')) {
        return;
    }
    if ('auto-draft' == $post->post_status) {
        return;
    }
    if (!wp_revisions_enabled($post)) {
        return;
    }
    // Compare the proposed update with the last stored revision verifying that
    // they are different, unless a plugin tells us to always save regardless.
    // If no previous revisions, save one
    if ($revisions = wp_get_post_revisions($post_id)) {
        // grab the last revision, but not an autosave
        foreach ($revisions as $revision) {
            if (false !== strpos($revision->post_name, "{$revision->post_parent}-revision")) {
                $last_revision = $revision;
                break;
            }
        }
        /**
         * Filter whether the post has changed since the last revision.
         *
         * By default a revision is saved only if one of the revisioned fields has changed.
         * This filter can override that so a revision is saved even if nothing has changed.
         *
         * @since 3.6.0
         *
         * @param bool    $check_for_changes Whether to check for changes before saving a new revision.
         *                                   Default true.
         * @param WP_Post $last_revision     The the last revision post object.
         * @param WP_Post $post              The post object.
         *
         */
        if (isset($last_revision) && apply_filters('wp_save_post_revision_check_for_changes', $check_for_changes = true, $last_revision, $post)) {
            $post_has_changed = false;
            foreach (array_keys(_wp_post_revision_fields()) as $field) {
                if (normalize_whitespace($post->{$field}) != normalize_whitespace($last_revision->{$field})) {
                    $post_has_changed = true;
                    break;
                }
            }
            /**
             * Filter whether a post has changed.
             *
             * By default a revision is saved only if one of the revisioned fields has changed.
             * This filter allows for additional checks to determine if there were changes.
             *
             * @since 4.1.0
             *
             * @param bool    $post_has_changed Whether the post has changed.
             * @param WP_Post $last_revision    The last revision post object.
             * @param WP_Post $post             The post object.
             *
             */
            $post_has_changed = (bool) apply_filters('wp_save_post_revision_post_has_changed', $post_has_changed, $last_revision, $post);
            //don't save revision if post unchanged
            if (!$post_has_changed) {
                return;
            }
        }
    }
    $return = _wp_put_post_revision($post);
    // If a limit for the number of revisions to keep has been set,
    // delete the oldest ones.
    $revisions_to_keep = wp_revisions_to_keep($post);
    if ($revisions_to_keep < 0) {
        return $return;
    }
    $revisions = wp_get_post_revisions($post_id, array('order' => 'ASC'));
    $delete = count($revisions) - $revisions_to_keep;
    if ($delete < 1) {
        return $return;
    }
    $revisions = array_slice($revisions, 0, $delete);
    for ($i = 0; isset($revisions[$i]); $i++) {
        if (false !== strpos($revisions[$i]->post_name, 'autosave')) {
            continue;
        }
        wp_delete_post_revision($revisions[$i]->ID);
    }
    return $return;
}
Example #5
0
 /**
  * Save new revision of CSS
  * Checks to see if content was modified before really saving
  *
  * @param string $css
  * @param bool $is_preview
  * @return bool|int If nothing was saved, returns false. If a post
  *                  or revision was saved, returns the post ID.
  */
 static function save_revision($css, $is_preview = false, $preprocessor = '')
 {
     $safecss_post = Jetpack_Custom_CSS::get_post();
     $compressed_css = Jetpack_Custom_CSS::minify($css, $preprocessor);
     // If null, there was no original safecss record, so create one
     if (null == $safecss_post) {
         if (!$css) {
             return false;
         }
         $post = array();
         $post['post_content'] = $css;
         $post['post_title'] = 'safecss';
         $post['post_status'] = 'publish';
         $post['post_type'] = 'safecss';
         $post['post_content_filtered'] = $compressed_css;
         // Set excerpt to current theme, for display in revisions list
         if (function_exists('wp_get_theme')) {
             $current_theme = wp_get_theme();
             $post['post_excerpt'] = $current_theme->Name;
         } else {
             $post['post_excerpt'] = get_current_theme();
         }
         // Insert the CSS into wp_posts
         $post_id = wp_insert_post($post);
         wp_cache_set('custom_css_post_id', $post_id);
         return $post_id;
     }
     // Update CSS in post array with new value passed to this function
     $safecss_post['post_content'] = $css;
     $safecss_post['post_content_filtered'] = $compressed_css;
     // Set excerpt to current theme, for display in revisions list
     if (function_exists('wp_get_theme')) {
         $current_theme = wp_get_theme();
         $safecss_post['post_excerpt'] = $current_theme->Name;
     } else {
         $safecss_post['post_excerpt'] = get_current_theme();
     }
     // Don't carry over last revision's timestamps, otherwise revisions all have matching timestamps
     unset($safecss_post['post_date']);
     unset($safecss_post['post_date_gmt']);
     unset($safecss_post['post_modified']);
     unset($safecss_post['post_modified_gmt']);
     // Do not update post if we are only saving a preview
     if (false === $is_preview) {
         $post_id = wp_update_post($safecss_post);
         wp_cache_set('custom_css_post_id', $post_id);
         return $post_id;
     } else {
         if (!defined('DOING_MIGRATE')) {
             return _wp_put_post_revision($safecss_post);
         }
     }
 }
Example #6
0
/**
 * Creates autosave data for the specified post from $_POST data.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @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_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_data($post_data, true);
        $new_autosave['ID'] = $old_autosave->ID;
        $new_autosave['post_author'] = $post_author;
        // 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_intersect(array_keys($new_autosave), array_keys(_wp_post_revision_fields($post))) as $field) {
            if (normalize_whitespace($new_autosave[$field]) != normalize_whitespace($post->{$field})) {
                $autosave_is_different = true;
                break;
            }
        }
        if (!$autosave_is_different) {
            wp_delete_post_revision($old_autosave->ID);
            return 0;
        }
        /**
         * Fires before an autosave is stored.
         *
         * @since 4.1.0
         *
         * @param array $new_autosave Post array - the autosave that is about to be saved.
         */
        do_action('wp_creating_autosave', $new_autosave);
        return wp_update_post($new_autosave);
    }
    // _wp_put_post_revision() expects unescaped.
    $post_data = wp_unslash($post_data);
    // Otherwise create the new autosave as a special post revision
    return _wp_put_post_revision($post_data, true);
}
Example #7
0
/**
 * Creates autosave data for the specified post from $_POST data.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @uses _wp_translate_postdata()
 * @uses _wp_post_revision_fields()
 *
 * @return unknown
 */
function wp_create_post_autosave($post_id)
{
    $translated = _wp_translate_postdata(true);
    if (is_wp_error($translated)) {
        return $translated;
    }
    $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['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.
        $post = get_post($post_id);
        $autosave_is_different = false;
        foreach (array_keys(_wp_post_revision_fields()) as $field) {
            if (normalize_whitespace($new_autosave[$field]) != normalize_whitespace($post->{$field})) {
                $autosave_is_different = true;
                break;
            }
        }
        if (!$autosave_is_different) {
            wp_delete_post_revision($old_autosave->ID);
            return;
        }
        return wp_update_post($new_autosave);
    }
    // _wp_put_post_revision() expects unescaped.
    $post_data = wp_unslash($_POST);
    // Otherwise create the new autosave as a special post revision
    return _wp_put_post_revision($post_data, true);
}
 function insert_post($update = false, $freshness = 2)
 {
     global $wpdb;
     $dbpost = $this->normalize_post(true);
     if (!is_null($dbpost)) {
         $dbpost['post_pingback'] = false;
         // Tell WP 2.1 and 2.2 not to process for pingbacks
         // This is a ridiculous f*****g kludge necessitated by WordPress 2.6 munging authorship meta-data
         add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
         // Kludge to prevent kses filters from stripping the
         // content of posts when updating without a logged in
         // user who has `unfiltered_html` capability.
         $mungers = array('wp_filter_kses', 'wp_filter_post_kses');
         $removed = array();
         foreach ($mungers as $munger) {
             if (has_filter('content_save_pre', $munger)) {
                 remove_filter('content_save_pre', $munger);
                 $removed[] = $munger;
             }
         }
         if ($update and function_exists('get_post_field')) {
             // Don't munge status fields that the user may
             // have reset manually
             $doNotMunge = array('post_status', 'comment_status', 'ping_status');
             foreach ($doNotMunge as $field) {
                 $dbpost[$field] = get_post_field($field, $this->wp_id());
             }
         }
         // WP3's wp_insert_post scans current_user_can() for the
         // tax_input, with no apparent way to override. Ugh.
         add_action('transition_post_status', array($this, 'add_terms'), -10001, 3);
         // WP3 appears to override whatever you give it for
         // post_modified. Ugh.
         add_action('transition_post_status', array($this, 'fix_post_modified_ts'), -10000, 3);
         if ($update) {
             $this->post['ID'] = $this->wp_id();
             $dbpost['ID'] = $this->post['ID'];
         }
         // O.K., is this a new post? If so, we need to create
         // the basic post record before we do anything else.
         if ($this->this_revision_needs_original_post()) {
             // *sigh*, for handling inconsistent slash expectations < 3.6
             $sdbpost = $this->db_sanitize_post($dbpost);
             // Go ahead and insert the first post record to
             // anchor the revision history.
             $this->_wp_id = wp_insert_post($sdbpost, true);
             $dbpost['ID'] = $this->_wp_id;
         }
         // Now that we've made sure the original exists, insert
         // this version here as a revision.
         $revision_id = _wp_put_post_revision($dbpost, false);
         if (!$this->this_revision_needs_original_post()) {
             if ($this->this_revision_is_current()) {
                 wp_restore_post_revision($revision_id);
             } else {
                 // If we do not activate this revision, then the
                 // add_rss_meta will not be called, which is
                 // more or less as it should be, but that means
                 // we have to actively record this revision's
                 // update hash from here.
                 $postId = $this->post['ID'];
                 $key = 'syndication_item_hash';
                 $hash = $this->update_hash();
                 FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [{$postId}]: [{$key}] = " . FeedWordPress::val($hash, true));
                 add_post_meta($postId, $key, $hash, false);
             }
         }
         remove_action('transition_post_status', array($this, 'add_terms'), -10001, 3);
         remove_action('transition_post_status', array($this, 'fix_post_modified_ts'), -10000, 3);
         // Turn off ridiculous f*****g kludges #1 and #2
         remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
         foreach ($removed as $filter) {
             add_filter('content_save_pre', $filter);
         }
         $this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
     }
 }
Example #9
0
/**
 * Creates autosave data for the specified post from $_POST data.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @uses _wp_translate_postdata()
 * @uses _wp_post_revision_fields()
 *
 * @return unknown
 */
function wp_create_post_autosave($post_id)
{
    $translated = _wp_translate_postdata(true);
    if (is_wp_error($translated)) {
        return $translated;
    }
    // Only store one autosave. If there is already an autosave, overwrite it.
    if ($old_autosave = wp_get_post_autosave($post_id)) {
        $new_autosave = _wp_post_revision_fields($_POST, true);
        $new_autosave['ID'] = $old_autosave->ID;
        $new_autosave['post_author'] = get_current_user_id();
        return wp_update_post($new_autosave);
    }
    // _wp_put_post_revision() expects unescaped.
    $_POST = stripslashes_deep($_POST);
    // Otherwise create the new autosave as a special post revision
    return _wp_put_post_revision($_POST, true);
}
Example #10
0
/**
 * Creates autosave data for the specified post from $_POST data.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @uses _wp_translate_postdata()
 * @uses _wp_post_revision_fields()
 */
function wp_create_post_autosave($post_id)
{
    $translated = _wp_translate_postdata(true);
    if (is_wp_error($translated)) {
        return $translated;
    }
    // Only store one autosave.  If there is already an autosave, overwrite it.
    if ($old_autosave = wp_get_post_autosave($post_id)) {
        $new_autosave = _wp_post_revision_fields($_POST, true);
        $new_autosave['ID'] = $old_autosave->ID;
        return wp_update_post($new_autosave);
    }
    // Otherwise create the new autosave as a special post revision
    return _wp_put_post_revision($_POST, true);
}
Example #11
0
/**
 * Save new revision of CSS
 * Checks to see if content was modified before really saving
 *
 * @param string $css
 * @param bool $is_preview
 * @return bool
 */
function save_revision($css, $is_preview = false)
{
    // If null, there was no original safecss record, so create one
    if (!($safecss_post = get_safecss_post())) {
        $post = array();
        $post['post_content'] = $css;
        $post['post_title'] = 'safecss';
        $post['post_status'] = 'publish';
        $post['post_type'] = 'safecss';
        // Insert the CSS into wp_posts
        $post_id = wp_insert_post($post);
        return true;
    }
    $safecss_post['post_content'] = $css;
    // Do not update post if we are only saving a preview
    if (false === $is_preview) {
        wp_update_post($safecss_post);
    }
    if (!defined('DOING_MIGRATE')) {
        _wp_put_post_revision($safecss_post);
    }
}
Example #12
0
 function testGetPostPreview()
 {
     $editor_user_id = $this->factory->user->create(array('role' => 'editor'));
     wp_set_current_user($editor_user_id);
     $post_id = $this->factory->post->create(array('post_author' => $editor_user_id));
     _wp_put_post_revision(array('ID' => $post_id, 'post_content' => 'New Stuff Goes here'), true);
     $_GET['preview'] = true;
     $_GET['preview_id'] = $post_id;
     $the_post = Timber::get_post($post_id);
     $this->assertEquals('New Stuff Goes here', $the_post->post_content);
 }
/**
 * Saves an already existing post as a post revision.
 *
 * Typically used immediately after post updates.
 * Adds a copy of the current post as a revision, so latest revision always matches current post
 *
 * @since 2.6.0
 *
 * @uses _wp_put_post_revision()
 *
 * @param int $post_id The ID of the post to save as a revision.
 * @return mixed Null or 0 if error, new revision ID, if success.
 */
function wp_save_post_revision($post_id)
{
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (!($post = get_post($post_id))) {
        return;
    }
    if (!post_type_supports($post->post_type, 'revisions')) {
        return;
    }
    if ('auto-draft' == $post->post_status) {
        return;
    }
    if (!wp_revisions_enabled($post)) {
        return;
    }
    // Compare the proposed update with the last stored revision verifying that
    // they are different, unless a plugin tells us to always save regardless.
    // If no previous revisions, save one
    if ($revisions = wp_get_post_revisions($post_id)) {
        // grab the last revision, but not an autosave
        foreach ($revisions as $revision) {
            if (false !== strpos($revision->post_name, "{$revision->post_parent}-revision")) {
                $last_revision = $revision;
                break;
            }
        }
        if (isset($last_revision) && apply_filters('wp_save_post_revision_check_for_changes', true, $last_revision, $post)) {
            $post_has_changed = false;
            foreach (array_keys(_wp_post_revision_fields()) as $field) {
                if (normalize_whitespace($post->{$field}) != normalize_whitespace($last_revision->{$field})) {
                    $post_has_changed = true;
                    break;
                }
            }
            // Check whether revisioned meta fields have changed.
            foreach (_wp_post_revision_meta_keys() as $meta_key) {
                if (get_post_meta($post->ID, $meta_key, true) != get_post_meta($last_revision->ID, $meta_key, true)) {
                    $post_has_changed = true;
                    break;
                }
            }
            // Check whether the post format has changed
            if (get_post_format($post->ID) != get_post_meta($last_revision->ID, '_revision_post_format', true)) {
                $post_has_changed = true;
            }
            //don't save revision if post unchanged
            if (!$post_has_changed) {
                return;
            }
        }
    }
    $return = _wp_put_post_revision($post);
    $revisions_to_keep = wp_revisions_to_keep($post);
    if ($revisions_to_keep < 0) {
        return $return;
    }
    // all revisions and autosaves
    $revisions = wp_get_post_revisions($post_id, array('order' => 'ASC'));
    $delete = count($revisions) - $revisions_to_keep;
    if ($delete < 1) {
        return $return;
    }
    $revisions = array_slice($revisions, 0, $delete);
    for ($i = 0; isset($revisions[$i]); $i++) {
        if (false !== strpos($revisions[$i]->post_name, 'autosave')) {
            continue;
        }
        wp_delete_post_revision($revisions[$i]->ID);
    }
    return $return;
}
Example #14
0
/**
 * Creates autosave data for the specified post from $_POST data.
 *
 * @package WordPress
 * @subpackage Post_Revisions
 * @since 2.6.0
 *
 * @uses _wp_translate_postdata()
 * @uses _wp_post_revision_fields()
 *
 * @return unknown
 */
function wp_create_post_autosave($post_id)
{
    $translated = _wp_translate_postdata(true);
    if (is_wp_error($translated)) {
        return $translated;
    }
    $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['ID'] = $old_autosave->ID;
        $new_autosave['post_author'] = $post_author;
        // Auto-save revisioned meta fields.
        foreach (_wp_post_revision_meta_keys() as $meta_key) {
            if (isset($_POST[$meta_key]) && get_post_meta($new_autosave['ID'], $meta_key, true) != $_POST[$meta_key]) {
                // Use the underlying delete_metadata and add_metadata vs delete_post_meta
                // and add_post_meta to make sure we're working with the actual revision meta.
                delete_metadata('post', $new_autosave['ID'], $meta_key);
                if (!empty($_POST[$meta_key])) {
                    add_metadata('post', $new_autosave['ID'], $meta_key, $_POST[$meta_key]);
                }
            }
        }
        // Save the post format if different
        if (isset($_POST['post_format']) && get_post_meta($new_autosave['ID'], '_revision_post_format', true) != $_POST['post_format']) {
            delete_metadata('post', $new_autosave['ID'], '_revision_post_format');
            if (!empty($_POST['post_format'])) {
                add_metadata('post', $new_autosave['ID'], '_revision_post_format', $_POST['post_format']);
            }
        }
        return wp_update_post($new_autosave);
    }
    // _wp_put_post_revision() expects unescaped.
    $_POST = wp_unslash($_POST);
    // Otherwise create the new autosave as a special post revision
    return _wp_put_post_revision($_POST, true);
}