Step 3: Balance the quotes directly on $text
[lhc/web/wiklou.git] / includes / LogEventsList.php
index fce4e9c..4bfdc2a 100644 (file)
@@ -39,7 +39,7 @@ class LogEventsList {
                // Precache various messages
                if( !isset( $this->message ) ) {
                        $messages = array( 'revertmerge', 'protect_change', 'unblocklink', 'change-blocklink',
-                               'revertmove', 'undeletelink', 'undeleteviewlink', 'revdel-restore', 'rev-delundel', 'hist', 'diff',
+                               'revertmove', 'undeletelink', 'undeleteviewlink', 'revdel-restore', 'hist', 'diff',
                                'pipe-separator' );
                        foreach( $messages as $msg ) {
                                $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) );
@@ -190,16 +190,16 @@ class LogEventsList {
                // First pass to load the log names
                foreach( $validTypes as $type ) {
                        $text = LogPage::logName( $type );
-                       $typesByName[$text] = $type;
+                       $typesByName[$type] = $text;
                }
 
                // Second pass to sort by name
-               ksort($typesByName);
+               asort($typesByName);
 
                // Note the query type
                $queryType = count($queryTypes) == 1 ? $queryTypes[0] : '';
                // Third pass generates sorted XHTML content
-               foreach( $typesByName as $text => $type ) {
+               foreach( $typesByName as $type => $text ) {
                        $selected = ($type == $queryType);
                        // Restricted types
                        if ( isset($wgLogRestrictions[$type]) ) {
@@ -507,22 +507,24 @@ class LogEventsList {
         * @return string
         */
        private function getShowHideLinks( $row ) {
+               global $wgUser;
+               if( $row->log_type == 'suppress' ) {
+                       return ''; // No one can hide items from the oversight log
+               }
+               $canHide = $wgUser->isAllowed( 'deleterevision' );
                // If event was hidden from sysops
                if( !self::userCan( $row, LogPage::DELETED_RESTRICTED ) ) {
-                       $del = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ),
-                               '(' . $this->message['rev-delundel'] . ')' );
-               } else if( $row->log_type == 'suppress' ) {
-                       $del = ''; // No one should be hiding from the oversight log
+                       $del = $this->skin->revDeleteLinkDisabled( $canHide );
                } else {
                        $target = SpecialPage::getTitleFor( 'Log', $row->log_type );
                        $page = Title::makeTitle( $row->log_namespace, $row->log_title );
                        $query = array(
                                'target' => $target->getPrefixedDBkey(),
-                               'type' => 'logging',
-                               'ids' => $row->log_id,
+                               'type'   => 'logging',
+                               'ids'    => $row->log_id,
                        );
                        $del = $this->skin->revDeleteLink( $query,
-                               self::isDeleted( $row, LogPage::DELETED_RESTRICTED ) );
+                               self::isDeleted( $row, LogPage::DELETED_RESTRICTED ), $canHide );
                }
                return $del;
        }
@@ -607,6 +609,7 @@ class LogEventsList {
         *   that are processed with wgMsgExt and option 'parse'
         * - offset Set to overwrite offset parameter in $wgRequest
         *   set to '' to unset offset
+        * - wrap String: Wrap the message in html (usually something like "<div ...>$1</div>").
         * @return Integer Number of total log items (not limited by $lim)
         */
        public static function showLogExtract( &$out, $types=array(), $page='', $user='', 
@@ -616,7 +619,8 @@ class LogEventsList {
                        'lim' => 25,
                        'conds' => array(),
                        'showIfEmpty' => true,
-                       'msgKey' => array('')
+                       'msgKey' => array(''),
+                       'wrap' => "$1"
                );
        
                # The + operator appends elements of remaining keys from the right
@@ -629,6 +633,7 @@ class LogEventsList {
                $conds = $param['conds'];
                $showIfEmpty = $param['showIfEmpty'];
                $msgKey = $param['msgKey'];
+               $wrap = $param['wrap'];
                if ( !is_array( $msgKey ) )
                        $msgKey = array( $msgKey );
                # Insert list of top 50 (or top $lim) items
@@ -656,7 +661,8 @@ class LogEventsList {
                                 $loglist->endLogEventsList();
                } else {
                        if ( $showIfEmpty )
-                               $s = wfMsgExt( 'logempty', array('parse') );
+                               $s = Html::rawElement( 'div', array( 'class' => 'mw-warning-logempty' ),
+                                       wfMsgExt( 'logempty', array( 'parseinline' ) ) );
                }
                if( $pager->getNumRows() > $pager->mLimit ) { # Show "Full log" link
                        $urlParam = array();
@@ -680,6 +686,11 @@ class LogEventsList {
                if ( $logBody && $msgKey[0] )
                        $s .= '</div>';
 
+               if ( $wrap!='' ) { // Wrap message in html
+                       $s = str_replace( '$1', $s, $wrap );
+               }
+
+               // $out can be either an OutputPage object or a String-by-reference
                if( $out instanceof OutputPage ){
                        $out->addHTML( $s );
                } else {
@@ -788,10 +799,13 @@ class LogPager extends ReverseChronologicalPager {
                $types = ($types === '') ? array() : (array)$types;
                // Don't even show header for private logs; don't recognize it...
                foreach ( $types as $type ) {
-                       if( isset( $wgLogRestrictions[$type] ) && !$wgUser->isAllowed($wgLogRestrictions[$type]) ) {
+                       if( isset( $wgLogRestrictions[$type] )
+                               && !$wgUser->isAllowed($wgLogRestrictions[$type])
+                       ) {
                                $types = array_diff( $types, array( $type ) );
                        }
                }
+               $this->types = $types;
                // Don't show private logs to unprivileged users.
                // Also, only show them upon specific request to avoid suprises.
                $audience = $types ? 'user' : 'public';
@@ -800,7 +814,6 @@ class LogPager extends ReverseChronologicalPager {
                        $this->mConds[] = $hideLogs;
                }
                if( count($types) ) {
-                       $this->types = $types;
                        $this->mConds['log_type'] = $types;
                        // Set typeCGI; used in url param for paging
                        if( count($types) == 1 ) $this->typeCGI = $types[0];
@@ -854,6 +867,8 @@ class LogPager extends ReverseChronologicalPager {
 
                $this->title = $title->getPrefixedText();
                $ns = $title->getNamespace();
+               $db = $this->mDb;
+
                # Using the (log_namespace, log_title, log_timestamp) index with a
                # range scan (LIKE) on the first two parts, instead of simple equality,
                # makes it unusable for sorting.  Sorted retrieval using another index
@@ -866,10 +881,8 @@ class LogPager extends ReverseChronologicalPager {
                # log entries for even the busiest pages, so it can be safely scanned
                # in full to satisfy an impossible condition on user or similar.
                if( $pattern && !$wgMiserMode ) {
-                       # use escapeLike to avoid expensive search patterns like 't%st%'
-                       $safetitle = $this->mDb->escapeLike( $title->getDBkey() );
                        $this->mConds['log_namespace'] = $ns;
-                       $this->mConds[] = "log_title LIKE '$safetitle%'";
+                       $this->mConds[] = 'log_title ' . $db->buildLike( $title->getDBkey(), $db->anyString() );
                        $this->pattern = $pattern;
                } else {
                        $this->mConds['log_namespace'] = $ns;
@@ -877,33 +890,40 @@ class LogPager extends ReverseChronologicalPager {
                }
                // Paranoia: avoid brute force searches (bug 17342)
                if( !$wgUser->isAllowed( 'deletedhistory' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::DELETED_ACTION) . ' = 0';
+                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::DELETED_ACTION) . ' = 0';
                } else if( !$wgUser->isAllowed( 'suppressrevision' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::SUPPRESSED_ACTION) .
+                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::SUPPRESSED_ACTION) .
                                ' != ' . LogPage::SUPPRESSED_ACTION;
                }
        }
 
        public function getQueryInfo() {
+               global $wgOut;
                $tables = array( 'logging', 'user' );
                $this->mConds[] = 'user_id = log_user';
-               $groupBy = false;
+               $index = array();
+               $options = array();
                # Add log_search table if there are conditions on it
                if( array_key_exists('ls_field',$this->mConds) ) {
                        $tables[] = 'log_search';
-                       $index = array( 'log_search' => 'ls_field_val', 'logging' => 'PRIMARY' );
-                       $groupBy = 'ls_log_id';
-               # Don't use the wrong logging index
+                       $index['log_search'] = 'ls_field_val';
+                       $index['logging'] = 'PRIMARY';
+                       $options[] = 'DISTINCT';
+               # Avoid usage of the wrong index by limiting
+               # the choices of available indexes. This mainly
+               # avoids site-breaking filesorts.
                } else if( $this->title || $this->pattern || $this->user ) {
-                       $index = array( 'logging' => array('page_time','user_time') );
-               } else if( $this->types ) {
-                       $index = array( 'logging' => 'type_time' );
+                       $index['logging'] = array( 'page_time', 'user_time' );
+                       if( count($this->types) == 1 ) {
+                               $index['logging'][] = 'log_user_type_time';
+                       }
+               } else if( count($this->types) == 1 ) {
+                       $index['logging'] = 'type_time';
                } else {
-                       $index = array( 'logging' => 'times' );
+                       $index['logging'] = 'times';
                }
-               $options = array( 'USE INDEX' => $index );
+               $options['USE INDEX'] = $index;
                # Don't show duplicate rows when using log_search
-               if( $groupBy ) $options['GROUP BY'] = $groupBy;
                $info = array(
                        'tables'     => $tables,
                        'fields'     => array( 'log_type', 'log_action', 'log_user', 'log_namespace',
@@ -919,7 +939,6 @@ class LogPager extends ReverseChronologicalPager {
                # Add ChangeTags filter query
                ChangeTags::modifyDisplayQuery( $info['tables'], $info['fields'], $info['conds'],
                        $info['join_conds'], $info['options'], $this->mTagFilter );
-
                return $info;
        }