# HG changeset patch # User Dan # Date 1204861541 18000 # Node ID 07bf15b066bcad193eb493bc3bfcda5a200a3141 # Parent d5376271f96bd28008cc203f0dbd6da63aa50625 Hopefully completed rewrite and localization of rollback backend and interface diff -r d5376271f96b -r 07bf15b066bc ajax.php --- a/ajax.php Thu Mar 06 20:53:26 2008 -0500 +++ b/ajax.php Thu Mar 06 22:45:41 2008 -0500 @@ -398,6 +398,13 @@ break; case "protect": // echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']); + + if ( @$_POST['reason'] === '__ROLLBACK__' ) + { + // __ROLLBACK__ is a keyword for log entries. + die('"__ROLLBACK__" ain\'t gonna do it, buddy. Try to _not_ use reserved keywords next time, ok?'); + } + $page = new PageProcessor($paths->page_id, $paths->namespace); header('Content-type: application/json'); diff -r d5376271f96b -r 07bf15b066bc includes/clientside/static/ajax.js --- a/includes/clientside/static/ajax.js Thu Mar 06 20:53:26 2008 -0500 +++ b/includes/clientside/static/ajax.js Thu Mar 06 22:45:41 2008 -0500 @@ -216,8 +216,20 @@ ajaxPost(stdAjaxPrefix+'&_mode=protect', 'reason='+ajaxEscape(r)+'&level='+l, function() { if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); - if(ajax.responseText != 'good') - alert(ajax.responseText); + if(ajax.responseText == 'good') + return true; + // check for JSON error response + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) == '{' ) + { + response = parseJSON(response); + if ( response.mode == 'error' ) + { + alert(response.error); + return true; + } + } + alert(ajax.responseText); } }, true); } @@ -403,13 +415,13 @@ }); } -function ajaxHistView(oldid, tit) { +function ajaxHistView(oldid, ttl) { // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - if(!tit) tit=title; + if(!ttl) ttl=title; setAjaxLoading(); - ajaxGet(append_sid(scriptPath+'/ajax.php?title='+tit+'&_mode=getpage&oldid='+oldid), function() { + ajaxGet(append_sid(scriptPath+'/ajax.php?title='+ttl+'&_mode=getpage&oldid='+oldid), function() { if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); edit_open = false; @@ -426,7 +438,30 @@ ajaxGet(stdAjaxPrefix+'&_mode=rollback&id='+id, function() { if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); - alert(ajax.responseText); + + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + + response = parseJSON(response); + if ( response.success ) + { + alert( $lang.get('page_msg_rb_success_' + response.action, { dateline: response.dateline }) ) + } + else + { + if ( response.action ) + { + alert( $lang.get('page_err_' + response.error, { action: response.action }) ); + } + else + { + alert( $lang.get('page_err_' + response.error) ); + } + } } }); } diff -r d5376271f96b -r 07bf15b066bc includes/functions.php --- a/includes/functions.php Thu Mar 06 20:53:26 2008 -0500 +++ b/includes/functions.php Thu Mar 06 22:45:41 2008 -0500 @@ -814,7 +814,12 @@ { $selfn = substr($paths->page_id, strlen($paths->nslist['File']), strlen($paths->page_id)); } - $q = $db->sql_query('SELECT mimetype,time_id,size FROM '.table_prefix.'files WHERE page_id=\''.$selfn.'\' ORDER BY time_id DESC;'); + $selfn = $db->escape($selfn); + $q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n" + . " LEFT JOIN " . table_prefix . "logs AS l\n" + . " ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n" + . " WHERE f.page_id = '$selfn'\n" + . " ORDER BY f.time_id DESC;"); if ( !$q ) { $db->_die('The file type could not be fetched.'); @@ -845,7 +850,7 @@ { $size .= ' (' . ( round($r['size'] / 1024, 1) ) . ' ' . $lang->get('etc_unit_kilobytes_short') . ')'; } - + echo $lang->get('onpage_filebox_lbl_size', array('size' => $size)); echo '
' . $lang->get('onpage_filebox_lbl_uploaded') . ' ' . $datestring . '

'; @@ -876,12 +881,26 @@ echo '

'; if ( $db->numrows() > 1 ) { + // requery, sql_result_seek() doesn't work on postgres + $db->free_result(); + $q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n" + . " LEFT JOIN " . table_prefix . "logs AS l\n" + . " ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n" + . " WHERE f.page_id = '$selfn'\n" + . " ORDER BY f.time_id DESC;"); + if ( !$q ) + $db->_die(); + echo '

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

