# HG changeset patch # User Dan # Date 1202389087 18000 # Node ID 2c9745b5c09ddacfdf2659ac2f55406a95ed92bd # Parent d907601ccad25c630e10bf3e1b7ad404297f5072 Started on a Special:RecentChanges page, more to come. diff -r d907601ccad2 -r 2c9745b5c09d includes/plugins.php --- a/includes/plugins.php Wed Feb 06 19:27:43 2008 -0500 +++ b/includes/plugins.php Thu Feb 07 07:58:07 2008 -0500 @@ -16,7 +16,7 @@ var $hook_list; var $load_list; var $loaded_plugins; - var $system_plugins = Array('SpecialUserFuncs.php','SpecialUserPrefs.php','SpecialPageFuncs.php','SpecialAdmin.php','SpecialCSS.php','SpecialUpdownload.php','SpecialSearch.php','PrivateMessages.php','SpecialGroups.php'); + var $system_plugins = Array('SpecialUserFuncs.php','SpecialUserPrefs.php','SpecialPageFuncs.php','SpecialAdmin.php','SpecialCSS.php','SpecialUpdownload.php','SpecialSearch.php','PrivateMessages.php','SpecialGroups.php', 'SpecialRecentChanges.php'); function loadAll() { $dir = ENANO_ROOT.'/plugins/'; diff -r d907601ccad2 -r 2c9745b5c09d language/english/core.json --- a/language/english/core.json Wed Feb 06 19:27:43 2008 -0500 +++ b/language/english/core.json Thu Feb 07 07:58:07 2008 -0500 @@ -457,6 +457,7 @@ btn_login: 'Log in', btn_logout: 'Log out', btn_changestyle: 'Change theme', + btn_recent_changes: 'Recent edits', }, perm: { read: 'Read page(s)', diff -r d907601ccad2 -r 2c9745b5c09d language/english/tools.json --- a/language/english/tools.json Wed Feb 06 19:27:43 2008 -0500 +++ b/language/english/tools.json Thu Feb 07 07:58:07 2008 -0500 @@ -47,6 +47,7 @@ member_list: 'Member list', language_export: 'Language exporter', private_messages: 'Private Messages', + recent_changes: 'Recent changes', }, search: { th_advanced_search: 'Advanced Search', @@ -125,6 +126,12 @@ tagcloud_sidebar_btn_larger: 'Larger version', tagcloug_tip_popularity_one: '1 page', tagcloug_tip_popularity_plural: '%popularity% pages', + + // Recent changes + rc_btn_diff: 'diff', + rc_btn_hist: 'hist', + rc_btn_pm: 'PM', + rc_btn_usertalk: 'comment', }, } }; diff -r d907601ccad2 -r 2c9745b5c09d plugins/SpecialRecentChanges.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/SpecialRecentChanges.php Thu Feb 07 07:58:07 2008 -0500 @@ -0,0 +1,205 @@ +attachHook('session_started', ' + global $paths; + $paths->add_page(Array( + \'name\'=>\'specialpage_recent_changes\', + \'urlname\'=>\'RecentChanges\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + '); + +function page_Special_RecentChanges() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + // One super-loaded SQL query to fetch all the info we need: + // (theoretical) + // SELECT ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + // l1.time_id AS currev_time, l2.time_id AS oldrev_time + // FROM logs AS l1 + // LEFT JOIN logs AS l2 + // ON ( l1.log_type = l2.log_type AND l1.action = 'edit' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace ) + // WHERE l2.time_id IS NOT NULL + // GROUP BY l1.page_id, l1.namespace + // ORDER BY l2.time_id DESC, l1.time_id DESC; + // (the actual query is generated based on filter criteria) + // How it works: + // * Join the logs table with itself + // * Select the size_change virtual column, which is based on current_rev_length - old_rev_length + // * Use GROUP BY to group rows from the same page together + // * Make sure that the time_id in the second instance (l2) of enano_logs is LESS than the time_id in the first instance (l1) + // * Use ORDER BY to ensure that the latest revision before current is selected + + $where_extra = ''; + if ( isset($_GET['filter_author']) && is_array($_GET['filter_author']) ) + { + $f_author = $_GET['filter_author']; + foreach ( $f_author as &$author ) + { + $author = $db->escape($author); + } + $f_author = "\n AND (\n l1.author = '" . implode("'\n OR l1.author = '", $f_author) . "'\n )"; + $where_extra .= $f_author; + } + + if ( ENANO_DBLAYER == 'MYSQL' ) + { + $sql = 'SELECT ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + l1.time_id AS currev_time, l2.time_id AS oldrev_time + FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l1.log_type = l2.log_type AND l1.action = \'edit\' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace ) + WHERE l2.time_id IS NOT NULL' . $where_extra . ' + GROUP BY oldrev_time + ORDER BY l1.time_id DESC, l2.time_id DESC;'; + } + else + { + $sql = 'SELECT DISTINCT ON (l1.time_id) ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + l1.time_id AS currev_time, l2.time_id AS oldrev_time + FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l1.log_type = l2.log_type AND l1.action = \'edit\' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace ) + WHERE l2.time_id IS NOT NULL' . $where_extra . ' + GROUP BY l1.time_id, l1.page_id, l1.namespace, l1.author, l1.edit_summary, l2.time_id, l1.page_text, l2.page_text + ORDER BY l1.time_id DESC, l2.time_id DESC;'; + } + + $template->header(); + + $q = $db->sql_unbuffered_query($sql); + if ( !$q ) + $db->_die(); + + if ( $row = $db->fetchrow($q) ) + { + echo '
';
+ do
+ {
+ $css = rch_get_css($row['size_change']);
+ $pagekey = ( isset($paths->nslist[$row['namespace']]) ) ? $paths->nslist[$row['namespace']] . $row['page_id'] : $row['namespace'] . ':' . $row['page_id'];
+ $pagekey = sanitize_page_id($pagekey);
+
+ // diff button
+ echo '(';
+ if ( isPage($pagekey) )
+ {
+ echo '';
+ }
+ echo $lang->get('pagetools_rc_btn_diff');
+ if ( isPage($pagekey) )
+ {
+ echo '';
+ }
+ echo ') ';
+
+ // hist button
+ echo '(';
+ if ( isPage($pagekey) )
+ {
+ echo '';
+ }
+ echo $lang->get('pagetools_rc_btn_hist');
+ if ( isPage($pagekey) )
+ {
+ echo '';
+ }
+ echo ') . . ';
+
+ // link to the page
+ $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"';
+ echo '' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '; ';
+
+ // date
+ $today = time() - ( time() % 86400 );
+ $date = ( $row['currev_time'] > $today ) ? '' : MemberlistFormatter::format_date($row['currev_time']) . ' ';
+ $date .= date('h:i s', $row['currev_time']);
+ echo "$date . . ";
+
+ // size counter
+ $size_change = number_format($row['size_change']);
+ if ( substr($size_change, 0, 1) != '-' )
+ $size_change = "+$size_change";
+
+ echo "({$size_change})";
+
+ // link to userpage
+ echo ' . . ';
+ $cls = ( isPage($paths->nslist['User'] . $row['author']) ) ? '' : ' class="wikilink-nonexistent"';
+ echo '' . htmlspecialchars($row['author']) . ' ';
+ echo '(';
+ echo '';
+ echo $lang->get('pagetools_rc_btn_pm');
+ echo ', ';
+ echo '';
+ echo $lang->get('pagetools_rc_btn_usertalk');
+ echo '';
+ echo ') . . ';
+
+ // Edit summary
+ echo '(';
+ if ( empty($row['edit_summary']) )
+ {
+ echo '' . $lang->get('history_summary_none_given') . '';
+ }
+ else
+ {
+ echo RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary']));
+ }
+ echo ')';
+
+ echo '
';
+ }
+ while ( $row = $db->fetchrow($q) );
+ echo '