diff -r de56132c008d -r bdac73ed481e includes/log.php --- a/includes/log.php Sun Mar 28 21:49:26 2010 -0400 +++ b/includes/log.php Sun Mar 28 23:10:46 2010 -0400 @@ -22,469 +22,469 @@ class LogDisplay { - /** - * Criteria for the search. - * Structure: - - array( - array( 'user', 'Dan' ), - array( 'within', 86400 ), - array( 'page', 'Main_Page' ) - ) - - * @var array - */ - - var $criteria = array(); - - /** - * Adds a criterion for the log display. - * @param string Criterion type - user, page, or within - * @param string Value - username, page ID, or (int) within # seconds or (string) number + suffix (suffix: d = day, w = week, m = month, y = year) ex: "1w" - */ - - public function add_criterion($criterion, $value) - { - switch ( $criterion ) - { - case 'user': - case 'page': - case 'action': - $this->criteria[] = array($criterion, $value); - break; - case 'minor': - $this->criteria[] = array($criterion, intval($value)); - break; - case 'within': - if ( is_int($value) ) - { - $this->criteria[] = array($criterion, $value); - } - else if ( is_string($value) ) - { - $lastchar = substr($value, -1); - $amt = intval($value); - switch($lastchar) - { - case 'd': - $amt = $amt * 86400; - break; - case 'w': - $amt = $amt * 604800; - break; - case 'm': - $amt = $amt * 2592000; - break; - case 'y': - $amt = $amt * 31536000; - break; - } - $this->criteria[] = array($criterion, $amt); - } - else - { - throw new Exception('Invalid value type for within'); - } - break; - default: - throw new Exception('Unknown criterion type'); - break; - } - } - - /** - * Build the necessary SQL query. - * @param int Optional: offset, defaults to 0 - * @param int Optional: page size, defaults to 0; 0 = don't limit - */ - - public function build_sql($offset = 0, $page_size = 0, $just_page_count = false) - { - global $db, $session, $paths, $template, $plugins; // Common objects - - $where_extra = ''; - $where_bits = array( - 'user' => array(), - 'page' => array(), - 'action' => array() - ); - foreach ( $this->criteria as $criterion ) - { - list($type, $value) = $criterion; - switch($type) - { - case 'user': - $where_bits['user'][] = "author = '" . $db->escape(str_replace('_', ' ', $value)) . "'"; - break; - case 'action': - if ( $value === 'protect' ) - { - $where_bits['action'][] = "action = 'prot'"; - $where_bits['action'][] = "action = 'unprot'"; - $where_bits['action'][] = "action = 'semiprot'"; - } - else - { - $where_bits['action'][] = "action = '" . $db->escape($value) . "'"; - } - break; - case 'page': - list($page_id, $namespace) = RenderMan::strToPageId($value); - $where_bits['page'][] = "page_id = '" . $db->escape($page_id) . "' AND namespace = '" . $db->escape($namespace) . "'"; - break; - case 'within': - $threshold = time() - $value; - $where_extra .= "\n AND time_id > $threshold"; - break; - case 'minor': - if ( $value == 1 ) - $where_extra .= "\n AND ( minor_edit = 1 OR action != 'edit' )"; - else - $where_extra .= "\n AND minor_edit != 1"; - break; - } - } - if ( !empty($where_bits['user']) ) - { - $where_extra .= "\n AND ( " . implode(" OR ", $where_bits['user']) . " )"; - } - if ( !empty($where_bits['page']) ) - { - $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['page']) . ") )"; - } - if ( !empty($where_bits['action']) ) - { - $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['action']) . ") )"; - } - if ( ENANO_DBLAYER == 'PGSQL' ) - $limit = ( $page_size > 0 ) ? "\n LIMIT $page_size OFFSET $offset" : ''; - else - $limit = ( $page_size > 0 ) ? "\n LIMIT $offset, $page_size" : ''; - $columns = ( $just_page_count ) ? 'COUNT(*)' : 'log_id, action, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, author, author_uid, u.username, time_id, edit_summary, minor_edit'; - $sql = 'SELECT ' . $columns . ' FROM ' . table_prefix . "logs AS l\n" - . " LEFT JOIN " . table_prefix . "users AS u\n" - . " ON ( u.user_id = l.author_uid OR u.user_id IS NULL )\n" - . " WHERE log_type = 'page' AND is_draft != 1$where_extra\n" - . " GROUP BY log_id, action, page_id, namespace, page_text, author, author_uid, username, time_id, edit_summary, minor_edit\n" - . " ORDER BY time_id DESC $limit;"; - - return $sql; - } - - /** - * Get data! - * @param int Offset, defaults to 0 - * @param int Page size, if 0 (default) returns entire table (danger Will Robinson!) - * @return array - */ - - public function get_data($offset = 0, $page_size = 0) - { - global $db, $session, $paths, $session, $plugins; // Common objects - $sql = $this->build_sql($offset, $page_size); - if ( !$db->sql_query($sql) ) - $db->_die(); - - $return = array(); - $deplist = array(); - $idlist = array(); - while ( $row = $db->fetchrow() ) - { - $return[ $row['log_id'] ] = $row; - if ( $row['action'] === 'edit' ) - { - // This is a page revision; its parent needs to be found - $pagekey = serialize(array($row['page_id'], $row['namespace'])); - $deplist[$pagekey] = "( page_id = '" . $db->escape($row['page_id']) . "' AND namespace = '" . $db->escape($row['namespace']) . "' AND log_id < {$row['log_id']} )"; - // if we already have a revision from this page in the dataset, we've found its parent - if ( isset($idlist[$pagekey]) ) - { - $child =& $return[ $idlist[$pagekey] ]; - $child['parent_size'] = $row['revision_size']; - $child['parent_revid'] = $row['log_id']; - $child['parent_time'] = $row['time_id']; - unset($child); - } - $idlist[$pagekey] = $row['log_id']; - } - } - - // Second query fetches all parent revision data - // (maybe we have no edits?? check deplist) - - if ( !empty($deplist) ) - { - // FIXME: inefficient. damn GROUP BY for not obeying ORDER BY, it means we can't group and instead have to select - // all previous revisions of page X and discard all but the first one we find. - $where_extra = implode("\n OR ", $deplist); - $sql = 'SELECT log_id, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, time_id FROM ' . table_prefix . "logs\n" - . " WHERE log_type = 'page' AND action = 'edit'\n AND ( $where_extra )\n" - // . " GROUP BY page_id, namespace\n" - . " ORDER BY log_id DESC;"; - if ( !$db->sql_query($sql) ) - $db->_die(); - - while ( $row = $db->fetchrow() ) - { - $pagekey = serialize(array($row['page_id'], $row['namespace'])); - if ( isset($idlist[$pagekey]) ) - { - $child =& $return[ $idlist[$pagekey] ]; - $child['parent_size'] = $row['revision_size']; - $child['parent_revid'] = $row['log_id']; - $child['parent_time'] = $row['time_id']; - unset($child, $idlist[$pagekey]); - } - } - } - - // final iteration goes through all edits and if there's not info on the parent, sets to 0. It also calculates size change. - foreach ( $return as &$row ) - { - if ( $row['action'] === 'edit' && !isset($row['parent_revid']) ) - { - $row['parent_revid'] = 0; - $row['parent_size'] = 0; - } - if ( $row['action'] === 'edit' ) - { - $row['size_delta'] = $row['revision_size'] - $row['parent_size']; - } - } - - return array_values($return); - } - - /** - * Get the number of rows that will be in the result set. - * @return int - */ - - public function get_row_count() - { - global $db, $session, $paths, $session, $plugins; // Common objects - - if ( !$db->sql_query( $this->build_sql(0, 0, true) ) ) - $db->_die(); - - list($count) = $db->fetchrow_num(); - return $count; - } - - /** - * Returns the list of criteria - * @return array - */ - - public function get_criteria() - { - return $this->criteria; - } - - /** - * Formats a result row into pretty HTML. - * @param array dataset from LogDisplay::get_data() - * @param bool If true (default), shows action buttons. - * @param bool If true (default), shows page title; good for integrated displays - * @static - * @return string - */ - - public static function render_row($row, $show_buttons = true, $show_pagetitle = true) - { - global $db, $session, $paths, $session, $plugins; // Common objects - global $lang; - - $html = ''; - - $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 - if ( $show_buttons ) - { - if ( $row['action'] == 'edit' && !empty($row['parent_revid']) ) - { - $html .= '('; - $ispage = isPage($pagekey); - - if ( $ispage ) - $html .= ''; - - $html .= $lang->get('pagetools_rc_btn_diff'); - - if ( $ispage ) - $html .= ''; - - if ( $ispage ) - $html .= ', '; - - $html .= $lang->get('pagetools_rc_btn_view'); - - if ( $ispage ) - $html .= ''; - - if ( $row['parent_revid'] > 0 && isPage($pagekey) ) - { - $html .= ', ' . $lang->get('pagetools_rc_btn_undo') . ''; - } - $html .= ') '; - } - else if ( $row['action'] != 'edit' && ( isPage($pagekey) || $row['action'] == 'delete' ) ) - { - $html .= '('; - $html .= '' . $lang->get('pagetools_rc_btn_undo') . ''; - $html .= ') '; - } - - // hist button - $html .= '('; - if ( isPage($pagekey) ) - { - $html .= ''; - } - $html .= $lang->get('pagetools_rc_btn_hist'); - if ( isPage($pagekey) ) - { - $html .= ''; - } - $html .= ') . . '; - } - - if ( $show_pagetitle ) - { - // new page? - if ( $row['action'] == 'edit' && empty($row['parent_revid']) ) - { - $html .= 'N '; - } - // minor edit? - if ( $row['action'] == 'edit' && $row['minor_edit'] ) - { - $html .= 'm '; - } - - // link to the page - $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"'; - $html .= '' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '; '; - } - - // date - $today = time() - ( time() % 86400 ); - $date = MemberlistFormatter::format_date($row['time_id']) . ' '; - $date .= date('h:i:s', $row['time_id']); - $html .= "$date . . "; - - // size counter - if ( $row['action'] == 'edit' ) - { - $css = self::get_css($row['size_delta']); - $size_change = number_format($row['size_delta']); - if ( substr($size_change, 0, 1) != '-' ) - $size_change = "+$size_change"; - - $html .= "({$size_change})"; - $html .= ' . . '; - } - - // link to userpage - $real_username = $row['author_uid'] > 1 && !empty($row['username']) ? $row['username'] : $row['author']; - $cls = ( isPage($paths->nslist['User'] . $real_username) ) ? '' : ' class="wikilink-nonexistent"'; - $rank_info = $session->get_user_rank($row['author_uid']); - $html .= '' . htmlspecialchars($real_username) . ' '; - $html .= '('; - $html .= ''; - $html .= $lang->get('pagetools_rc_btn_pm'); - $html .= ', '; - $html .= ''; - $html .= $lang->get('pagetools_rc_btn_usertalk'); - $html .= ''; - $html .= ') . . '; - - // Edit summary - - if ( $row['action'] == 'edit' ) - { - $html .= '('; - if ( empty($row['edit_summary']) ) - { - $html .= '' . $lang->get('history_summary_none_given') . ''; - } - else - { - $html .= RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary'])); - } - $html .= ')'; - } - else - { - switch($row['action']) - { - default: - $html .= $row['action']; - break; - case 'rename': - $html .= $lang->get('log_action_rename', array('old_name' => htmlspecialchars($row['edit_summary']))); - break; - case 'create': - $html .= $lang->get('log_action_create'); - break; - case 'votereset': - $html .= $lang->get('log_action_votereset', array('num_votes' => $row['edit_summary'], 'plural' => ( intval($row['edit_summary']) == 1 ? '' : $lang->get('meta_plural')))); - break; - case 'prot': - case 'unprot': - case 'semiprot': - case 'delete': - case 'reupload': - $stringmap = array( - 'prot' => 'log_action_protect_full', - 'unprot' => 'log_action_protect_none', - 'semiprot' => 'log_action_protect_semi', - 'delete' => 'log_action_delete', - 'reupload' => 'log_action_reupload' - ); - - if ( $row['edit_summary'] === '__REVERSION__' ) - $reason = '' . $lang->get('log_msg_reversion') . ''; - else if ( $row['action'] == 'reupload' && $row['edit_summary'] === '__ROLLBACK__' ) - $reason = '' . $lang->get('log_msg_file_restored') . ''; - else - $reason = ( !empty($row['edit_summary']) ) ? htmlspecialchars($row['edit_summary']) : '' . $lang->get('log_msg_no_reason_provided') . ''; - - $html .= $lang->get($stringmap[$row['action']], array('reason' => $reason)); - } - } - - return $html; - } - - /** - * Return CSS blurb for size delta - * @return string - * @static - * @access private - */ - - private static function 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; - } + /** + * Criteria for the search. + * Structure: + + array( + array( 'user', 'Dan' ), + array( 'within', 86400 ), + array( 'page', 'Main_Page' ) + ) + + * @var array + */ + + var $criteria = array(); + + /** + * Adds a criterion for the log display. + * @param string Criterion type - user, page, or within + * @param string Value - username, page ID, or (int) within # seconds or (string) number + suffix (suffix: d = day, w = week, m = month, y = year) ex: "1w" + */ + + public function add_criterion($criterion, $value) + { + switch ( $criterion ) + { + case 'user': + case 'page': + case 'action': + $this->criteria[] = array($criterion, $value); + break; + case 'minor': + $this->criteria[] = array($criterion, intval($value)); + break; + case 'within': + if ( is_int($value) ) + { + $this->criteria[] = array($criterion, $value); + } + else if ( is_string($value) ) + { + $lastchar = substr($value, -1); + $amt = intval($value); + switch($lastchar) + { + case 'd': + $amt = $amt * 86400; + break; + case 'w': + $amt = $amt * 604800; + break; + case 'm': + $amt = $amt * 2592000; + break; + case 'y': + $amt = $amt * 31536000; + break; + } + $this->criteria[] = array($criterion, $amt); + } + else + { + throw new Exception('Invalid value type for within'); + } + break; + default: + throw new Exception('Unknown criterion type'); + break; + } + } + + /** + * Build the necessary SQL query. + * @param int Optional: offset, defaults to 0 + * @param int Optional: page size, defaults to 0; 0 = don't limit + */ + + public function build_sql($offset = 0, $page_size = 0, $just_page_count = false) + { + global $db, $session, $paths, $template, $plugins; // Common objects + + $where_extra = ''; + $where_bits = array( + 'user' => array(), + 'page' => array(), + 'action' => array() + ); + foreach ( $this->criteria as $criterion ) + { + list($type, $value) = $criterion; + switch($type) + { + case 'user': + $where_bits['user'][] = "author = '" . $db->escape(str_replace('_', ' ', $value)) . "'"; + break; + case 'action': + if ( $value === 'protect' ) + { + $where_bits['action'][] = "action = 'prot'"; + $where_bits['action'][] = "action = 'unprot'"; + $where_bits['action'][] = "action = 'semiprot'"; + } + else + { + $where_bits['action'][] = "action = '" . $db->escape($value) . "'"; + } + break; + case 'page': + list($page_id, $namespace) = RenderMan::strToPageId($value); + $where_bits['page'][] = "page_id = '" . $db->escape($page_id) . "' AND namespace = '" . $db->escape($namespace) . "'"; + break; + case 'within': + $threshold = time() - $value; + $where_extra .= "\n AND time_id > $threshold"; + break; + case 'minor': + if ( $value == 1 ) + $where_extra .= "\n AND ( minor_edit = 1 OR action != 'edit' )"; + else + $where_extra .= "\n AND minor_edit != 1"; + break; + } + } + if ( !empty($where_bits['user']) ) + { + $where_extra .= "\n AND ( " . implode(" OR ", $where_bits['user']) . " )"; + } + if ( !empty($where_bits['page']) ) + { + $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['page']) . ") )"; + } + if ( !empty($where_bits['action']) ) + { + $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['action']) . ") )"; + } + if ( ENANO_DBLAYER == 'PGSQL' ) + $limit = ( $page_size > 0 ) ? "\n LIMIT $page_size OFFSET $offset" : ''; + else + $limit = ( $page_size > 0 ) ? "\n LIMIT $offset, $page_size" : ''; + $columns = ( $just_page_count ) ? 'COUNT(*)' : 'log_id, action, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, author, author_uid, u.username, time_id, edit_summary, minor_edit'; + $sql = 'SELECT ' . $columns . ' FROM ' . table_prefix . "logs AS l\n" + . " LEFT JOIN " . table_prefix . "users AS u\n" + . " ON ( u.user_id = l.author_uid OR u.user_id IS NULL )\n" + . " WHERE log_type = 'page' AND is_draft != 1$where_extra\n" + . " GROUP BY log_id, action, page_id, namespace, page_text, author, author_uid, username, time_id, edit_summary, minor_edit\n" + . " ORDER BY time_id DESC $limit;"; + + return $sql; + } + + /** + * Get data! + * @param int Offset, defaults to 0 + * @param int Page size, if 0 (default) returns entire table (danger Will Robinson!) + * @return array + */ + + public function get_data($offset = 0, $page_size = 0) + { + global $db, $session, $paths, $session, $plugins; // Common objects + $sql = $this->build_sql($offset, $page_size); + if ( !$db->sql_query($sql) ) + $db->_die(); + + $return = array(); + $deplist = array(); + $idlist = array(); + while ( $row = $db->fetchrow() ) + { + $return[ $row['log_id'] ] = $row; + if ( $row['action'] === 'edit' ) + { + // This is a page revision; its parent needs to be found + $pagekey = serialize(array($row['page_id'], $row['namespace'])); + $deplist[$pagekey] = "( page_id = '" . $db->escape($row['page_id']) . "' AND namespace = '" . $db->escape($row['namespace']) . "' AND log_id < {$row['log_id']} )"; + // if we already have a revision from this page in the dataset, we've found its parent + if ( isset($idlist[$pagekey]) ) + { + $child =& $return[ $idlist[$pagekey] ]; + $child['parent_size'] = $row['revision_size']; + $child['parent_revid'] = $row['log_id']; + $child['parent_time'] = $row['time_id']; + unset($child); + } + $idlist[$pagekey] = $row['log_id']; + } + } + + // Second query fetches all parent revision data + // (maybe we have no edits?? check deplist) + + if ( !empty($deplist) ) + { + // FIXME: inefficient. damn GROUP BY for not obeying ORDER BY, it means we can't group and instead have to select + // all previous revisions of page X and discard all but the first one we find. + $where_extra = implode("\n OR ", $deplist); + $sql = 'SELECT log_id, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, time_id FROM ' . table_prefix . "logs\n" + . " WHERE log_type = 'page' AND action = 'edit'\n AND ( $where_extra )\n" + // . " GROUP BY page_id, namespace\n" + . " ORDER BY log_id DESC;"; + if ( !$db->sql_query($sql) ) + $db->_die(); + + while ( $row = $db->fetchrow() ) + { + $pagekey = serialize(array($row['page_id'], $row['namespace'])); + if ( isset($idlist[$pagekey]) ) + { + $child =& $return[ $idlist[$pagekey] ]; + $child['parent_size'] = $row['revision_size']; + $child['parent_revid'] = $row['log_id']; + $child['parent_time'] = $row['time_id']; + unset($child, $idlist[$pagekey]); + } + } + } + + // final iteration goes through all edits and if there's not info on the parent, sets to 0. It also calculates size change. + foreach ( $return as &$row ) + { + if ( $row['action'] === 'edit' && !isset($row['parent_revid']) ) + { + $row['parent_revid'] = 0; + $row['parent_size'] = 0; + } + if ( $row['action'] === 'edit' ) + { + $row['size_delta'] = $row['revision_size'] - $row['parent_size']; + } + } + + return array_values($return); + } + + /** + * Get the number of rows that will be in the result set. + * @return int + */ + + public function get_row_count() + { + global $db, $session, $paths, $session, $plugins; // Common objects + + if ( !$db->sql_query( $this->build_sql(0, 0, true) ) ) + $db->_die(); + + list($count) = $db->fetchrow_num(); + return $count; + } + + /** + * Returns the list of criteria + * @return array + */ + + public function get_criteria() + { + return $this->criteria; + } + + /** + * Formats a result row into pretty HTML. + * @param array dataset from LogDisplay::get_data() + * @param bool If true (default), shows action buttons. + * @param bool If true (default), shows page title; good for integrated displays + * @static + * @return string + */ + + public static function render_row($row, $show_buttons = true, $show_pagetitle = true) + { + global $db, $session, $paths, $session, $plugins; // Common objects + global $lang; + + $html = ''; + + $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 + if ( $show_buttons ) + { + if ( $row['action'] == 'edit' && !empty($row['parent_revid']) ) + { + $html .= '('; + $ispage = isPage($pagekey); + + if ( $ispage ) + $html .= ''; + + $html .= $lang->get('pagetools_rc_btn_diff'); + + if ( $ispage ) + $html .= ''; + + if ( $ispage ) + $html .= ', '; + + $html .= $lang->get('pagetools_rc_btn_view'); + + if ( $ispage ) + $html .= ''; + + if ( $row['parent_revid'] > 0 && isPage($pagekey) ) + { + $html .= ', ' . $lang->get('pagetools_rc_btn_undo') . ''; + } + $html .= ') '; + } + else if ( $row['action'] != 'edit' && ( isPage($pagekey) || $row['action'] == 'delete' ) ) + { + $html .= '('; + $html .= '' . $lang->get('pagetools_rc_btn_undo') . ''; + $html .= ') '; + } + + // hist button + $html .= '('; + if ( isPage($pagekey) ) + { + $html .= ''; + } + $html .= $lang->get('pagetools_rc_btn_hist'); + if ( isPage($pagekey) ) + { + $html .= ''; + } + $html .= ') . . '; + } + + if ( $show_pagetitle ) + { + // new page? + if ( $row['action'] == 'edit' && empty($row['parent_revid']) ) + { + $html .= 'N '; + } + // minor edit? + if ( $row['action'] == 'edit' && $row['minor_edit'] ) + { + $html .= 'm '; + } + + // link to the page + $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"'; + $html .= '' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '; '; + } + + // date + $today = time() - ( time() % 86400 ); + $date = MemberlistFormatter::format_date($row['time_id']) . ' '; + $date .= date('h:i:s', $row['time_id']); + $html .= "$date . . "; + + // size counter + if ( $row['action'] == 'edit' ) + { + $css = self::get_css($row['size_delta']); + $size_change = number_format($row['size_delta']); + if ( substr($size_change, 0, 1) != '-' ) + $size_change = "+$size_change"; + + $html .= "({$size_change})"; + $html .= ' . . '; + } + + // link to userpage + $real_username = $row['author_uid'] > 1 && !empty($row['username']) ? $row['username'] : $row['author']; + $cls = ( isPage($paths->nslist['User'] . $real_username) ) ? '' : ' class="wikilink-nonexistent"'; + $rank_info = $session->get_user_rank($row['author_uid']); + $html .= '' . htmlspecialchars($real_username) . ' '; + $html .= '('; + $html .= ''; + $html .= $lang->get('pagetools_rc_btn_pm'); + $html .= ', '; + $html .= ''; + $html .= $lang->get('pagetools_rc_btn_usertalk'); + $html .= ''; + $html .= ') . . '; + + // Edit summary + + if ( $row['action'] == 'edit' ) + { + $html .= '('; + if ( empty($row['edit_summary']) ) + { + $html .= '' . $lang->get('history_summary_none_given') . ''; + } + else + { + $html .= RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary'])); + } + $html .= ')'; + } + else + { + switch($row['action']) + { + default: + $html .= $row['action']; + break; + case 'rename': + $html .= $lang->get('log_action_rename', array('old_name' => htmlspecialchars($row['edit_summary']))); + break; + case 'create': + $html .= $lang->get('log_action_create'); + break; + case 'votereset': + $html .= $lang->get('log_action_votereset', array('num_votes' => $row['edit_summary'], 'plural' => ( intval($row['edit_summary']) == 1 ? '' : $lang->get('meta_plural')))); + break; + case 'prot': + case 'unprot': + case 'semiprot': + case 'delete': + case 'reupload': + $stringmap = array( + 'prot' => 'log_action_protect_full', + 'unprot' => 'log_action_protect_none', + 'semiprot' => 'log_action_protect_semi', + 'delete' => 'log_action_delete', + 'reupload' => 'log_action_reupload' + ); + + if ( $row['edit_summary'] === '__REVERSION__' ) + $reason = '' . $lang->get('log_msg_reversion') . ''; + else if ( $row['action'] == 'reupload' && $row['edit_summary'] === '__ROLLBACK__' ) + $reason = '' . $lang->get('log_msg_file_restored') . ''; + else + $reason = ( !empty($row['edit_summary']) ) ? htmlspecialchars($row['edit_summary']) : '' . $lang->get('log_msg_no_reason_provided') . ''; + + $html .= $lang->get($stringmap[$row['action']], array('reason' => $reason)); + } + } + + return $html; + } + + /** + * Return CSS blurb for size delta + * @return string + * @static + * @access private + */ + + private static function 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; + } } ?>