WordPress.org

Make WordPress Core

Opened 6 years ago

Closed 6 years ago

Last modified 5 years ago

#6775 closed enhancement (fixed)

Post Revisions

Reported by: mdawaffe Owned by: mdawaffe
Milestone: 2.6 Priority: normal
Severity: normal Version: 2.5.1
Component: General Keywords: revision needs-testing has-patch blessed
Focuses: Cc:

Description

Overview

Attached is a first pass at adding basic versioning/revisioning to WordPress.

What it does:

  1. Saves a copy of a post every time you edit it.
  2. Allows you to view (not edit) each of those copies (revisions).
  3. Shows diffs between any two revisions. Forward (in time) diffs only.

What it doesn't do:

  1. You cannot have a live-revision and a working revision to be pushed live later. I'm not sure if that feature would be useful to our core audience or not. At any rate, it's a little tricky to get working correctly.

How it works

Posts are copied into a new row in the posts table on the pre_post_update hook. Only certain (configurable by plugin) fields are saved (title, content, author, excerpt). The rest are either used internally by WP somewhere or I felt weren't useful to save.

Posts can be restored from an older revision either in full or field by field (not chunk by chunk).

The Diff engine is an extension of the PEAR Text_Diff package (which I believe to be the descendent of the MediaWiki Diff engine). The generation of the diff output is fully pluggable via the new wp_text_diff() pluggable function.

The provided function shows diffs "side by side" and with both line and word highlighting (trac style). The old content is on the left, and the new content is on the right. This presentation allows you to ignore all the color highlighting and plusses and minuses and just read either side from top to bottom to see what the post looked like in that revision.

Functions provided:

  • wp_text_diff( $left_string, $right_string, $args = null )
  • wp_save_revision( $post_id )
  • wp_get_revision(&$post, $output = OBJECT, $filter = 'raw')
  • wp_restore_revision( $revision_id, $fields = null )
  • wp_delete_revision( $revision_id )
  • wp_get_post_revisions( $post_id = 0 )
  • wp_list_post_revisions( $post_id = 0, $args = null )

TODO

  1. Open up revisions for pages as well. That's where they'll be most useful.
  2. Rework Autosave to store its data as a special post revision. Then we'll be able to autosave *all* posts/pages (not just drafts) and have recovery messages like "WordPress found an autosaved copy of this post that's more recent than your version, would you like to see it?"
  3. Review caps/permissions. Do we need any new ones like current_user_can( 'view_revision', $id )?
  4. Display revisions and/or diffs in front end?
  5. Decide how many revisions to store for each post. Right now it stores an arbitrary number. Should it be capped?

Prior work and idea sources

  1. http://wordpress.org/extend/plugins/post-revisions/ (me)
  2. http://wordpress.org/extend/plugins/blicki/ (Ryan)
  3. http://comox.textdrive.com/pipermail/wp-hackers/2008-March/018689.html (Paul Menard)

Committer:

svn add wp-includes/Text
svn add wp-incledes/wp-diff.php
svn add wp-admin/revision.php

Attachments (8)

6775.diff (91.2 KB) - added by mdawaffe 6 years ago.
6775.2.diff (34.4 KB) - added by mdawaffe 6 years ago.
Autosave
6775.3.diff (5.0 KB) - added by mdawaffe 6 years ago.
Pages
6775.4.diff (1.9 KB) - added by mdawaffe 6 years ago.
cap tweaks (independent of 6775.3.diff)
6775.5.diff (2.3 KB) - added by mdawaffe 6 years ago.
delete deleted post's revisions, constant for turning off revisions
6775.6.diff (2.0 KB) - added by mdawaffe 6 years ago.
6775.7.diff (20.1 KB) - added by mdawaffe 6 years ago.
6775.8.diff (3.2 KB) - added by mdawaffe 6 years ago.
validation

Download all attachments as: .zip

Change History (52)

mdawaffe6 years ago

comment:1 mdawaffe6 years ago

Right now, because of autosave, the attached will save a "blank" revision. Just ignore it, we'll work out the kinks when we port autosave.

comment:2 mdawaffe6 years ago

More TODO:

  1. See if get_last*modified() need any adjusting.

comment:3 ryan6 years ago

(In [7747]) Post revisions from mdawaffe. see #6775

comment:4 Viper007Bond6 years ago

Wow, that's one big patch!

Nitpick: why is "Text" capitalized?

comment:5 follow-ups: DD326 years ago

Nitpick: why is "Text" capitalized?

Because thats the naming proceedure which the package uses, (Which looks to be Horde)

require_once 'Text/Diff/Renderer.php';

