Revamped page deletion interface; fixed bug where page_meta cache was not being cleared upon restoration of deleted page.
authorDan
Sun, 17 Aug 2008 23:24:41 -0400
changeset 696 bd5069e1f19a
parent 695 6bd7215c718b
child 698 40f9528b6348
child 699 c7d737202d59
Revamped page deletion interface; fixed bug where page_meta cache was not being cleared upon restoration of deleted page.
includes/clientside/static/ajax.js
includes/pageprocess.php
includes/pageutils.php
includes/paths.php
language/english/core.json
--- a/includes/clientside/static/ajax.js	Sun Aug 17 23:24:18 2008 -0400
+++ b/includes/clientside/static/ajax.js	Sun Aug 17 23:24:41 2008 -0400
@@ -222,24 +222,194 @@
   if ( KILL_SWITCH )
     return true;
   load_component('l10n');
-  var reason = prompt($lang.get('ajax_delete_prompt_reason'));
-  if ( !reason || reason == '' )
+  load_component('messagebox');
+  load_component('SpryEffects');
+  
+  // stage 1: prompt for reason and confirmation
+  miniPrompt(function(parent)
+    {
+      // heading/title
+      var h3 = document.createElement('h3');
+      h3.appendChild(document.createTextNode($lang.get('ajax_delete_header')));
+      parent.appendChild(h3);
+      
+      // "please enter your reason"
+      var p1 = document.createElement('p');
+      p1.appendChild(document.createTextNode($lang.get('ajax_delete_prompt_reason')));
+      parent.appendChild(p1);
+      
+      // textbox + label thereof
+      var p2 = document.createElement('p');
+      var tb = document.createElement('input');
+      var dl = document.createElement('label');
+      
+      tb.type = 'text';
+      tb.size = '30';
+      tb.onkeyup = function(e)
+      {
+        if ( e )
+        if ( e.keyCode )
+        if ( e.keyCode == 13 )
+        {
+          if ( ajaxDeletePageSubmit(this) )
+          {
+            miniPromptDestroy(this);
+          }
+        }
+        else if ( e.keyCode == 27 )
+        {
+          miniPromptDestroy(this);
+        }
+      }
+      
+      dl.appendChild(document.createTextNode($lang.get('ajax_delete_lbl_reason') + ' '));
+      dl.appendChild(tb);
+      p2.appendChild(dl);
+      parent.appendChild(p2);
+      
+      // notice underneath
+      var p3 = document.createElement('p');
+      p3.style.fontSize = 'smaller';
+      p3.appendChild(document.createTextNode($lang.get('ajax_delete_msg_confirm')));
+      parent.appendChild(p3);
+      
+      // confirmation + submit/cancel (structure)
+      var divleft  = document.createElement('div');
+      var divright = document.createElement('div');
+      var divclear = document.createElement('div');
+      
+      divleft.style.cssFloat = 'left';
+      divleft.style.styleFloat = 'left';
+      
+      divright.style.cssFloat = 'right';
+      divright.style.styleFloat = 'right';
+      
+      divclear.style.clear = 'both';
+      
+      parent.appendChild(divleft);
+      parent.appendChild(divright);
+      parent.appendChild(divclear);
+      
+      // confirmation + submit/cancel (controls)
+      var cb = document.createElement('input');
+      var cl = document.createElement('label');
+      
+      cb.type = 'checkbox';
+      cb.checked = false;
+      
+      // a bit of a hack here, doesn't seem to work in fx3
+      cb.onblur = function(e)
+      {
+        var parent = this.parentNode.parentNode.parentNode;
+        var submitter = parent.getElementsByTagName('a')[0];
+        if ( submitter )
+          submitter.focus();
+      }
+      
+      cl.appendChild(cb);
+      cl.appendChild(document.createTextNode(' ' + $lang.get('ajax_delete_lbl_confirm')));
+      divleft.appendChild(cl);
+      
+      var btn_submit = document.createElement('a');
+      btn_submit.className = 'abutton abutton_red';
+      btn_submit.href = '#';
+      btn_submit.appendChild(document.createTextNode($lang.get('ajax_delete_btn_delete')));
+      btn_submit.onclick = function()
+      {
+        if ( ajaxDeletePageSubmit(this) )
+        {
+          miniPromptDestroy(this);
+        }
+        return false;
+      }
+      
+      var btn_cancel = document.createElement('a');
+      btn_cancel.className = 'abutton';
+      btn_cancel.href = '#';
+      btn_cancel.appendChild(document.createTextNode($lang.get('etc_cancel')));
+      btn_cancel.onclick = function()
+      {
+        miniPromptDestroy(this);
+        return false;
+      }
+      
+      divright.appendChild(btn_submit);
+      divright.appendChild(document.createTextNode(' '));
+      divright.appendChild(btn_cancel);
+      
+      var timeout = ( aclDisableTransitionFX ) ? 10 : 1000;
+      setTimeout(function()
+        {
+          tb.focus();
+        }, timeout);
+    });
+}
+
+window.ajaxDeletePageSubmit = function(prompt_obj)
+{
+  prompt_obj = miniPromptGetParent(prompt_obj).childNodes[1];
+  var inputs = prompt_obj.getElementsByTagName('input');
+  var reason = inputs[0];
+  var confirm = inputs[1];
+  
+  if ( trim(reason.value) == '' )
   {
+    // flash the background of the reason entry
+    if ( !reason.sfx )
+      reason.sfx = new Spry.Effect.Highlight(reason.parentNode);
+    
+    reason.sfx.start();
     return false;
   }
-  c = confirm($lang.get('ajax_delete_confirm'));
-  if(!c)
+  
+  if ( !confirm.checked )
   {
-    return;
+    // flash the background of the confirm checkbox
+    if ( !confirm.sfx )
+      confirm.sfx = new Spry.Effect.Highlight(confirm.parentNode);
+    
+    confirm.sfx.start();
+    return false;
   }
+  
+  prompt_obj.innerHTML = '<img alt="loading" style="display: block; margin: 0 auto;" src="' + cdnPath + '/images/loading-big.gif" />';
+  
+  // tenemos la confirmación y la razón - borre la página.
   setAjaxLoading();
-  ajaxPost(stdAjaxPrefix+'&_mode=deletepage', 'reason=' + ajaxEscape(reason), function() {
-    if ( ajax.readyState == 4 && ajax.status == 200 ) {
-      unsetAjaxLoading();
-      alert(ajax.responseText);
-      window.location.reload();                                                                           
-    }
-  });
+  ajaxPost(stdAjaxPrefix + '&_mode=deletepage', 'reason=' + ajaxEscape(trim(reason.value)), function()
+    {
+      if ( ajax.readyState == 4 && ajax.status == 200 )
+      {
+        unsetAjaxLoading();
+        
+        // show the response in the same prompt window
+        prompt_obj.style.textAlign = 'center';
+        prompt_obj.innerHTML = '';
+        
+        var p1 = document.createElement('div');
+        p1.style.marginBottom = '15px';
+        p1.appendChild(document.createTextNode(ajax.responseText));
+        prompt_obj.appendChild(p1);
+        
+        var p2 = document.createElement('p');
+        var a = document.createElement('a');
+        a.className = 'abutton';
+        a.href = '#';
+        a.appendChild(document.createTextNode($lang.get('etc_close')));
+        a.onclick = function()
+        {
+          miniPromptDestroy(this);
+          window.location.reload();
+          return false;
+        }
+        p2.appendChild(a);
+        prompt_obj.appendChild(a);
+        
+        a.focus();
+      }
+    });
+  
+  return true;
 }
 
 window.ajaxDelVote = function()
