Item10311: Restore topic fails to restore META preferences

Priority: Urgent
Current State: Closed
Released In: 1.1.3
Target Release: patch
Applies To: Engine
Component: Manage
Reported By: GeorgeClark
Waiting For:
Last Change By: KennethLavrsen
See also Item10304. The current Restore process only recovers the topic text from an older revision. The chosen revision's text is passed to the editor to be saved as a new revision. However no other topic metadata is recovered. This is particularly severe in the case of the new Group UI, as there is now no easy way to recover a change to a group.

There are several potential fixes - discussed on IRC

  1. Add a "restoremeta=rev" parameter to the edit URL which will copy the META information from an older Rev upon save
  2. Change the editor to a "reprev" type view, showing and saving all topic data and metadata in the edit window.
  3. Implement a new restore process as a single-step operation, restoring the text and meta without passing through edit.
  4. Find a "meld" type javascript editor to do a diff / save of the two versions.

This is probably deserving of a feature request but it is also an urgent issue given the impact on Group topics.

For a short term solution, option 3 - either a new restore, or a checkbox to "restore meta" bypassing the edit might be preferable. Biggest issue would be Attachments. Do we ignore attachments, or do an intelligent merge of the attachment metadata, restoring only the manually set information - hidden and comment fields . -- GeorgeClark - 01 Feb 2011

There is meta and there is meta

In my view restoring to an older revision should always restore
  • All form fields
  • All preferences

But probably not

  • attachment data. If you renamed or added or removed an attachment braindead restore of meta will goof up the relationship between actual attachment file and the meta
  • the topic info meta needs to be saved so it fits the new revision that is created
  • Plugin specific meta. We need to look at some of the plugins that store meta. Will they all work if we revert their meta. E.g. RevCommentsPlugin. The new revision which is a copy of the older revision should not have the old meta loaded. In fact you need to be able to enter a new comment.

My immediate reaction is that the restore to earlier version should restore form and preference meta only

-- KennethLavrsen - 01 Feb 2011

MetaCommentPlugin and SemanticLinksPlugin, Workflow plugins register custom META:types; in these cases, the meta should be restored.

I suspect that RevCommentsPlugin is the only one that doesn't want to be restored.

I am hopeful there's a way to accommodate this plugin though - it's (hopefully) "just" a matter of restoring the meta "early" and then letting RevCommentsPlugin override the "new" "Restored v12" comment.

-- PaulHarvey - 01 Feb 2011

I wonder if we could extend the VALIDATE hash for metadata to include a "norevert" or similar attribute so that when Meta is registered, it can specify whether or not it can be safely reverted.

-- GeorgeClark - 02 Feb 2011

I'm struggling to think of why you'd want to do that. Revert should revert. If RevCommentPlugin uses an beforeSaveHandler to do its work, I'm not even sure we have a problem. But maybe I'm being naive smile

-- PaulHarvey - 02 Feb 2011

As for the attachments meta; this wouldn't be a problem if we re-built the meta on every topic save. But then that would only make 90% of users happy.

Let's not complicate this task by trying to fix the attachments meta situation; that's another hairy ball of string that needs its own careful thought.

-- PaulHarvey - 02 Feb 2011

If RevCommentsPlugin is the only plugin with a problem then I will say

  • Minor problem in the first place. It is not the end of the world if a comment or two are removed. They are still available if you view an earlier version of the topic. Audit trail is still there.
  • We can fix the problem - if there is a problem - in the plugin

I would say that we should conclude that restoring an earlier version using the UI should create a new revision of of the topic that contains both the old text and old meta

Except the attachment meta. We have to keep the attachment meta valid. If someone deleted a file, added a file or renamed a file we must keep the attachment meta valid. If they get out of sync the end user cannot correct it. Even the admin has to hack the .txt file or add or remove or move the attachment at filesystem level.

I would not try to intelligently figure out what the attachment were in the old rev. I would simply let the restore code load the entire new revision and then remove all the attachment meta and add the attachment meta from the current version. That will keep the meta valid.

-- KennethLavrsen - 02 Feb 2011

I have a small patch to that restores the topic. It eliminates the edit, which means that users expecting to "take a look" and possibly cancel the restore will have a bad surprise. Options:
  • Add a checkbox to optionally restore metadata (too geeky?)
  • Add a warning - option to revew/cancel is eliminated .. maybe with a checkbox that say "Yes I understand the topic will be restored without confirmation.
  • Add a hidden url param to save to cause save to copy in old metadata.

(The below code probably isn't the best solution. By referencing the topicObject as a hash, it's violating the object API. It would probably be better to move the restore logic into Foskik::Meta->restoreRev( $rev ).

diff --git a/core/lib/Foswiki/UI/ b/core/lib/Foswiki/UI/
index 8906279..606dc65 100644
--- a/core/lib/Foswiki/UI/
+++ b/core/lib/Foswiki/UI/
@@ -462,6 +462,7 @@ sub _parsePreferenceValue {
 sub _action_restoreRevision {
     my ($session) = @_;
+    my $query     = $session->{request};
     my ( $web, $topic ) =
       $session->normalizeWebTopicName( $session->{webName},
         $session->{topicName} );
@@ -469,9 +470,35 @@ sub _action_restoreRevision {
     # read the current topic
     my $meta = Foswiki::Meta->load( $session, $web, $topic );
+    # read the old topic
+    my $rev = $query->param('rev');
+    my $oldmeta = Foswiki::Meta->load( $session, $web, $topic, $rev );
+    foreach my $k (sort keys %$meta ) {
+        next if $k =~ m/^_/;
+        next if $k eq 'TOPICINFO';          # Don't revert topicinfo
+        next if $k eq 'FILEATTACHMENT';     # Don't revert attachments
+        $meta->remove($k)  unless $oldmeta->{$k};
+        }
+    foreach my $k (sort keys %$oldmeta ) {
+        next if $k =~ m/^_/;
+        next if $k eq 'TOPICINFO';          # Don't revert topicinfo
+        next if $k eq 'FILEATTACHMENT';     # Don't revert attachments
+        $meta->copyFrom( $oldmeta, $k );
+        }
+    $meta->text($oldmeta->text());          # copy the old text
+    $meta->save(( forcenewrevision => 1 ) );
-    require Foswiki::UI::Edit;
-    Foswiki::UI::Edit::edit($session);
+    my $viewURL = $session->getScriptUrl( 0, 'view', $web, $topic );
+    $session->redirect( $session->redirectto($viewURL) );
+    #require Foswiki::UI::Edit;
+    #Foswiki::UI::Edit::edit($session);

-- GeorgeClark - 21 Feb 2011

Committed the fix with additional validations. Note that there is a new message in messages.tmpl, and some added strings in more.tmpl that will need translation.

-- GeorgeClark - 22 Feb 2011

This needs better wording on the More screen. Instead of CAUTION: Restore no longer proceeds to edit with an option to cancel! If you click the [Restore...] button, the topic will be immediately restored to the requested revision

something that does not scare the shit out of the user.


Restore topic

INFO Restore will create an exact copy from your selected revision. And because each copy will be preserved in the topic history, you can always revisit the revision you are replacing.

Restore topic to revision [ n]

[Restore button]

Note: copy changes and additions also need to get translated.

-- ArthurClemens - 06 Mar 2011

Topic revision: r22 - 16 Apr 2011, KennethLavrsen
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy