* Add isSingleRevRedirect(). Refactor isValidMoveTarget() with this.
authorAaron Schulz <aaron@users.mediawiki.org>
Sat, 8 Nov 2008 19:31:08 +0000 (19:31 +0000)
committerAaron Schulz <aaron@users.mediawiki.org>
Sat, 8 Nov 2008 19:31:08 +0000 (19:31 +0000)
* Add getNotificationTimestamp() function

includes/Title.php

index e3e702d..0e493cf 100644 (file)
@@ -68,6 +68,7 @@ class Title {
        var $mWatched = null;             ///< Is $wgUser watching this page? null if unfilled, accessed through userIsWatching()
        var $mLength = -1;                ///< The page length, 0 for special pages
        var $mRedirect = null;            ///< Is the article at this title a redirect?
+       var $mNotificationTimestamp = array(); ///< Associative array of ID -> timestamp/NULL
        //@}
 
 
@@ -2840,6 +2841,48 @@ class Title {
                $this->purgeSquid();
                
        }
+       
+       /**
+        * Checks if this page is just a one-rev redirect.
+        * Adds lock, so don't use just for light purposes.
+        *
+        * @param $curId \type{int} page ID, optional
+        * @return \type{\bool} TRUE or FALSE
+        */
+       public function isSingleRevRedirect( $curId = 0 ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $curId = $curId ? $curId : $this->getArticleId();
+               # Nothing here?
+               if( !$curId ) {
+                       return true;
+               }
+               # Is it a redirect?
+               $row = $dbw->selectRow( 'page',
+                       array( 'page_is_redirect', 'page_latest' ),
+                       array( 'page_id' => $curId ),
+                       __METHOD__,
+                       'FOR UPDATE'
+               );
+               # Cache some fields we may want
+               $this->mRedirect = $row ? (bool)$row->page_is_redirect : false;
+               $this->mLatestID = $row ? intval($row->page_latest) : false;
+               if( $this->mRedirect ) {
+                       return false;
+               }
+               # Does the article have a history?
+               $row = $dbw->selectField( array( 'page', 'revision'),
+                       'rev_id',
+                       array( 'page_namespace' => $this->getNamespace(),
+                               'page_title' => $this->getDBkey(),
+                               'page_id=rev_page',
+                               'page_latest != rev_id'
+                       ), 
+                       __METHOD__,
+                       'FOR UPDATE'
+               );
+               # Return true if there was no history
+               return ($row === false);
+       }
 
        /**
         * Checks if $this can be moved to a given Title
@@ -2849,10 +2892,7 @@ class Title {
         * @return \type{\bool} TRUE or FALSE
         */
        public function isValidMoveTarget( $nt ) {
-
-               $fname = 'Title::isValidMoveTarget';
                $dbw = wfGetDB( DB_MASTER );
-
                # Is it an existsing file?
                if( $nt->getNamespace() == NS_IMAGE ) {
                        $file = wfLocalFile( $nt );
@@ -2861,21 +2901,14 @@ class Title {
                                return false;
                        }
                }
-
-               # Is it a redirect?
-               $id  = $nt->getArticleID();
-               $obj = $dbw->selectRow( array( 'page', 'revision', 'text'),
-                       array( 'page_is_redirect','old_text','old_flags' ),
-                       array( 'page_id' => $id, 'page_latest=rev_id', 'rev_text_id=old_id' ),
-                       $fname, 'FOR UPDATE' );
-
-               if ( !$obj || 0 == $obj->page_is_redirect ) {
-                       # Not a redirect
-                       wfDebug( __METHOD__ . ": not a redirect\n" );
+               # Is it a redirect with no history?
+               if( !$nt->isSingleRevRedirect() ) {
+                       wfDebug( __METHOD__ . ": not a one-rev redirect\n" );
                        return false;
                }
-               $text = Revision::getRevisionText( $obj );
-
+               # Get the article text
+               $rev = Revision::newFromTitle( $nt );
+               $text = $rev->getText();
                # Does the redirect point to the source?
                # Or is it a broken self-redirect, usually caused by namespace collisions?
                $m = array();
@@ -2892,18 +2925,7 @@ class Title {
                        wfDebug( __METHOD__ . ": failsafe\n" );
                        return false;
                }
-
-               # Does the article have a history?
-               $row = $dbw->selectRow( array( 'page', 'revision'),
-                       array( 'rev_id' ),
-                       array( 'page_namespace' => $nt->getNamespace(),
-                               'page_title' => $nt->getDBkey(),
-                               'page_id=rev_page AND page_latest != rev_id'
-                       ), $fname, 'FOR UPDATE'
-               );
-
-               # Return true if there was no history
-               return $row === false;
+               return true;
        }
 
        /**
@@ -3150,6 +3172,39 @@ class Title {
                return $touched;
        }
 
+       /**
+        * Get the timestamp when this page was updated since the user last saw it.
+        * @param User $user
+        * @return mixed string/NULL
+        */
+       public function getNotificationTimestamp( $user = NULL ) {
+               global $wgUser, $wgShowUpdatedMarker;
+               // Assume current user if none given
+               if( !$user ) $user = $wgUser;
+               // Check cache first
+               $uid = $user->getId();
+               if( isset($this->mNotificationTimestamp[$uid]) ) {
+                       return $this->mNotificationTimestamp[$uid];
+               }
+               if( !$uid || !$wgShowUpdatedMarker ) {
+                       return $this->mNotificationTimestamp[$uid] = false;
+               }
+               // Don't cache too much!
+               if( count($this->mNotificationTimestamp) >= self::CACHE_MAX ) {
+                       $this->mNotificationTimestamp = array();
+               }
+               $dbr = wfGetDB( DB_SLAVE );
+               $this->mNotificationTimestamp[$uid] = $dbr->selectField( 'watchlist',
+                       'wl_notificationtimestamp',
+                       array( 'wl_namespace' => $this->getNamespace(),
+                               'wl_title' => $this->getDBkey(),
+                               'wl_user' => $user->getId()
+                       ),
+                       __METHOD__
+               );
+               return $this->mNotificationTimestamp[$uid];
+       }
+
        /**
         * Get the trackback URL for this page
         * @return \type{\string} Trackback URL