--- a/includes/pageprocess.php	Sun Aug 17 23:24:18 2008 -0400
+++ b/includes/pageprocess.php	Sun Aug 17 23:24:41 2008 -0400
@@ -640,6 +640,7 @@
   function rollback_log_entry($log_id)
   {
     global $db, $session, $paths, $template, $plugins; // Common objects
+    global $cache;
     
     // Verify permissions
     if ( !$this->perms->get_permissions('history_rollback') )
@@ -698,6 +699,8 @@
         
         // FIXME: l10n
         // rollback_extra is required because usually only moderators can undo page deletion AND restore the content.
+        // potential flaw here - once recreated, can past revisions be restored by users without rollback_extra? should
+        // probably modify editor routine to deny revert access if the timestamp < timestamp of last deletion if any.
         if ( !$this->perms->get_permissions('history_rollback_extra') )
           return 'Administrative privileges are required for page undeletion.';
         
@@ -738,6 +741,8 @@
         if ( !$e )
           $db->die_json();
         
+        $cache->purge('page_meta');
+        
         return array(
             'success' => true,
             'dateline' => $dateline,
--- a/includes/pageutils.php	Sun Aug 17 23:24:18 2008 -0400
+++ b/includes/pageutils.php	Sun Aug 17 23:24:41 2008 -0400
@@ -1162,6 +1162,8 @@
   {
     global $db, $session, $paths, $template, $plugins; // Common objects
     global $lang;
+    global $cache;
+    
     if ( !$session->get_permissions('vote_delete') )
     {
       return $lang->get('etc_access_denied');
@@ -1214,6 +1216,11 @@
     
     $q = 'UPDATE ' . table_prefix.'pages SET delvotes=' . $cv . ',delvote_ips=\'' . $ips . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\'';
     $w = $db->sql_query($q);
+    if ( !$w )
+      $db->_die();
+    
+    // all done, flush page cache to mark it up
+    $cache->purge('page_meta');
     
     return $lang->get('ajax_delvote_success');
   }
@@ -1229,15 +1236,21 @@
   {
     global $db, $session, $paths, $template, $plugins; // Common objects
     global $lang;
+    global $cache;
+    
     if(!$session->get_permissions('vote_reset'))
     {
       return $lang->get('etc_access_denied');
     }
     $q = 'UPDATE ' . table_prefix.'pages SET delvotes=0,delvote_ips=\'' . $db->escape(serialize(array('ip'=>array(),'u'=>array()))) . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\'';
     $e = $db->sql_query($q);
-    if(!$e) $db->_die('The number of delete votes was not reset.');
+    if ( !$e )
+    {
+      $db->_die('The number of delete votes was not reset.');
+    }
     else
     {
+      $cache->purge('page_meta');
       return $lang->get('ajax_delvote_reset_success');
     }
   }
--- a/includes/paths.php	Sun Aug 17 23:24:18 2008 -0400
+++ b/includes/paths.php	Sun Aug 17 23:24:41 2008 -0400
@@ -803,6 +803,16 @@
     global $db, $session, $paths, $template, $plugins; // Common objects
     require_once(ENANO_ROOT . '/includes/search.php');
     
+    $progress = false;
+    if ( class_exists('ProgressBar') )
+    {
+      // CLI only.
+      $progress = new ProgressBar('Rebuilding search index: [', ']', 'Initializing...', 'green', 'blue', 'white', 'yellow');
+      $verbose = false;
+      $debug = false;
+      $progress->start();
+    }
+    
     @set_time_limit(0);
     
     $q = $db->sql_query('DELETE FROM ' . table_prefix . 'search_index;');
@@ -868,6 +878,11 @@
               echo ", mem = $mu...";
             flush();
           }
+          else if ( is_object($progress) )
+          {
+            $progress->update_text_quiet("$k/$num_pages {$row['namespace']}:{$row['page_id']}");
+            $progress->set($k, $num_pages);
+          }
           
           // skip this page if it's not supposed to be indexed
           if ( $row['visible'] == 0 )
@@ -943,6 +958,11 @@
         echo '<br />';
       echo "\n";
     }
+    else if ( is_object($progress) )
+    {
+      $progress->update_text('Complete.');
+      $progress->end();
+    }
     return true;
   }
   
