X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=blobdiff_plain;f=includes%2FWatchedItem.php;h=fe9784381e2b0b34b6a56c1143767ea6dcb4ceeb;hb=0fe6aaf91cb481a5b946bb32aad8b10dd4ab4490;hp=45aa82266e681b7598210e3639b0b0233c287522;hpb=7636bea2bf3ccc33389a97d968bdda64036f59c0;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php index 45aa82266e..fe9784381e 100644 --- a/includes/WatchedItem.php +++ b/includes/WatchedItem.php @@ -27,19 +27,37 @@ * @ingroup Watchlist */ class WatchedItem { - var $mTitle, $mUser; + /** + * Constant to specify that user rights 'editmywatchlist' and + * 'viewmywatchlist' should not be checked. + * @since 1.22 + */ + const IGNORE_USER_RIGHTS = 0; + + /** + * Constant to specify that user rights 'editmywatchlist' and + * 'viewmywatchlist' should be checked. + * @since 1.22 + */ + const CHECK_USER_RIGHTS = 1; + + var $mTitle, $mUser, $mCheckRights; private $loaded = false, $watched, $timestamp; /** * Create a WatchedItem object with the given user and title + * @since 1.22 $checkRights parameter added * @param $user User: the user to use for (un)watching * @param $title Title: the title we're going to (un)watch + * @param $checkRights int: Whether to check the 'viewmywatchlist' and 'editmywatchlist' rights. + * Pass either WatchedItem::IGNORE_USER_RIGHTS or WatchedItem::CHECK_USER_RIGHTS. * @return WatchedItem object */ - public static function fromUserTitle( $user, $title ) { + public static function fromUserTitle( $user, $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) { $wl = new WatchedItem; $wl->mUser = $user; $wl->mTitle = $title; + $wl->mCheckRights = $checkRights; return $wl; } @@ -95,6 +113,12 @@ class WatchedItem { return; } + // some pages cannot be watched + if ( !$this->getTitle()->isWatchable() ) { + $this->watched = false; + return; + } + # Pages and their talk pages are considered equivalent for watching; # remember that talk namespaces are numbered as page namespace+1. @@ -110,11 +134,23 @@ class WatchedItem { } } + /** + * Check permissions + * @param $what string: 'viewmywatchlist' or 'editmywatchlist' + */ + private function isAllowed( $what ) { + return !$this->mCheckRights || $this->mUser->isAllowed( $what ); + } + /** * Is mTitle being watched by mUser? * @return bool */ public function isWatched() { + if ( !$this->isAllowed( 'viewmywatchlist' ) ) { + return false; + } + $this->load(); return $this->watched; } @@ -126,6 +162,10 @@ class WatchedItem { * the wl_notificationtimestamp field otherwise */ public function getNotificationTimestamp() { + if ( !$this->isAllowed( 'viewmywatchlist' ) ) { + return false; + } + $this->load(); if ( $this->watched ) { return $this->timestamp; @@ -139,10 +179,11 @@ class WatchedItem { * * @param $force Whether to force the write query to be executed even if the * page is not watched or the notification timestamp is already NULL. + * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed. */ - public function resetNotificationTimestamp( $force = '' ) { + public function resetNotificationTimestamp( $force = '', $oldid = 0 ) { // Only loggedin user can have a watchlist - if ( wfReadOnly() || $this->mUser->isAnon() ) { + if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) { return; } @@ -153,10 +194,50 @@ class WatchedItem { } } + $title = $this->getTitle(); + if ( !$oldid ) { + // No oldid given, assuming latest revision; clear the timestamp. + $notificationTimestamp = null; + } elseif ( !$title->getNextRevisionID( $oldid ) ) { + // Oldid given and is the latest revision for this title; clear the timestamp. + $notificationTimestamp = null; + } else { + // See if the version marked as read is more recent than the one we're viewing. + // Call load() if it wasn't called before due to $force. + $this->load(); + + if ( $this->timestamp === null ) { + // This can only happen if $force is enabled. + $notificationTimestamp = null; + } else { + // Oldid given and isn't the latest; update the timestamp. + // This will result in no further notification emails being sent! + $dbr = wfGetDB( DB_SLAVE ); + $notificationTimestamp = $dbr->selectField( + 'revision', 'rev_timestamp', + array( 'rev_page' => $title->getArticleID(), 'rev_id' => $oldid ) + ); + // We need to go one second to the future because of various strict comparisons + // throughout the codebase + $ts = new MWTimestamp( $notificationTimestamp ); + $ts->timestamp->add( new DateInterval( 'PT1S' ) ); + $notificationTimestamp = $ts->getTimestamp( TS_MW ); + + if ( $notificationTimestamp < $this->timestamp ) { + if ( $force != 'force' ) { + return; + } else { + // This is a little silly… + $notificationTimestamp = $this->timestamp; + } + } + } + } + // If the page is watched by the user (or may be watched), update the timestamp on any // any matching rows $dbw = wfGetDB( DB_MASTER ); - $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => null ), + $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => $notificationTimestamp ), $this->dbCond(), __METHOD__ ); $this->timestamp = null; } @@ -170,7 +251,7 @@ class WatchedItem { wfProfileIn( __METHOD__ ); // Only loggedin user can have a watchlist - if ( wfReadOnly() || $this->mUser->isAnon() ) { + if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) { wfProfileOut( __METHOD__ ); return false; } @@ -210,7 +291,7 @@ class WatchedItem { wfProfileIn( __METHOD__ ); // Only loggedin user can have a watchlist - if ( wfReadOnly() || $this->mUser->isAnon() ) { + if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) { wfProfileOut( __METHOD__ ); return false; }