Is that going to be an issue on systems which do not have the wp-includes directory in the include search path?

comment:6 in reply to: ↑ 5 Viper007Bond6 years ago

Replying to DD32:

Because thats the naming proceedure which the package uses,

Gotcha.

comment:7 in reply to: ↑ 5 mdawaffe6 years ago

require_once 'Text/Diff/Renderer.php';

Is that going to be an issue on systems which do not have the wp-includes directory in the include search path?

There's an ini_set() in wp_text_diff(): http://trac.wordpress.org/browser/trunk/wp-includes/pluggable.php?rev=7747#L1377 and later an ini_restore().

I don't know if that will work on all systems, but I wanted to try it first rather than modifying the code. (Though I've already modified it in the sense that I've left out about half of the package.)

comment:8 in reply to: ↑ description Dickie6 years ago

Replying to mdawaffe:

Overview

What it doesn't do:

  1. You cannot have a live-revision and a working revision to be pushed live later. I'm not sure if that feature would be useful to our core audience or not. At any rate, it's a little tricky to get working correctly.

That's a real shame, as that is something that I personally would find really handy, as I generally use WP as a CMS not a blog and to be able to make modifications to a post without actually committing them yet would be great... (The history side of things is useful but less important to me).
I would also like to be able to change multiple pages all at once, and then commit them all with one deft stroke of the mouse ;)
But that's just my £0.02

comment:9 follow-up: neoen6 years ago

Will be possible to turn off post revisions and use only current autosave?

comment:10 matt6 years ago

  • Keywords blessed added

comment:11 markjaquith6 years ago

(In [7817]) Fix typo in wp_save_revision(). props Andy. see #6775

comment:12 in reply to: ↑ 9 mdawaffe6 years ago

Replying to neoen:

Will be possible to turn off post revisions and use only current autosave?

No - Autosave will use the new revisions system. There may be a (hidden) option to limit how many revisions WP should keep for any given post. If we do that, then setting it to 0 would mean "do autosaves, but don't keep post revisions".

comment:13 mdawaffe6 years ago

  • Owner changed from anonymous to mdawaffe
  • Status changed from new to assigned

6775.2.diff

  1. Moves autosave to post revisions. For drafts, autosave overwrites the post (this is the same as the old behavior). For non-drafts, a special post revision is inserted into the posts table.

Only one autosave is stored per post.

The philosophy here is that a new post revision is created every time the user clicks one of the save buttons, but not for each autosave.

  1. Turns on autosave for all posts.
  2. Displays warning when a user edits a post for which there is an autosave more recent than the post itself.
  3. Consolidates code from edit_post() and wp_write_post().
  4. Refactors wp-admin/revision.php into switch( $action ) : like our other "object" pages.

Still TODO:

  1. Open up revisions for pages as well. It's mostly there, but probably needs some tweaks. Pages might be a bit broken right now, in fact.
  2. Review caps/permissions. Do we need any new ones like current_user_can( 'view_revision', $id )?
  3. Display revisions and/or diffs in front end?
  4. Decide how many revisions to store for each post. Right now it stores an arbitrary number. Should it be capped?
  5. See if get_last*modified() need any adjusting.

New functions:

wp_get_autosave( $post_id );
wp_create_autosave();
_wp_translate_postdata(); // Rename $_POST data from form names to DB post columns

mdawaffe6 years ago

Autosave

comment:14 ryan6 years ago

Viewing diff results in infinite redirect. $redirect is "/trunk/wp-admin/revision.php?action=diff&right=59&left=58" every time.

comment:15 ryan6 years ago

Found it. Small typo in the code that checks for reversed diffs.

comment:16 ryan6 years ago

(In [7907]) Move autosave to post revisions. Props mdawaffe. see #6775

comment:17 mdawaffe6 years ago

6775.3.diff

  1. Turn on revisions for pages.

mdawaffe6 years ago

Pages

comment:18 mdawaffe6 years ago

Ryan feels that current caps for edit_post, read_post, etc are all fine to use with revisions as well. I'll look over the cap code to see if we should check caps against the post_parent if 'inherit' == post_status.

comment:19 mdawaffe6 years ago

get_last*modified() are fine.

comment:20 mdawaffe6 years ago

6775.4.diff (independent of .3.diff)

  1. Tweak some caps.

mdawaffe6 years ago

cap tweaks (independent of 6775.3.diff)

comment:21 mdawaffe6 years ago

  • Keywords has-patch added

6775.diff (independent of .3.diff and .4.diff)

  1. Delete post revisions of deleted post.
  2. Turn off post revisions with WP_POST_REVISIONS constant in wp-config.php or during plugins_loaded action.

