MediaWiki  REL1_19
WatchedItem.php
Go to the documentation of this file.
00001 <?php
00010 class WatchedItem {
00011         var $mTitle, $mUser, $id, $ns, $ti;
00012 
00019         public static function fromUserTitle( $user, $title ) {
00020                 $wl = new WatchedItem;
00021                 $wl->mUser = $user;
00022                 $wl->mTitle = $title;
00023                 $wl->id = $user->getId();
00024                 # Patch (also) for email notification on page changes T.Gries/M.Arndt 11.09.2004
00025                 # TG patch: here we do not consider pages and their talk pages equivalent - why should we ?
00026                 # The change results in talk-pages not automatically included in watchlists, when their parent page is included
00027                 # $wl->ns = $title->getNamespace() & ~1;
00028                 $wl->ns = $title->getNamespace();
00029 
00030                 $wl->ti = $title->getDBkey();
00031                 return $wl;
00032         }
00033 
00038         public function isWatched() {
00039                 # Pages and their talk pages are considered equivalent for watching;
00040                 # remember that talk namespaces are numbered as page namespace+1.
00041 
00042                 $dbr = wfGetDB( DB_SLAVE );
00043                 $res = $dbr->select( 'watchlist', 1, array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns,
00044                         'wl_title' => $this->ti ), __METHOD__ );
00045                 $iswatched = ($dbr->numRows( $res ) > 0) ? 1 : 0;
00046                 return $iswatched;
00047         }
00048 
00054         public function addWatch() {
00055                 wfProfileIn( __METHOD__ );
00056 
00057                 // Use INSERT IGNORE to avoid overwriting the notification timestamp
00058                 // if there's already an entry for this page
00059                 $dbw = wfGetDB( DB_MASTER );
00060                 $dbw->insert( 'watchlist',
00061                   array(
00062                         'wl_user' => $this->id,
00063                         'wl_namespace' => MWNamespace::getSubject($this->ns),
00064                         'wl_title' => $this->ti,
00065                         'wl_notificationtimestamp' => null
00066                   ), __METHOD__, 'IGNORE' );
00067 
00068                 // Every single watched page needs now to be listed in watchlist;
00069                 // namespace:page and namespace_talk:page need separate entries:
00070                 $dbw->insert( 'watchlist',
00071                   array(
00072                         'wl_user' => $this->id,
00073                         'wl_namespace' => MWNamespace::getTalk($this->ns),
00074                         'wl_title' => $this->ti,
00075                         'wl_notificationtimestamp' => null
00076                   ), __METHOD__, 'IGNORE' );
00077 
00078                 wfProfileOut( __METHOD__ );
00079                 return true;
00080         }
00081 
00086         public function removeWatch() {
00087                 wfProfileIn( __METHOD__ );
00088 
00089                 $success = false;
00090                 $dbw = wfGetDB( DB_MASTER );
00091                 $dbw->delete( 'watchlist',
00092                         array(
00093                                 'wl_user' => $this->id,
00094                                 'wl_namespace' => MWNamespace::getSubject($this->ns),
00095                                 'wl_title' => $this->ti
00096                         ), __METHOD__
00097                 );
00098                 if ( $dbw->affectedRows() ) {
00099                         $success = true;
00100                 }
00101 
00102                 # the following code compensates the new behaviour, introduced by the
00103                 # enotif patch, that every single watched page needs now to be listed
00104                 # in watchlist namespace:page and namespace_talk:page had separate
00105                 # entries: clear them
00106                 $dbw->delete( 'watchlist',
00107                         array(
00108                                 'wl_user' => $this->id,
00109                                 'wl_namespace' => MWNamespace::getTalk($this->ns),
00110                                 'wl_title' => $this->ti
00111                         ), __METHOD__
00112                 );
00113 
00114                 if ( $dbw->affectedRows() ) {
00115                         $success = true;
00116                 }
00117 
00118                 wfProfileOut( __METHOD__ );
00119                 return $success;
00120         }
00121 
00129         public static function duplicateEntries( $ot, $nt ) {
00130                 WatchedItem::doDuplicateEntries( $ot->getSubjectPage(), $nt->getSubjectPage() );
00131                 WatchedItem::doDuplicateEntries( $ot->getTalkPage(), $nt->getTalkPage() );
00132         }
00133 
00142         private static function doDuplicateEntries( $ot, $nt ) {        
00143                 $oldnamespace = $ot->getNamespace();
00144                 $newnamespace = $nt->getNamespace();
00145                 $oldtitle = $ot->getDBkey();
00146                 $newtitle = $nt->getDBkey();
00147 
00148                 $dbw = wfGetDB( DB_MASTER );
00149                 $res = $dbw->select( 'watchlist', 'wl_user',
00150                         array( 'wl_namespace' => $oldnamespace, 'wl_title' => $oldtitle ),
00151                         __METHOD__, 'FOR UPDATE'
00152                 );
00153                 # Construct array to replace into the watchlist
00154                 $values = array();
00155                 foreach ( $res as $s ) {
00156                         $values[] = array(
00157                                 'wl_user' => $s->wl_user,
00158                                 'wl_namespace' => $newnamespace,
00159                                 'wl_title' => $newtitle
00160                         );
00161                 }
00162 
00163                 if( empty( $values ) ) {
00164                         // Nothing to do
00165                         return true;
00166                 }
00167 
00168                 # Perform replace
00169                 # Note that multi-row replace is very efficient for MySQL but may be inefficient for
00170                 # some other DBMSes, mostly due to poor simulation by us
00171                 $dbw->replace( 'watchlist', array( array( 'wl_user', 'wl_namespace', 'wl_title' ) ), $values, __METHOD__ );
00172                 return true;
00173         }
00174 }