When changing namespace of a File: page, associated files are now deleted. Also fixed some issues with image scaling.
authorDan
Sat, 11 Apr 2009 22:32:45 -0400
changeset 898 c75754f5b1da
parent 897 f31c252c52c1
child 899 df88cedf0995
When changing namespace of a File: page, associated files are now deleted. Also fixed some issues with image scaling.
includes/functions.php
includes/pageutils.php
language/english/admin.json
plugins/SpecialAdmin.php
plugins/SpecialUpdownload.php
plugins/admin/PageManager.php
--- a/includes/functions.php	Sat Apr 11 16:58:32 2009 -0400
+++ b/includes/functions.php	Sat Apr 11 22:32:45 2009 -0400
@@ -3841,23 +3841,23 @@
   global $db, $session, $paths, $template, $plugins; // Common objects
   
   if ( !is_int($width) || !is_int($height) )
-    return false;
+    throw new Exception('Invalid height or width.');
   
   if ( !file_exists($in_file) )
-    return false;
+    throw new Exception('Input file does not exist');
   
-  $in_file = escapeshellarg($in_file);
-  $out_file = escapeshellarg($out_file);
+  $in_file_sh = escapeshellarg($in_file);
+  $out_file_sh = escapeshellarg($out_file);
   
   if ( file_exists($out_file) && !$unlink )
-    return false;
+    throw new Exception('Refusing to write output file as it already exists and $unlink was not specified.');
   else if ( file_exists($out_file) && $unlink )
     @unlink($out_file);
   if ( file_exists($out_file) )
     // couldn't unlink (delete) the output file
-    return false;
+    throw new Exception('Failed to delete existing output file.');
     
-  $file_ext = substr($in_file, ( strrpos($in_file, '.') + 1));
+  $file_ext = strtolower(substr($in_file, ( strrpos($in_file, '.') + 1)));
   switch($file_ext)
   {
     case 'png':
@@ -3874,7 +3874,7 @@
       $func = 'imagecreatefromxpm';
       break;
     default:
-      return false;
+      throw new Exception('Invalid extension of input file.');
   }
     
   $magick_path = getConfig('imagemagick_path');