'; + $last_rollback_id = false; while ( $r = $db->fetchrow() ) { echo '(' . $lang->get('onpage_filebox_btn_this_version') . ') '; - if ( $session->get_permissions('history_rollback') ) - echo ' (' . $lang->get('onpage_filebox_btn_revert') . ') '; + if ( $session->get_permissions('history_rollback') && $last_rollback_id ) + echo ' (' . $lang->get('onpage_filebox_btn_revert') . ') '; + else if ( $session->get_permissions('history_rollback') && !$last_rollback_id ) + echo ' (' . $lang->get('onpage_filebox_btn_current') . ') '; + $last_rollback_id = $r['log_id']; $mimetype = $r['mimetype']; $datestring = enano_date('F d, Y h:i a', (int)$r['time_id']); @@ -4189,6 +4208,51 @@ return ( get_char_count($string, "\n") ) + 1; } +if ( !function_exists('sys_get_temp_dir') ) +{ + // Based on http://www.phpit.net/ + // article/creating-zip-tar-archives-dynamically-php/2/ + /** + * Attempt to get the system's temp directory. + * @return string or bool false on failure + */ + + function sys_get_temp_dir() + { + // Try to get from environment variable + if ( !empty($_ENV['TMP']) ) + { + return realpath( $_ENV['TMP'] ); + } + else if ( !empty($_ENV['TMPDIR']) ) + { + return realpath( $_ENV['TMPDIR'] ); + } + else if ( !empty($_ENV['TEMP']) ) + { + return realpath( $_ENV['TEMP'] ); + } + + // Detect by creating a temporary file + else + { + // Try to use system's temporary directory + // as random name shouldn't exist + $temp_file = tempnam( md5(uniqid(rand(), TRUE)), '' ); + if ( $temp_file ) + { + $temp_dir = realpath( dirname($temp_file) ); + unlink( $temp_file ); + return $temp_dir; + } + else + { + return FALSE; + } + } + } +} + //die('

Original:  01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'
'); ?> diff -r d5376271f96b -r 07bf15b066bc includes/pageprocess.php --- a/includes/pageprocess.php Thu Mar 06 20:53:26 2008 -0500 +++ b/includes/pageprocess.php Thu Mar 06 22:45:41 2008 -0500 @@ -221,7 +221,8 @@ if ( !$this->page_exists ) { $func_name = "page_{$this->namespace}_{$this->page_id}"; - die_semicritical($lang->get('page_msg_admin_404_title'), $lang->get('page_msg_admin_404_body', array('func_name' => $func_name))); + + die_semicritical($lang->get('page_msg_admin_404_title'), $lang->get('page_msg_admin_404_body', array('func_name' => $func_name)), (!$this->send_headers)); } $func_name = "page_{$this->namespace}_{$this->page_id}"; if ( function_exists($func_name) ) @@ -519,7 +520,7 @@ } // Guess the proper title - $name = ( !empty($title) ) ? $title : dirtify_page_id($this->page_id); + $name = ( !empty($title) ) ? $title : str_replace('_', ' ', dirtify_page_id($this->page_id)); // Check for the restricted Project: prefix if ( substr($this->page_id, 0, 8) == 'Project:' ) @@ -621,19 +622,134 @@ $log_entry = $db->fetchrow(); $db->free_result(); + $dateline = enano_date('d M Y h:i a', $log_entry['time_id']); + // Let's see, what do we have here... switch ( $log_entry['action'] ) { case 'rename': // Page was renamed, let the rename method handle this - return $this->rename($log_entry['edit_summary']); + return array_merge($this->rename($log_entry['edit_summary']), array('dateline' => $dateline, 'action' => $log_entry['action'])); break; case 'prot': case 'unprot': case 'semiprot': - return $this->protect_page(intval($log_entry['page_text']), '__REVERSION__'); + return array_merge($this->protect_page(intval($log_entry['page_text']), '__REVERSION__'), array('dateline' => $dateline, 'action' => $log_entry['action'])); + break; + case 'delete': + + // Raising a previously dead page has implications... + + // FIXME: l10n + // rollback_extra is required because usually only moderators can undo page deletion AND restore the content. + if ( !$this->perms->get_permissions('history_rollback_extra') ) + return 'Administrative privileges are required for page undeletion.'; + + // Rolling back the deletion of a page that was since created? + $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id; + if ( isset($paths->pages[$pathskey]) ) + return array( + 'success' => false, + // This is a clean Christian in-joke. + 'error' => 'seeking_living_among_dead' + ); + + // Generate a crappy page name + $name = $db->escape( str_replace('_', ' ', dirtify_page_id($this->page_id)) ); + + // Stage 1 - re-insert page + $e = $db->sql_query('INSERT INTO ' . table_prefix.'pages(name,urlname,namespace) VALUES( \'' . $name . '\', \'' . $this->page_id . '\',\'' . $this->namespace . '\' )'); + if ( !$e ) + $db->die_json(); + + // Select the latest published revision + $q = $db->sql_query('SELECT page_text FROM ' . table_prefix . "logs WHERE\n" + . " log_type = 'page'\n" + . " AND action = 'edit'\n" + . " AND page_id = '$this->page_id'\n" + . " AND namespace = '$this->namespace'\n" + . " AND is_draft != 1\n" + . "ORDER BY time_id DESC LIMIT 1;"); + if ( !$q ) + $db->die_json(); + list($page_text) = $db->fetchrow_num(); + $db->free_result($q); + + // Apply the latest revision as the current page text + $page_text = $db->escape($page_text); + $e = $db->sql_query('INSERT INTO ' . table_prefix."page_text(page_id, namespace, page_text) VALUES\n" + . " ( '$this->page_id', '$this->namespace', '$page_text' );"); + if ( !$e ) + $db->die_json(); + + return array( + 'success' => true, + 'dateline' => $dateline, + 'action' => $log_entry['action'] + ); + + break; + case 'reupload': + + // given a log id and some revision info, restore the old file. + // get the timestamp of the file before this one + $q = $db->sql_query('SELECT time_id, file_key, file_extension, filename, size, mimetype FROM ' . table_prefix . "files WHERE time_id < {$log_entry['time_id']} ORDER BY time_id DESC LIMIT 1;"); + if ( !$q ) + $db->_die(); + + $row = $db->fetchrow(); + $db->free_result(); + + // If the file hasn't been renamed to the new format (omitting timestamp), do that now. + $fname = ENANO_ROOT . "/files/{$row['file_key']}_{$row['time_id']}{$row['file_extension']}"; + if ( @file_exists($fname) ) + { + // it's stored in the old format - rename + $fname_new = ENANO_ROOT . "/files/{$row['file_key']}{$row['file_extension']}"; + if ( !@rename($fname, $fname_new) ) + { + return array( + 'success' => false, + 'error' => 'rb_file_rename_failed', + 'action' => $log_entry['action'] + ); + } + } + + // Insert a new file entry + $time = time(); + $filename = $db->escape($row['filename']); + $mimetype = $db->escape($row['mimetype']); + $ext = $db->escape($row['file_extension']); + $key = $db->escape($row['file_key']); + + $q = $db->sql_query('INSERT INTO ' . table_prefix . "files ( time_id, page_id, filename, size, mimetype, file_extension, file_key ) VALUES\n" + . " ( $time, '$this->page_id', '$filename', {$row['size']}, '$mimetype', '$ext', '$key' );"); + if ( !$q ) + $db->die_json(); + + // add reupload log entry + $username = $db->escape($session->username); + $q = $db->sql_query('INSERT INTO ' . table_prefix . "logs ( log_type, action, time_id, page_id, namespace, author, edit_summary ) VALUES\n" + . " ( 'page', 'reupload', $time, '$this->page_id', '$this->namespace', '$username', '__ROLLBACK__' )"); + if ( !$q ) + $db->die_json(); + + return array( + 'success' => true, + 'dateline' => $dateline, + 'action' => $log_entry['action'] + ); + break; default: + + return array( + 'success' => false, + 'error' => 'rb_action_not_supported', + 'action' => $log_entry['action'] + ); + break; } } @@ -743,6 +859,14 @@ $existing_protection = intval($metadata['protected']); $reason = $db->escape($reason); + if ( $existing_protection == $protection_level ) + { + return array( + 'success' => false, + 'error' => 'protection_already_there' + ); + } + $action = '[ insanity ]'; switch($protection_level) { @@ -755,13 +879,13 @@ . " ( 'page', '$action', '{$this->page_id}', '{$this->namespace}', '$username', '$reason', '$time', '$existing_protection', 'DATE_STRING COLUMN OBSOLETE, USE time_id' );"; if ( !$db->sql_query($sql) ) { - $db->_die(); + $db->die_json(); } // Perform the actual protection $q = $db->sql_query('UPDATE ' . table_prefix . "pages SET protected = $protection_level WHERE urlname = '{$this->page_id}' AND namespace = '{$this->namespace}';"); if ( !$q ) - $db->_die(); + $db->die_json(); return array( 'success' => true @@ -1666,7 +1790,7 @@ echo '

' . $lang->get('page_msg_404_was_deleted', array( 'delete_time' => enano_date('d M Y h:i a', $r['time_id']), 'delete_reason' => htmlspecialchars($r['edit_summary']), - 'rollback_flags' => 'href="'.makeUrl($paths->page, 'do=rollback&id='.$r['time_id']).'" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;"' + 'rollback_flags' => 'href="'.makeUrl($paths->page, 'do=rollback&id='.$r['log_id']).'" onclick="ajaxRollback(\''.$r['log_id'].'\'); return false;"' )) . '

'; if ( $session->user_level >= USER_LEVEL_ADMIN ) diff -r d5376271f96b -r 07bf15b066bc includes/pageutils.php --- a/includes/pageutils.php Thu Mar 06 20:53:26 2008 -0500 +++ b/includes/pageutils.php Thu Mar 06 22:45:41 2008 -0500 @@ -498,7 +498,7 @@ elseif($r['action']=='rename') echo $lang->get('history_log_rename') . '' . $lang->get('history_extra_oldtitle') . ' '.htmlspecialchars($r['edit_summary']); elseif($r['action']=='create') echo $lang->get('history_log_create') . ''; elseif($r['action']=='delete') echo $lang->get('history_log_delete') . '' . $lang->get('history_extra_reason') . ' ' . $r['edit_summary']; - elseif($r['action']=='reupload') echo $lang->get('history_log_uploadnew') . '' . $lang->get('history_extra_reason') . ' '.htmlspecialchars($r['edit_summary']); + elseif($r['action']=='reupload') echo $lang->get('history_log_uploadnew') . '' . $lang->get('history_extra_reason') . ' ' . ( $r['edit_summary'] === '__ROLLBACK__' ? $lang->get('history_extra_upload_reversion') : htmlspecialchars($r['edit_summary']) ); echo ''; // Actions! @@ -526,157 +526,8 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; - // FIXME: l10n - - if ( !$session->get_permissions('history_rollback') ) - { - return('You are not authorized to perform rollbacks.'); - } - if ( !preg_match('#^([0-9]+)$#', (string)$id) ) - { - return('The value "id" on the query string must be an integer.'); - } - $e = $db->sql_query('SELECT time_id,log_type,action,date_string,page_id,namespace,page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE log_id=' . $id . ';'); - if ( !$e ) - { - $db->_die('The rollback data could not be selected.'); - } - $rb = $db->fetchrow(); - $db->free_result(); - - if ( $rb['log_type'] == 'page' && $rb['action'] != 'delete' ) - { - $pagekey = $paths->nslist[$rb['namespace']] . $rb['page_id']; - if ( !isset($paths->pages[$pagekey]) ) - { - return "Page doesn't exist"; - } - $pagedata =& $paths->pages[$pagekey]; - $protected = false; - // Special case: is the page protected? if so, check for even_when_protected permissions - if($pagedata['protected'] == 2) - { - // The page is semi-protected, determine permissions - if($session->user_logged_in && $session->reg_time + 60*60*24*4 < time()) - { - $protected = false; - } - else - { - $protected = true; - } - } - else - { - $protected = ( $pagedata['protected'] == 1 ); - } - - $perms = $session->fetch_page_acl($rb['page_id'], $rb['namespace']); - - if ( $protected && !$perms->get_permissions('even_when_protected') ) - { - return "Because this page is protected, you need moderator rights to roll back changes."; - } - } - else - { - $perms =& $session; - } - - switch($rb['log_type']) - { - case "page": - switch($rb['action']) - { - // Support for rolling back edits removed in 1.1.2 - moved to page editor system - case "rename": - if ( !$perms->get_permissions('rename') ) - return "You don't have permission to rename pages, so rolling back renames can't be allowed either."; - - $t = $rb['edit_summary']; - // result prediction - $subst = array( - 'page_name_old' => get_page_title_ns($rb['page_id'], $rb['namespace']), - 'page_name_new' => $t - ); - - $e = PageUtils::rename($rb['page_id'], $rb['namespace'], $t); - - $e = ( $e == $lang->get('ajax_rename_success', $subst) ); - - if ( !$e ) - { - return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); - } - else - { - return 'The page "' . htmlspecialchars($paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name']) . '" has been rolled back to the name it had ("' . htmlspecialchars($rb['edit_summary']) . '") before ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; - } - break; - case "prot": - if ( !$perms->get_permissions('protect') ) - return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; - $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=0 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); - if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); - else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; - break; - case "semiprot": - if ( !$perms->get_permissions('protect') ) - return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; - $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=0 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); - if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); - else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; - break; - case "unprot": - if ( !$perms->get_permissions('protect') ) - return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; - $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=1 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); - if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); - else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been protected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; - break; - case "delete": - if ( !$perms->get_permissions('history_rollback_extra') ) - return 'Administrative privileges are required for page undeletion.'; - if ( isset($paths->pages[$paths->cpage['urlname']]) ) - return 'You cannot raise a dead page that is alive.'; - $name = str_replace('_', ' ', $rb['page_id']); - $e = $db->sql_query('INSERT INTO ' . table_prefix.'pages(name,urlname,namespace) VALUES( \'' . $name . '\', \'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\' )');if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); - $e = $db->sql_query('SELECT page_text,char_tag FROM ' . table_prefix.'logs WHERE page_id=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\' AND log_type=\'page\' AND action=\'edit\' ORDER BY time_id DESC;'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); - $r = $db->fetchrow(); - $e = $db->sql_query('INSERT INTO ' . table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\',\'' . $db->escape($r['page_text']) . '\',\'' . $r['char_tag'] . '\')'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); - return 'The page "' . $name . '" has been undeleted according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; - break; - case "reupload": - if ( !$session->get_permissions('history_rollback_extra') ) - { - return 'Administrative privileges are required for file rollbacks.'; - } - $newtime = time(); - $newdate = enano_date('d M Y h:i a'); - if(!$db->sql_query('UPDATE ' . table_prefix.'logs SET time_id=' . $newtime . ',date_string=\'' . $newdate . '\' WHERE time_id=' . $id)) - return 'Error during query: '.$db->get_error(); - if(!$db->sql_query('UPDATE ' . table_prefix.'files SET time_id=' . $newtime . ' WHERE time_id=' . $id)) - return 'Error during query: '.$db->get_error(); - return 'The file has been rolled back to the version uploaded on '.enano_date('d M Y h:i a', (int)$id).'.'; - break; - default: - return('Rollback of the action "' . $rb['action'] . '" is not yet supported.'); - break; - } - break; - case "security": - case "login": - return('A ' . $rb['log_type'] . '-related log entry cannot be rolled back.'); - break; - default: - return('Unknown log entry type: "' . $rb['log_type'] . '"'); - } + // placeholder + return 'PageUtils->rollback() is deprecated - use PageProcessor instead.'; } /** diff -r d5376271f96b -r 07bf15b066bc index.php --- a/index.php Thu Mar 06 20:53:26 2008 -0500 +++ b/index.php Thu Mar 06 22:45:41 2008 -0500 @@ -267,9 +267,23 @@ case 'rollback': $id = (isset($_GET['id'])) ? $_GET['id'] : false; if(!$id || !preg_match('#^([0-9]+)$#', $id)) die_friendly('Invalid action ID', '

The URL parameter "id" is not an integer. Exiting to prevent nasties like SQL injection, etc.

'); - $rb = PageUtils::rollback( (int) $id ); + + $id = intval($id); + + $page = new PageProcessor($paths->page_id, $paths->namespace); + $result = $page->rollback_log_entry($id); + + if ( $result['success'] ) + { + $result = $lang->get("page_msg_rb_success_{$result['action']}", array('dateline' => $result['dateline'])); + } + else + { + $result = $lang->get("page_err_{$result['error']}", array('action' => @$result['action'])); + } + $template->header(); - echo '

'.$rb.' Return to the page.

'; + echo '

'.$result.' ' . $lang->get('etc_return_to_page') . '

'; $template->footer(); break; case 'catedit': diff -r d5376271f96b -r 07bf15b066bc language/english/core.json --- a/language/english/core.json Thu Mar 06 20:53:26 2008 -0500 +++ b/language/english/core.json Thu Mar 06 22:45:41 2008 -0500 @@ -128,6 +128,13 @@

If you would like to inquire further about this message, you may contact the %site_administration%.

', err_access_denied_siteadmin: 'site administrator', + err_seeking_living_among_dead: 'You are trying to un-delete a page that has since been restored.\n\n"But the men said to them, \'Why do you look for the living among the dead?\'" (Luke 24:5b/NIV)', + err_access_denied: 'Access to that action is denied.', + err_invalid_parameter: 'An invalid value (parameter) was sent to this action.', + err_rb_action_not_supported: 'Rolling back actions of type "%action%" isn\'t supported.', + err_rb_file_rename_failed: 'Could not rename the file to its new name (1.1.x format)', + err_protection_already_there: 'The protection level you selected is already in effect for this page.', + msg_this_is_a_redirector: 'This page is a redirector.
This means that this page will not show its own content by default. Instead it will display the contents of the page it redirects to.

To create a redirect page, make the first characters in the page content #redirect [[Page_ID]]. For more information, see the @@ -135,6 +142,14 @@ This page redirects to %redirect_target%.', msg_redirected_from: '(Redirected from %from%)', msg_redirected_from_to: '(Redirected from %from% to %to%)', + msg_rb_success_rename: 'The page has been restored the name it had on %dateline%.', + // next 3 are mostly identical + msg_rb_success_prot: 'The page\'s protection has been undone and replaced with the previous level it had as of %dateline%.', + msg_rb_success_unprot: 'The page\'s protection has been undone and replaced with the previous level it had as of %dateline%.', + msg_rb_success_semiprot: 'The page\'s semi-protection has been undone and replaced with the previous level it had as of %dateline%.', + + msg_rb_success_delete: 'The deletion of this page, which occurred on %dateline%, has been undone. This page has been restored, but comments and categorization data may have been lost.', + msg_rb_success_reupload: 'The file has been restored to the version uploaded on %dateline%.', msg_passrequired: 'Access to this page requires a password. Please enter the password for this page below:', msg_pass_wrong: 'The password you entered for this page was incorrect. Please enter the password for this page below:', @@ -292,8 +307,8 @@ filebox_btn_upload_new: 'Upload new version', filebox_heading_history: 'File history', filebox_btn_this_version: 'this ver', - filebox_btn_revert: 'revert', - + filebox_btn_revert: 'restore', + filebox_btn_current: 'current', }, editor: { err_server: 'There was a problem starting the editor', @@ -373,6 +388,7 @@ extra_reason: 'Reason:', extra_oldtitle: 'Old title:', extra_protection_reversion: '(Reversion of previous protection)', + extra_upload_reversion: '(Restoration of previous upload)', tip_rdns: 'Click cell background for reverse DNS info', action_view: 'View', action_contrib: 'User contribs', diff -r d5376271f96b -r 07bf15b066bc plugins/SpecialUpdownload.php --- a/plugins/SpecialUpdownload.php Thu Mar 06 20:53:26 2008 -0500 +++ b/plugins/SpecialUpdownload.php Thu Mar 06 22:45:41 2008 -0500 @@ -120,8 +120,8 @@ $chartag = sha1(microtime()); $urln = str_replace(' ', '_', $filename); - $key = md5($filename . '_' . file_get_contents($file['tmp_name'])); - $targetname = ENANO_ROOT . '/files/' . $key . '_' . $utime . $ext; + $key = md5($filename . '_' . ( function_exists('md5_file') ? md5_file($file['tmp_name']) : file_get_contents($file['tmp_name']))); + $targetname = ENANO_ROOT . '/files/' . $key . $ext; if(!@move_uploaded_file($file['tmp_name'], $targetname)) { @@ -233,7 +233,15 @@ die_friendly($lang->get('etc_access_denied_short'), '

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

'); } - $fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension']; + $fname = ENANO_ROOT . '/files/' . $row['file_key'] . $row['file_extension']; + if ( !file_exists($fname) ) + { + $fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension']; + } + if ( !file_exists($fname) ) + { + die("Uploaded file $fname not found."); + } if ( isset($_GET['preview']) && substr($row['mimetype'], 0, 6) == 'image/' ) { @@ -262,7 +270,7 @@ { // Get a temporary file // In this case, the file will not be cached and will be scaled each time it's requested - $temp_dir = ( is_dir('/tmp') ) ? '/tmp' : ( isset($_ENV['TEMP']) ) ? $_ENV['TEMP'] : 'SOME RANDOM NAME'; + $temp_dir = sys_get_temp_dir(); // if tempnam() cannot use the specified directory name, it will fall back on the system default $tempname = tempnam($temp_dir, $filename); if ( $tempname && is_writeable($tempname) )