comment:22 mdawaffe6 years ago

All the above backend TODOs are now done with patches .3.diff, .4.diff and .5.diff.

We need to decide if we want to be able to display revisions and/or diffs blog-side.

The admin-side UI needs a general going over.

UI for deleting revisions?

mdawaffe6 years ago

delete deleted post's revisions, constant for turning off revisions

comment:23 ryan6 years ago

(In [7913]) Revisioning for pages from mdawaffe. see #6775

comment:24 ionfish6 years ago

Using revisions seems to break the saving of tag associations. Currently looking into it.

comment:25 ionfish6 years ago

Seems to be fine on a fresh install. Probably just something screwy in my database.

comment:26 Viper007Bond6 years ago

I'm having issues with the revisions being attributed to the wrong user.

comment:27 DD326 years ago

I'm having issues with the revisions being attributed to the wrong user.

I think that may be due to a bug in #6964, Could you give the changes from my patch on that ticket to wp-admin/edit-form-advanced.php a try?

comment:28 Viper007Bond6 years ago

Yeah, that fixes it.

comment:29 mdawaffe6 years ago

6775.6.diff

  1. Allow get_posts() args to be passed to wp_get_post_revisions().
  2. WP_POST_REVISIONS can be
    • true (default), -1: Save all revisions.
    • false, 0: Save no revisions. Only do autosave.
    • (int) > 0: Only save that # of revisions + 1 autosave. Older revisions are deleted.

mdawaffe6 years ago

comment:30 ryan6 years ago

(In [7987]) Allow defining the number of revisions to save. Props mdawaffe. see #6775

comment:31 mdawaffe6 years ago

I don't think core needs to have any bulit in functionality for displaying revisions/diffs on the front end. Themers/Pluginers can address that with rewrite endpoints, and the current revisions API.

comment:32 mdawaffe6 years ago

6775.7.diff

  1. Consistency in function names: rename from *_revision* to *_post_revision*.
  2. If WP_POST_REVISIONS is set to false, allow autosaves to be viewed, diffed, restored via revisions UI. Do not allow similar for other revisions.
  3. New convenience functions: wp_is_post_revision(), wp_is_post_autosave().

mdawaffe6 years ago

comment:33 ryan6 years ago

(In [8011]) Post revisions API cleanup from mdawaffe. see #6775

comment:34 mdawaffe6 years ago

6775.8.diff

Validation errors.

mdawaffe6 years ago

validation

comment:35 ryan6 years ago

(In [8012]) Validation fixes for post revisions. Props mdawaffe. see #6775

comment:36 follow-up: johnhennmacc6 years ago

Are there plans to allow a user to delete revisions through the administration screens? Another idea would be to delete revisions when a post gets published. It's very easy to build up revisions if you save every few minutes and that adds to the size of your database. Going in and doing deletions from database tables is all very fine but clearing up things through a UI is much more convenient. I am curious as your thoughts on this. Otherwise, I can see post revisions being very useful things to have.

comment:37 in reply to: ↑ 36 Viper007Bond6 years ago

Replying to johnhennmacc:

It's very easy to build up revisions if you save every few minutes and that adds to the size of your database.

Why are you saving every few minutes? Autosave does it for you every 60 seconds and only uses one post revision.

comment:38 ryan6 years ago

(In [8175]) don't show autosave message if post and autosave are 'identical'. Props mdawaffe. see #6775

comment:39 ryan6 years ago

(In [8176]) better handling of comparing a revision to itself. Props mdawaffe. see #6775

comment:40 ryan6 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

comment:41 follow-up: rawalex6 years ago

Can there be something added in settings to allow blog owners to decide if they want to save revisions or not? Not everyone needs this functionality or wants to increase the size of the data files to accommodate it.

comment:42 rawalex6 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:43 in reply to: ↑ 41 westi6 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

Replying to rawalex:

Can there be something added in settings to allow blog owners to decide if they want to save revisions or not? Not everyone needs this functionality or wants to increase the size of the data files to accommodate it.

Firstly please don't re-open enhancement tickets when the feature has been released.

Secondly, you can disable the post revision code with a define in your wp-config.php file by adding define('WP_POST_REVISIONS','0');.

comment:44 Viper007Bond6 years ago

westi types faster than me, but here's my reply anyway:

1) For future reference, please open your own ticket rather opening up a resolved ticket.

2) Such a feature already exists via the WP_POST_REVISIONS constant (see mdawaffe's above comment). Please try searching first next time too.

3) Like all user content, revisions are stored in your database, not files.

Note: See TracTickets for help on using tickets.