# HG changeset patch # User Dan # Date 1239503565 14400 # Node ID c75754f5b1da1ad2f0e53548b3bc5c1bd05b4b52 # Parent f31c252c52c130aa76c1b03ba0834532781217c1 When changing namespace of a File: page, associated files are now deleted. Also fixed some issues with image scaling. diff -r f31c252c52c1 -r c75754f5b1da includes/functions.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.'); } /** diff -r f31c252c52c1 -r c75754f5b1da includes/pageutils.php --- 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 = "

" . $lang->get('history_lbl_comparingrevisions') . " {$time1} → {$time2}

"; diff -r f31c252c52c1 -r c75754f5b1da language/english/admin.json --- 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: 'WARNING: 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', diff -r f31c252c52c1 -r c75754f5b1da plugins/SpecialAdmin.php --- 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 = '
Loading page...
'; - ajaxGet('/ajax.php?title='+t+'&_mode=getpage&noheaders&auth=' + ENANO_SID, function() { + ajaxGet('/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) ) diff -r f31c252c52c1 -r c75754f5b1da plugins/SpecialUpdownload.php --- 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 diff -r f31c252c52c1 -r c75754f5b1da plugins/admin/PageManager.php --- 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 '

' . $lang->get('acppm_heading_main') . '

'; $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 @@ + +
+ {lang:acppm_msg_file_ns_warning} + @@ -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) )