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 '

'; + } + + $template->footer(); +} + +function rch_get_css($change_size) +{ + // Hardly changed at all? Return a gray + if ( $change_size <= 5 && $change_size >= -5 ) + return 'color: #808080;'; + // determine saturation based on size of change (1-500 bytes) + $change_abs = abs($change_size); + $index = 0x70 * ( $change_abs / 500 ); + if ( $index > 0x70 ) + $index = 0x70; + $index = $index + 0x40; + $index = dechex($index); + if ( strlen($index) < 2 ) + $index = "0$index"; + $css = ( $change_size > 0 ) ? "color: #00{$index}00;" : "color: #{$index}0000;"; + if ( $change_abs > 500 ) + $css .= ' font-weight: bold;'; + return $css; +} + +?>