The return of the validation feature (caveat: new table scheme!)
[lhc/web/wiklou.git] / includes / SpecialLog.php
index f2fda40..76cfd5e 100644 (file)
 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 # http://www.gnu.org/copyleft/gpl.html
 
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
+
+/**
+ * constructor
+ */
 function wfSpecialLog( $par = '' ) {
        global $wgRequest;
        $logReader =& new LogReader( $wgRequest );
@@ -25,22 +34,34 @@ function wfSpecialLog( $par = '' ) {
        }
        $logViewer =& new LogViewer( $logReader );
        $logViewer->show();
-       $logReader->cleanUp();
 }
 
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
 class LogReader {
        var $db, $joinClauses, $whereClauses;
        var $type = '', $user = '', $title = null;
        
+       /**
+        * @param WebRequest $request For internal use use a FauxRequest object to pass arbitrary parameters.
+        */
        function LogReader( $request ) {
                $this->db =& wfGetDB( DB_SLAVE );
                $this->setupQuery( $request );
        }
        
+       /**
+        * Basic setup and applies the limiting factors from the WebRequest object.
+        * @param WebRequest $request
+        * @private
+        */
        function setupQuery( $request ) {
-               $cur = $this->db->tableName( 'cur' );
+               $page = $this->db->tableName( 'page' );
                $user = $this->db->tableName( 'user' );
-               $this->joinClauses = array( "LEFT OUTER JOIN $cur ON log_namespace=cur_namespace AND log_title=cur_title" );
+               $this->joinClauses = array( "LEFT OUTER JOIN $page ON log_namespace=page_namespace AND log_title=page_title" );
                $this->whereClauses = array( 'user_id=log_user' );
                
                $this->limitType( $request->getVal( 'type' ) );
@@ -52,6 +73,11 @@ class LogReader {
                list( $this->limit, $this->offset ) = $request->getLimitOffset();
        }
        
+       /**
+        * Set the log reader to return only entries of the given type.
+        * @param string $type A log type ('upload', 'delete', etc)
+        * @private
+        */
        function limitType( $type ) {
                if( empty( $type ) ) {
                        return false;
@@ -61,8 +87,13 @@ class LogReader {
                $this->whereClauses[] = "log_type='$safetype'";
        }
        
+       /**
+        * Set the log reader to return only entries by the given user.
+        * @param string $name Valid user name
+        * @private
+        */
        function limitUser( $name ) {
-               $title = Title::makeTitleSafe( NS_USER, $name );
+               $title = Title::makeTitle( NS_USER, $name );
                if( empty( $name ) || is_null( $title ) ) {
                        return false;
                }
@@ -72,6 +103,12 @@ class LogReader {
                $this->whereClauses[] = "user_name='$safename'";
        }
        
+       /**
+        * Set the log reader to return only entries affecting the given page.
+        * (For the block and rights logs, this is a user page.)
+        * @param string $page Title name as text
+        * @private
+        */
        function limitTitle( $page ) {
                $title = Title::newFromText( $page );
                if( empty( $page ) || is_null( $title )  ) {
@@ -83,6 +120,12 @@ class LogReader {
                $this->whereClauses[] = "log_namespace=$ns AND log_title='$safetitle'";
        }
        
+       /**
+        * Set the log reader to return only entries in a given time range.
+        * @param string $time Timestamp of one endpoint
+        * @param string $direction either ">=" or "<=" operators
+        * @private
+        */
        function limitTime( $time, $direction ) {
                # Direction should be a comparison operator
                if( empty( $time ) ) {
@@ -92,13 +135,18 @@ class LogReader {
                $this->whereClauses[] = "log_timestamp $direction '$safetime'";
        }
        
+       /**
+        * Build an SQL query from all the set parameters.
+        * @return string the SQL query
+        * @private
+        */
        function getQuery() {
                $logging = $this->db->tableName( "logging" );
                $user = $this->db->tableName( 'user' );
                $sql = "SELECT log_type, log_action, log_timestamp,
                        log_user, user_name,
-                       log_namespace, log_title, cur_id,
-                       log_comment FROM $logging, $user ";
+                       log_namespace, log_title, page_id,
+                       log_comment, log_params FROM $user, $logging ";
                if( !empty( $this->joinClauses ) ) {
                        $sql .= implode( ',', $this->joinClauses );
                }
@@ -110,26 +158,31 @@ class LogReader {
                return $sql;
        }
        
-       function initQuery() {
-               $this->result = $this->db->query( $this->getQuery() );
-       }
-       
-       function fetchObject() {
-               return $this->db->fetchObject( $this->result );
-       }
-       
-       function cleanUp() {
-               $this->db->freeResult( $this->result );
+       /**
+        * Execute the query and start returning results.
+        * @return ResultWrapper result object to return the relevant rows
+        */
+       function getRows() {
+               return $this->db->resultObject( $this->db->query( $this->getQuery() ) );
        }
        
+       /**
+        * @return string The query type that this LogReader has been limited to.
+        */
        function queryType() {
                return $this->type;
        }
        
+       /**
+        * @return string The username type that this LogReader has been limited to, if any.
+        */
        function queryUser() {
                return $this->user;
        }
        
+       /**
+        * @return string The text of the title that this LogReader has been limited to.
+        */
        function queryTitle() {
                if( is_null( $this->title ) ) {
                        return '';
@@ -139,76 +192,95 @@ class LogReader {
        }
 }
 
+/**
+ *
+ * @package MediaWiki
+ * @subpackage SpecialPage
+ */
 class LogViewer {
-       var $reader, $skin;
-       var $typeText = array(
-               ''        => array( 'log',            'alllogstext'       ),
-               'block'   => array( 'blocklogpage',   'blocklogtext'      ),
-               'protect' => array( 'protectlogpage', 'protectlogtext'    ),
-               'rights'  => array( 'bureaucratlog',  ''                  ),
-               'delete'  => array( 'dellogpage',     'dellogpagetext'    ),
-               'upload'  => array( 'uploadlogpage',  'uploadlogpagetext' )
-       );
-
+       /**
+        * @var LogReader $reader
+        */
+       var $reader;
        
+       /**
+        * @param LogReader &$reader where to get our data from
+        */
        function LogViewer( &$reader ) {
                global $wgUser;
                $this->skin =& $wgUser->getSkin();
                $this->reader =& $reader;
        }
        
+       /**
+        * Take over the whole output page in $wgOut with the log display.
+        */
        function show() {
                global $wgOut;
                $this->showHeader( $wgOut );
                $this->showOptions( $wgOut );
                $this->showPrevNext( $wgOut );
-               $out = "";
-               $this->reader->initQuery();
-               while( $s = $this->reader->fetchObject() ) {
-                       $out .= $this->logLine( $s );
-               }
-               $wgOut->addHTML( $out );
+               $this->showList( $wgOut );
                $this->showPrevNext( $wgOut );
        }
        
-       # wfMsg( unprotectedarticle, $text )
-       # wfMsg( 'protectedarticle', $text )
-       # wfMsg( 'deletedarticle', $text )
-       # wfMsg( 'uploadedimage', $text )
-       # wfMsg( "blocklogentry", $this->BlockAddress, $this->BlockExpiry );
-       # wfMsg( "bureaucratlogentry", $this->mUser, implode( " ", $rightsNotation ) );
-       # wfMsg( "undeletedarticle", $this->mTarget ),
+       /**
+        * Output just the list of entries given by the linked LogReader,
+        * with extraneous UI elements. Use for displaying log fragments in
+        * another page (eg at Special:Undelete)
+        * @param OutputPage $out where to send output
+        */
+       function showList( &$out ) {
+               $html = "\n<ul>\n";
+               $result = $this->reader->getRows();
+               while( $s = $result->fetchObject() ) {
+                       $html .= $this->logLine( $s );
+               }
+               $result->free();
+               $html .= "\n</ul>\n";
+               $out->addHTML( $html );
+       }
+       
+       /**
+        * @param Object $s a single row from the result set
+        * @return string Formatted HTML list item
+        * @private
+        */
        function logLine( $s ) {
                global $wgLang;
                $title = Title::makeTitle( $s->log_namespace, $s->log_title );
                $user = Title::makeTitleSafe( NS_USER, $s->user_name );
-               $time = $wgLang->timeanddate( $s->log_timestamp );
-               if( $s->cur_id ) {
+               $time = $wgLang->timeanddate( $s->log_timestamp, true );
+               if( $s->page_id ) {
                        $titleLink = $this->skin->makeKnownLinkObj( $title );
                } else {
                        $titleLink = $this->skin->makeBrokenLinkObj( $title );
                }
                $userLink = $this->skin->makeLinkObj( $user, htmlspecialchars( $s->user_name ) );
-               if( '' === $s->log_comment ) {
-                       $comment = '';
-               } else {
-                       $comment = '(<em>' . $this->skin->formatComment( $s->log_comment ) . '</em>)';
-               }
+               $comment = $this->skin->commentBlock( $s->log_comment );
+               $paramArray = LogPage::extractParams( $s->log_params );
                
-               $action = LogPage::actionText( $s->log_type, $s->log_action, $titleLink );
+               $action = LogPage::actionText( $s->log_type, $s->log_action, $titleLink, $paramArray );
                $out = "<li>$time $userLink $action $comment</li>\n";
                return $out;
        }
        
+       /**
+        * @param OutputPage &$out where to send output
+        * @private
+        */
        function showHeader( &$out ) {
                $type = $this->reader->queryType();
-               if( isset( $this->typeText[$type] ) ) {
-                       list( $title, $headertext ) = $this->typeText[$type];
-                       $out->setPageTitle( str_replace( '_', ' ', wfMsg( $title ) ) );
-                       $out->addWikiText( wfMsg( $headertext ) );
+               if( LogPage::isLogType( $type ) ) {
+                       $out->setPageTitle( LogPage::logName( $type ) );
+                       $out->addWikiText( LogPage::logHeader( $type ) );
                }
        }
        
+       /**
+        * @param OutputPage &$out where to send output
+        * @private
+        */
        function showOptions( &$out ) {
                global $wgScript;
                $action = htmlspecialchars( $wgScript );
@@ -223,10 +295,14 @@ class LogViewer {
                        "</form>" );
        }
        
+       /**
+        * @return string Formatted HTML
+        * @private
+        */
        function getTypeMenu() {
                $out = "<select name='type'>\n";
-               foreach( $this->typeText as $type => $msg ) {
-                       $text = htmlspecialchars( str_replace( '_', ' ', wfMsg( $msg[0] ) ) );
+               foreach( LogPage::validTypes() as $type ) {
+                       $text = htmlspecialchars( LogPage::logName( $type ) );
                        $selected = ($type == $this->reader->queryType()) ? ' selected="selected"' : '';
                        $out .= "<option value=\"$type\"$selected>$text</option>\n";
                }
@@ -234,29 +310,41 @@ class LogViewer {
                return $out;
        }
        
+       /**
+        * @return string Formatted HTML
+        * @private
+        */
        function getUserInput() {
                $user = htmlspecialchars( $this->reader->queryUser() );
-               return "User: <input type='text' name='user' size='12' value=\"$user\" />\n";
+               return wfMsg('specialloguserlabel') . "<input type='text' name='user' size='12' value=\"$user\" />\n";
        }
        
+       /**
+        * @return string Formatted HTML
+        * @private
+        */
        function getTitleInput() {
                $title = htmlspecialchars( $this->reader->queryTitle() );
-               return "Title: <input type='text' name='page' size='20' value=\"$title\" />\n";
+               return wfMsg('speciallogtitlelabel') . "<input type='text' name='page' size='20' value=\"$title\" />\n";
        }
        
+       /**
+        * @param OutputPage &$out where to send output
+        * @private
+        */
        function showPrevNext( &$out ) {
-               global $wgLang;
+               global $wgContLang,$wgRequest;
                $pieces = array();
                $pieces[] = 'type=' . htmlspecialchars( $this->reader->queryType() );
                $pieces[] = 'user=' . htmlspecialchars( $this->reader->queryUser() );
                $pieces[] = 'page=' . htmlspecialchars( $this->reader->queryTitle() );
                $bits = implode( '&', $pieces );
-               $offset = 0; $limit = 50;
+               list( $limit, $offset ) = $wgRequest->getLimitOffset();
                
                # TODO: use timestamps instead of offsets to make it more natural
                # to go huge distances in time
                $html = wfViewPrevNext( $offset, $limit,
-                       $wgLang->specialpage( 'Log' ),
+                       $wgContLang->specialpage( 'Log' ),
                        $bits,
                        false);
                $out->addHTML( '<p>' . $html . '</p>' );
@@ -264,4 +352,4 @@ class LogViewer {
 }
 
 
-?>
\ No newline at end of file
+?>