Merge "Added ORMIterator interface which can be used for type hinting (in particular...
[lhc/web/wiklou.git] / includes / actions / HistoryAction.php
index 29b4eb9..50d210f 100644 (file)
@@ -3,6 +3,22 @@
  * Page history
  *
  * Split off from Article.php and Skin.php, 2003-12-22
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
  * @file
  */
 
@@ -69,10 +85,9 @@ class HistoryAction extends FormlessAction {
 
        /**
         * Print the history page for an article.
-        * @return nothing
         */
        function onView() {
-               global $wgScript, $wgUseFileCache, $wgSquidMaxage;
+               global $wgScript, $wgUseFileCache;
 
                $out = $this->getOutput();
                $request = $this->getRequest();
@@ -86,10 +101,6 @@ class HistoryAction extends FormlessAction {
 
                wfProfileIn( __METHOD__ );
 
-               if ( $request->getFullRequestURL() == $this->getTitle()->getInternalURL( 'action=history' ) ) {
-                       $out->setSquidMaxage( $wgSquidMaxage );
-               }
-
                $this->preCacheMessages();
 
                # Fill in the file cache if not set already
@@ -107,12 +118,13 @@ class HistoryAction extends FormlessAction {
                // Handle atom/RSS feeds.
                $feedType = $request->getVal( 'feed' );
                if ( $feedType ) {
+                       $this->feed( $feedType );
                        wfProfileOut( __METHOD__ );
-                       return $this->feed( $feedType );
+                       return;
                }
 
                // Fail nicely if article doesn't exist.
-               if ( !$this->getTitle()->exists() ) {
+               if ( !$this->page->exists() ) {
                        $out->addWikiMsg( 'nohistory' );
                        # show deletion/move log if there is an entry
                        LogEventsList::showLogExtract(
@@ -136,13 +148,7 @@ class HistoryAction extends FormlessAction {
                $year        = $request->getInt( 'year' );
                $month       = $request->getInt( 'month' );
                $tagFilter   = $request->getVal( 'tagfilter' );
-               $tagFilterDropdown = $request->getVal( 'tagfilterdropdown' );
-               $tagSelector = ChangeTags::buildTagFilterWithDropdown(
-                       'tag-filter-dropdown-list',
-                       $tagFilter,
-                       $tagFilterDropdown
-               );
-               $tagSelector = implode( ' ', $tagSelector );
+               $tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter );
 
                /**
                 * Option to show only revisions that have been (partially) hidden via RevisionDelete
@@ -167,26 +173,14 @@ class HistoryAction extends FormlessAction {
                        Html::hidden( 'title', $this->getTitle()->getPrefixedDBKey() ) . "\n" .
                        Html::hidden( 'action', 'history' ) . "\n" .
                        Xml::dateMenu( $year, $month ) . ' ' .
-                       Html::rawElement(
-                               'span',
-                               array( 'style' => 'white-space: nowrap' ),
-                               ( $tagSelector ? ( $tagSelector . ' ' ) : '' )
-                       ) .
-                       Html::rawElement(
-                               'span',
-                               array( 'style' => 'white-space: nowrap' ),
-                               $checkDeleted
-                       ) .
+                       ( $tagSelector ? ( implode( ' ', $tagSelector ) . ' ' ) : '' ) .
+                       $checkDeleted .
                        Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" .
                        '</fieldset></form>'
                );
 
                wfRunHooks( 'PageHistoryBeforeList', array( &$this->page ) );
 
-               if ( $tagFilterDropdown !== '' && $tagFilterDropdown !== 'other' ) {
-                       $tagFilter = $tagFilterDropdown;
-               }
-
                // Create and output the list.
                $pager = new HistoryPager( $this, $year, $month, $tagFilter, $conds );
                $out->addHTML(
@@ -210,6 +204,11 @@ class HistoryAction extends FormlessAction {
         * @return ResultWrapper
         */
        function fetchRevisions( $limit, $offset, $direction ) {
+               // Fail if article doesn't exist.
+               if( !$this->getTitle()->exists() ) {
+                       return new FakeResultWrapper( array() );
+               }
+
                $dbr = wfGetDB( DB_SLAVE );
 
                if ( $direction == HistoryPage::DIR_PREV ) {
@@ -224,7 +223,7 @@ class HistoryAction extends FormlessAction {
                        $offsets = array();
                }
 
-               $page_id = $this->getTitle()->getArticleID();
+               $page_id = $this->page->getId();
 
                return $dbr->select( 'revision',
                        Revision::selectFields(),
@@ -334,6 +333,10 @@ class HistoryPager extends ReverseChronologicalPager {
        public $lastRow = false, $counter, $historyPage, $buttons, $conds;
        protected $oldIdChecked;
        protected $preventClickjacking = false;
+       /**
+        * @var array
+        */
+       protected $parentLens;
 
        function __construct( $historyPage, $year = '', $month = '', $tagFilter = '', $conds = array() ) {
                parent::__construct( $historyPage->getContext() );
@@ -361,7 +364,7 @@ class HistoryPager extends ReverseChronologicalPager {
                        'tables'  => array( 'revision', 'user' ),
                        'fields'  => array_merge( Revision::selectFields(), Revision::selectUserFields() ),
                        'conds'   => array_merge(
-                               array( 'rev_page' => $this->getTitle()->getArticleID() ),
+                               array( 'rev_page' => $this->getWikiPage()->getId() ),
                                $this->conds ),
                        'options' => array( 'USE INDEX' => array( 'revision' => 'page_timestamp' ) ),
                        'join_conds' => array(
@@ -402,14 +405,47 @@ class HistoryPager extends ReverseChronologicalPager {
                # Do a link batch query
                $this->mResult->seek( 0 );
                $batch = new LinkBatch();
+               $revIds = array();
                foreach ( $this->mResult as $row ) {
-                       $batch->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) );
-                       $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) );
+                       if( $row->rev_parent_id ) {
+                               $revIds[] = $row->rev_parent_id;
+                       }
+                       if( !is_null( $row->user_name ) ) {
+                               $batch->add( NS_USER, $row->user_name );
+                               $batch->add( NS_USER_TALK, $row->user_name );
+                       } else { # for anons or usernames of imported revisions
+                               $batch->add( NS_USER, $row->rev_user_text );
+                               $batch->add( NS_USER_TALK, $row->rev_user_text );
+                       }
                }
+               $this->parentLens = $this->getParentLengths( $revIds );
                $batch->execute();
                $this->mResult->seek( 0 );
        }
 
+       /**
+        * Do a batched query to get the parent revision lengths
+        * @param $revIds array
+        * @return array
+        * @TODO: stolen from Contributions, refactor
+        */
+       private function getParentLengths( array $revIds ) {
+               $revLens = array();
+               if ( !$revIds ) {
+                       return $revLens; // empty
+               }
+               wfProfileIn( __METHOD__ );
+               $res = $this->mDb->select( 'revision',
+                       array( 'rev_id', 'rev_len' ),
+                       array( 'rev_id' => $revIds ),
+                       __METHOD__ );
+               foreach ( $res as $row ) {
+                       $revLens[$row->rev_id] = $row->rev_len;
+               }
+               wfProfileOut( __METHOD__ );
+               return $revLens;
+       }
+
        /**
         * Creates begin of history list with a submit button
         *
@@ -536,7 +572,7 @@ class HistoryPager extends ReverseChronologicalPager {
                $histLinks = Html::rawElement(
                                'span',
                                array( 'class' => 'mw-history-histlinks' ),
-                               '(' . $curlink . $this->historyPage->message['pipe-separator'] . $lastlink . ') '
+                               $this->msg( 'parentheses' )->rawParams( $curlink . $this->historyPage->message['pipe-separator'] . $lastlink )->escaped()
                );
                $s = $histLinks . $diffButtons;
 
@@ -586,18 +622,19 @@ class HistoryPager extends ReverseChronologicalPager {
                        $s .= ' ' . ChangesList::flag( 'minor' );
                }
 
-               if ( $prevRev
-                       && !$prevRev->isDeleted( Revision::DELETED_TEXT )
-                       && !$rev->isDeleted( Revision::DELETED_TEXT ) )
-               {
-                       $sDiff = ChangesList::showCharacterDifference( $prevRev->getSize(), $rev->getSize() );
-                       $s .= ' . . ' . $sDiff . ' . . ';
-               }
+               # Size is always public data
+               $prevSize = isset( $this->parentLens[$row->rev_parent_id] )
+                       ? $this->parentLens[$row->rev_parent_id]
+                       : 0;
+               $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
+               $fSize = Linker::formatRevisionSize($rev->getSize());
+               $s .= " . . $fSize $sDiff";
 
-               $s .= Linker::revComment( $rev, false, true );
+               # Text following the character difference is added just before running hooks
+               $s2 = Linker::revComment( $rev, false, true );
 
                if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
-                       $s .= ' <span class="updatedmarker">' .  $this->msg( 'updatedmarker' )->escaped() . '</span>';
+                       $s2 .= ' <span class="updatedmarker">' .  $this->msg( 'updatedmarker' )->escaped() . '</span>';
                }
 
                $tools = array();
@@ -634,13 +671,20 @@ class HistoryPager extends ReverseChronologicalPager {
                }
 
                if ( $tools ) {
-                       $s .= ' (' . $lang->pipeList( $tools ) . ')';
+                       $s2 .= ' '. $this->msg( 'parentheses' )->rawParams( $lang->pipeList( $tools ) )->escaped();
                }
 
                # Tags
                list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( $row->ts_tags, 'history' );
                $classes = array_merge( $classes, $newClasses );
-               $s .= " $tagSummary";
+               if ( $tagSummary !== '' ) {
+                       $s2 .= " $tagSummary";
+               }
+
+               # Include separator between character difference and following text
+               if ( $s2 !== '' ) {
+                       $s .= " . . $s2";
+               }
 
                wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row , &$s, &$classes ) );
 
@@ -694,7 +738,7 @@ class HistoryPager extends ReverseChronologicalPager {
                                $cur,
                                array(),
                                array(
-                                       'diff' => $this->getTitle()->getLatestRevID(),
+                                       'diff' => $this->getWikiPage()->getLatest(),
                                        'oldid' => $rev->getId()
                                )
                        );
@@ -800,6 +844,7 @@ class HistoryPager extends ReverseChronologicalPager {
 
        /**
         * Get the "prevent clickjacking" flag
+        * @return bool
         */
        function getPreventClickjacking() {
                return $this->preventClickjacking;