@@ -3891,21 +3891,21 @@
     );
   if ( $can_use_magick )
   {
-    if ( !preg_match('/^([\/A-z0-9_-]+)$/', $magick_path) )
+    if ( !preg_match('/^([\/A-z0-9:\. _-]+)$/', $magick_path) )
     {
       die('SECURITY: ImageMagick path is screwy');
     }
-    $cmdline = "$magick_path \"$in_file\" -resize \"{$width}x{$height}>\" \"$out_file\"";
+    $cmdline = "$magick_path $in_file_sh -resize \"{$width}x{$height}>\" $out_file_sh";
     system($cmdline, $return);
     if ( !file_exists($out_file) )
-      return false;
+      throw new Exception('ImageMagick: did not produce output image file.');
     return true;
   }
   else if ( $can_use_gd )
   {
     @list($width_orig, $height_orig) = @getimagesize($in_file);
     if ( !$width_orig || !$height_orig )
-      return false;
+      throw new Exception('GD: Could not get height and width of input file.');
     // calculate new width and height
     
     $ratio = $width_orig / $height_orig;
@@ -3935,16 +3935,16 @@
     
     $newimage = @imagecreatetruecolor($new_width, $new_height);
     if ( !$newimage )
-      return false;
+      throw new Exception('GD: Request to create new truecolor image refused.');
     $oldimage = @$func($in_file);
     if ( !$oldimage )
-      return false;
+      throw new Exception('GD: Request to load input image file failed.');
     
     // Perform scaling
     imagecopyresampled($newimage, $oldimage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
     
     // Get output format
-    $out_ext = substr($out_file, ( strrpos($out_file, '.') + 1));
+    $out_ext = strtolower(substr($out_file, ( strrpos($out_file, '.') + 1)));
     switch($out_ext)
     {
       case 'png':
@@ -3963,7 +3963,7 @@
       default:
         imagedestroy($newimage);
         imagedestroy($oldimage);
-        return false;
+        throw new Exception('GD: Invalid extension of output file.');
     }
     
     // Write output
@@ -3984,7 +3984,8 @@
   }
   if ( file_exists($out_file) )
     return true;
-  return false;
+  
+  throw new Exception('Failed to find an appropriate method for scaling.');
 }
 
 /**
--- a/includes/pageutils.php	Sat Apr 11 16:58:32 2009 -0400
+++ b/includes/pageutils.php	Sat Apr 11 22:32:45 2009 -0400
@@ -1168,6 +1168,54 @@
   }
   
   /**
+   * Deletes files associated with a File page.
+   * @param string Page ID
+   */
+  
+  public static function delete_page_files($page_id)
+  {
+    global $db, $session, $paths, $template, $plugins; // Common objects
+    
+    $q = $db->sql_query('SELECT file_id, filename, file_key, time_id, file_extension FROM ' . table_prefix . "files WHERE page_id = '{$db->escape($page_id)}';");
+    if ( !$q )
+      $db->_die();
+    
+    while ( $row = $db->fetchrow() )
+    {
+      // wipe original file
+      foreach ( array(
+          ENANO_ROOT . "/files/{$row['file_key']}_{$row['time_id']}{$row['file_extension']}",
+          ENANO_ROOT . "/files/{$row['file_key']}{$row['file_extension']}"
+        ) as $orig_file )
+      {
+        if ( file_exists($orig_file) )
+          @unlink($orig_file);
+      }
+      
+      // wipe cached files
+      if ( $dr = @opendir(ENANO_ROOT . '/cache/') )
+      {
+        // lol404.jpg-1217958283-200x320.jpg
+        while ( $dh = @readdir($dr) )
+        {
+          $regexp = ':^' . preg_quote("{$row['filename']}-{$row['time_id']}-") . '[0-9]+x[0-9]+\.' . ltrim($row['file_extension'], '.') . '$:';
+          if ( preg_match($regexp, $dh) )
+          {
+            @unlink(ENANO_ROOT . "/cache/$dh");
+          }
+        }
+        @closedir($dr);
+      }
+    }
+    
+    $q = $db->sql_query('DELETE FROM ' . table_prefix . "files WHERE page_id = '{$db->escape($page_id)}';");
+    if ( !$q )
+      $db->die();
+    
+    return true;
+  }
+  
+  /**
    * Increments the deletion votes for a page by 1, and adds the current username/IP to the list of users that have voted for the page to prevent dual-voting
    * @param $page_id the page ID
    * @param $namespace the namespace
@@ -1586,14 +1634,16 @@
   {
     global $db, $session, $paths, $template, $plugins; // Common objects
     global $lang;
-    if(!$session->get_permissions('history_view'))
+    
+    if ( !$session->get_permissions('history_view') )
       return $lang->get('etc_access_denied');
+    
     if(!preg_match('#^([0-9]+)$#', (string)$id1) ||
        !preg_match('#^([0-9]+)$#', (string)$id2  )) return 'SQL injection attempt';
     // OK we made it through security
     // Safest way to make sure we don't end up with the revisions in wrong columns is to make 2 queries
-    if(!$q1 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id1 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.$db->get_error();
-    if(!$q2 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id2 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.$db->get_error();
+    if ( !$q1 = $db->sql_query('SELECT time_id,page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE log_id = ' . $id1 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: ' . $db->get_error();
+    if ( !$q2 = $db->sql_query('SELECT time_id,page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE log_id = ' . $id2 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: ' . $db->get_error();
     $row1 = $db->fetchrow($q1);
     $db->free_result($q1);
     $row2 = $db->fetchrow($q2);
@@ -1601,8 +1651,8 @@
     if(sizeof($row1) < 1 || sizeof($row2) < 2) return 'Couldn\'t find any rows that matched the query. The time ID probably doesn\'t exist in the logs table.';
     $text1 = $row1['page_text'];
     $text2 = $row2['page_text'];
-    $time1 = enano_date('F d, Y h:i a', $id1);
-    $time2 = enano_date('F d, Y h:i a', $id2);
+    $time1 = enano_date('F d, Y h:i a', $row1['time_id']);
+    $time2 = enano_date('F d, Y h:i a', $row2['time_id']);
     $_ob = "
     <p>" . $lang->get('history_lbl_comparingrevisions') . " {$time1} &rarr; {$time2}</p>
     ";
--- a/language/english/admin.json	Sat Apr 11 16:58:32 2009 -0400
+++ b/language/english/admin.json	Sat Apr 11 22:32:45 2009 -0400
@@ -529,6 +529,7 @@
       lbl_namespace: 'Namespace (URL prefix):',
       ns_article: '[No prefix, default Article namespace]',
       heading_advanced: 'Advanced options',
+      msg_file_ns_warning: '<b>WARNING:</b> Changing the namespace to something other than "File" will delete the uploaded file and all previous revisions of it.',
       lbl_enable_comments_title: 'Allow comments to be posted on this page?',
       lbl_enable_comments_hint: 'This option has no effect if comments are disabled globally in the administration panel. This option is enabled by default.',
       lbl_enable_comments: 'Enable comments on this page',
--- a/plugins/SpecialAdmin.php	Sat Apr 11 16:58:32 2009 -0400
+++ b/plugins/SpecialAdmin.php	Sat Apr 11 22:32:45 2009 -0400
@@ -2304,7 +2304,7 @@
         return false;
       }
       document.getElementById('ajaxPageContainer').innerHTML = '<div class="wait-box">Loading page...</div>';
-      ajaxGet('<?php echo scriptPath; ?>/ajax.php?title='+t+'&_mode=getpage&noheaders&auth=' + ENANO_SID, function() {
+      ajaxGet('<?php echo scriptPath; ?>/ajax.php?title='+t+'&_mode=getpage&noheaders&auth=' + ENANO_SID, function(ajax) {
           if ( ajax.readyState == 4 && ajax.status == 200 ) {
             var response = String(ajax.responseText + '');
             if ( check_json_response(response) )
--- a/plugins/SpecialUpdownload.php	Sat Apr 11 16:58:32 2009 -0400
+++ b/plugins/SpecialUpdownload.php	Sat Apr 11 22:32:45 2009 -0400
@@ -308,7 +308,9 @@
   {
     header('Content-disposition: attachment, filename="' . $filename . '";');
   }
-  header('Content-length: '.$len);
+  if ( !@$GLOBALS['do_gzip'] )
+    header('Content-length: ' . $len);
+  
   header('Last-Modified: '.enano_date('r', $row['time_id']));
   
   // using this method limits RAM consumption
--- a/plugins/admin/PageManager.php	Sat Apr 11 16:58:32 2009 -0400
+++ b/plugins/admin/PageManager.php	Sat Apr 11 22:32:45 2009 -0400
@@ -28,6 +28,8 @@
     return;
   }
   
+  require_once(ENANO_ROOT . '/includes/pageutils.php');
+  
   echo '<h3>' . $lang->get('acppm_heading_main') . '</h3>';
   $show_select = true;
   
@@ -160,7 +162,7 @@
             }
             
             // Field: namespace
-            $namespace = $_POST['page_namespace'];
+            $namespace_new = $_POST['page_namespace'];
             if ( !isset($paths->nslist[ $namespace ]) )
             {
               $errors[] = $lang->get('acppm_err_invalid_namespace');
@@ -168,7 +170,7 @@
             else
             {
               $namespace_changed = ( $_POST['page_namespace'] !== $dataset['namespace'] );
-              $dataset['namespace'] = $namespace;
+              $dataset['namespace'] = $namespace_new;
             }
             
             // Field: comments enabled
@@ -254,6 +256,12 @@
                       $db->_die('PageManager running slave update query after page ID/namespace change');
                   }
                   
+                  // If we're going File -> other, remove files
+                  if ( $namespace_db === 'File' )
+                  {
+                    PageUtils::delete_page_files($page_id);
+                  }
+                  
                   // update $paths with the new pathskey
                   $new_pathskey = $paths->nslist[$namespace_new] . $page_id_new;
                   $paths->pages[$new_pathskey] =& $paths->pages[$pathskey];
@@ -318,6 +326,10 @@
               <td class="row1">
                 <select name="page_namespace">
                 {NAMESPACE_LIST}</select>
+                <!-- BEGIN is_file -->
+                <br />
+                {lang:acppm_msg_file_ns_warning}
+                <!-- END is_file -->
               </td>
             </tr>
             
@@ -481,7 +493,8 @@
             'protected_semi'  => ( $dataset['protected'] == 2 ),
             'wikimode_off'    => ( $dataset['wiki_mode'] == 0 ),
             'wikimode_on'     => ( $dataset['wiki_mode'] == 1 ),
-            'wikimode_global' => ( $dataset['wiki_mode'] == 2 )
+            'wikimode_global' => ( $dataset['wiki_mode'] == 2 ),
+            'is_file'         => ( $dataset['namespace'] == 'File' )
           ));
         
         if ( isset($errors) )