--- a/language/english/core.json	Sun Aug 17 23:24:18 2008 -0400
+++ b/language/english/core.json	Sun Aug 17 23:24:41 2008 -0400
@@ -438,8 +438,12 @@
       rename_prompt: 'What title should this page be renamed to?\n%this.ajax_rename_notice%',
       rename_prompt_short: 'Enter a new name for this page',
       rename_notice: 'This won\'t change the URL to this page. To change the URL to this page, use Page Manager in the administration panel.',
-      delete_prompt_reason: 'Please enter your reason for deleting this page.',
-      delete_confirm: 'You are about to REVERSIBLY delete this page. Do you REALLY want to do this?\n\n(Comments and categorization data, as well as any attached files, will be permanently lost)',
+      delete_header: 'Delete this page?',
+      delete_lbl_reason: 'Reason:',
+      delete_prompt_reason: 'Please enter your reason for deleting this page. This will be visible in the page history as well as on the deleted page.',
+      delete_msg_confirm: 'Deleting pages is reversible. Users with administrative access can restore the page, but not any comments, categorization data, tags, or files (if the page contains an uploaded file). If Wiki Mode is in effect globally, everyone can create this page again and see past revisions.',
+      delete_lbl_confirm: 'Yes, I\'m sure',
+      delete_btn_delete: 'Delete page',
       delvote_confirm_title: 'Vote to delete this page?',
       delvote_confirm_body: 'Administrators and moderators will see a notice on this page showing who voted.',
       delvote_btn_submit: 'Vote',
@@ -717,6 +721,7 @@
       // Message box buttons
       ok: 'OK',
       cancel: 'Cancel',
+      close: 'Close',
       yes: 'Yes',
       no: 'No',
       go: 'Go',