2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
|
|
|
|
* @ingroup Watchlist
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-11-09 11:45:12 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup Watchlist
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2003-11-09 11:45:12 +00:00
|
|
|
class WatchedItem {
|
2008-09-15 17:40:12 +00:00
|
|
|
var $mTitle, $mUser, $id, $ns, $ti;
|
2012-02-10 19:35:14 +00:00
|
|
|
private $loaded = false, $watched, $timestamp;
|
2003-11-09 11:45:12 +00:00
|
|
|
|
2005-01-27 17:56:04 +00:00
|
|
|
/**
|
|
|
|
|
* Create a WatchedItem object with the given user and title
|
2008-09-17 14:26:43 +00:00
|
|
|
* @param $user User: the user to use for (un)watching
|
|
|
|
|
* @param $title Title: the title we're going to (un)watch
|
2008-09-15 17:40:12 +00:00
|
|
|
* @return WatchedItem object
|
2005-01-27 17:56:04 +00:00
|
|
|
*/
|
2008-09-15 17:40:12 +00:00
|
|
|
public static function fromUserTitle( $user, $title ) {
|
2003-11-09 11:45:12 +00:00
|
|
|
$wl = new WatchedItem;
|
2007-05-02 15:36:17 +00:00
|
|
|
$wl->mUser = $user;
|
|
|
|
|
$wl->mTitle = $title;
|
2008-05-22 16:39:43 +00:00
|
|
|
$wl->id = $user->getId();
|
2008-09-15 17:40:12 +00:00
|
|
|
# Patch (also) for email notification on page changes T.Gries/M.Arndt 11.09.2004
|
|
|
|
|
# TG patch: here we do not consider pages and their talk pages equivalent - why should we ?
|
|
|
|
|
# The change results in talk-pages not automatically included in watchlists, when their parent page is included
|
|
|
|
|
# $wl->ns = $title->getNamespace() & ~1;
|
2004-12-18 03:47:11 +00:00
|
|
|
$wl->ns = $title->getNamespace();
|
|
|
|
|
|
2003-11-09 11:45:12 +00:00
|
|
|
$wl->ti = $title->getDBkey();
|
|
|
|
|
return $wl;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2012-02-10 19:35:14 +00:00
|
|
|
* Return an array of conditions to select or update the appropriate database
|
|
|
|
|
* row.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2012-02-10 19:35:14 +00:00
|
|
|
private function dbCond() {
|
|
|
|
|
return array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns, 'wl_title' => $this->ti );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Load the object from the database
|
|
|
|
|
*/
|
|
|
|
|
private function load() {
|
|
|
|
|
if ( $this->loaded ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
$this->loaded = true;
|
|
|
|
|
|
2003-11-09 11:45:12 +00:00
|
|
|
# Pages and their talk pages are considered equivalent for watching;
|
|
|
|
|
# remember that talk namespaces are numbered as page namespace+1.
|
2004-07-18 08:48:43 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2012-02-10 19:35:14 +00:00
|
|
|
$row = $dbr->selectRow( 'watchlist', 'wl_notificationtimestamp',
|
|
|
|
|
$this->dbCond(), __METHOD__ );
|
|
|
|
|
|
|
|
|
|
if ( $row === false ) {
|
|
|
|
|
$this->watched = false;
|
|
|
|
|
} else {
|
|
|
|
|
$this->watched = true;
|
|
|
|
|
$this->timestamp = $row->wl_notificationtimestamp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Is mTitle being watched by mUser?
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function isWatched() {
|
|
|
|
|
$this->load();
|
|
|
|
|
return $this->watched;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the notification timestamp of this entry.
|
|
|
|
|
*
|
|
|
|
|
* @return false|null|string: false if the page is not watched, the value of
|
|
|
|
|
* the wl_notificationtimestamp field otherwise
|
|
|
|
|
*/
|
|
|
|
|
public function getNotificationTimestamp() {
|
|
|
|
|
$this->load();
|
|
|
|
|
if ( $this->watched ) {
|
|
|
|
|
return $this->timestamp;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reset the notification timestamp of this entry
|
|
|
|
|
*
|
|
|
|
|
* @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.
|
|
|
|
|
*/
|
|
|
|
|
public function resetNotificationTimestamp( $force = '' ) {
|
|
|
|
|
if ( $force != 'force' ) {
|
|
|
|
|
$this->load();
|
|
|
|
|
if ( !$this->watched || $this->timestamp === null ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 ),
|
|
|
|
|
$this->dbCond(), __METHOD__ );
|
|
|
|
|
$this->timestamp = null;
|
2003-11-09 11:45:12 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-27 17:56:04 +00:00
|
|
|
/**
|
2008-09-15 17:40:12 +00:00
|
|
|
* Given a title and user (assumes the object is setup), add the watch to the
|
|
|
|
|
* database.
|
|
|
|
|
* @return bool (always true)
|
2005-01-27 17:56:04 +00:00
|
|
|
*/
|
2008-09-15 17:40:12 +00:00
|
|
|
public function addWatch() {
|
2009-02-26 12:52:21 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-12-08 01:36:33 +00:00
|
|
|
// Use INSERT IGNORE to avoid overwriting the notification timestamp
|
|
|
|
|
// if there's already an entry for this page
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-12-08 01:36:33 +00:00
|
|
|
$dbw->insert( 'watchlist',
|
2005-08-02 13:35:19 +00:00
|
|
|
array(
|
2009-02-26 12:52:21 +00:00
|
|
|
'wl_user' => $this->id,
|
|
|
|
|
'wl_namespace' => MWNamespace::getSubject($this->ns),
|
2004-12-18 03:47:11 +00:00
|
|
|
'wl_title' => $this->ti,
|
2009-12-11 21:07:27 +00:00
|
|
|
'wl_notificationtimestamp' => null
|
2009-02-26 12:52:21 +00:00
|
|
|
), __METHOD__, 'IGNORE' );
|
2004-12-18 03:47:11 +00:00
|
|
|
|
2005-12-08 01:36:33 +00:00
|
|
|
// Every single watched page needs now to be listed in watchlist;
|
|
|
|
|
// namespace:page and namespace_talk:page need separate entries:
|
|
|
|
|
$dbw->insert( 'watchlist',
|
2004-12-18 03:47:11 +00:00
|
|
|
array(
|
|
|
|
|
'wl_user' => $this->id,
|
2009-02-26 12:52:21 +00:00
|
|
|
'wl_namespace' => MWNamespace::getTalk($this->ns),
|
2004-07-18 08:48:43 +00:00
|
|
|
'wl_title' => $this->ti,
|
2009-12-11 21:07:27 +00:00
|
|
|
'wl_notificationtimestamp' => null
|
2009-02-26 12:52:21 +00:00
|
|
|
), __METHOD__, 'IGNORE' );
|
2004-06-11 15:54:29 +00:00
|
|
|
|
2012-02-10 19:35:14 +00:00
|
|
|
$this->watched = true;
|
|
|
|
|
|
2009-02-26 12:52:21 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2003-11-09 11:45:12 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-15 17:40:12 +00:00
|
|
|
/**
|
|
|
|
|
* Same as addWatch, only the opposite.
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function removeWatch() {
|
2011-02-13 19:12:24 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
|
|
|
|
|
2005-05-14 17:55:04 +00:00
|
|
|
$success = false;
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-08-02 13:35:19 +00:00
|
|
|
$dbw->delete( 'watchlist',
|
|
|
|
|
array(
|
|
|
|
|
'wl_user' => $this->id,
|
2009-02-26 12:52:21 +00:00
|
|
|
'wl_namespace' => MWNamespace::getSubject($this->ns),
|
2004-12-18 03:47:11 +00:00
|
|
|
'wl_title' => $this->ti
|
2009-02-26 12:52:21 +00:00
|
|
|
), __METHOD__
|
2004-12-18 03:47:11 +00:00
|
|
|
);
|
2005-05-14 17:55:04 +00:00
|
|
|
if ( $dbw->affectedRows() ) {
|
|
|
|
|
$success = true;
|
|
|
|
|
}
|
2004-12-18 03:47:11 +00:00
|
|
|
|
2005-01-27 17:56:04 +00:00
|
|
|
# the following code compensates the new behaviour, introduced by the
|
|
|
|
|
# enotif patch, that every single watched page needs now to be listed
|
|
|
|
|
# in watchlist namespace:page and namespace_talk:page had separate
|
|
|
|
|
# entries: clear them
|
2004-12-18 03:47:11 +00:00
|
|
|
$dbw->delete( 'watchlist',
|
|
|
|
|
array(
|
|
|
|
|
'wl_user' => $this->id,
|
2009-02-26 12:52:21 +00:00
|
|
|
'wl_namespace' => MWNamespace::getTalk($this->ns),
|
2004-07-18 08:48:43 +00:00
|
|
|
'wl_title' => $this->ti
|
2009-02-26 12:52:21 +00:00
|
|
|
), __METHOD__
|
2004-07-18 08:48:43 +00:00
|
|
|
);
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-07-18 08:48:43 +00:00
|
|
|
if ( $dbw->affectedRows() ) {
|
2005-05-14 17:55:04 +00:00
|
|
|
$success = true;
|
|
|
|
|
}
|
2011-02-13 19:12:24 +00:00
|
|
|
|
2012-02-10 19:35:14 +00:00
|
|
|
$this->watched = false;
|
|
|
|
|
|
2011-02-13 19:12:24 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-05-14 17:55:04 +00:00
|
|
|
return $success;
|
2003-11-09 11:45:12 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2005-11-26 00:54:07 +00:00
|
|
|
* Check if the given title already is watched by the user, and if so
|
|
|
|
|
* add watches on a new title. To be used for page renames and such.
|
|
|
|
|
*
|
2008-05-22 19:48:26 +00:00
|
|
|
* @param $ot Title: page title to duplicate entries from, if present
|
|
|
|
|
* @param $nt Title: page title to add watches on
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-09-15 17:40:12 +00:00
|
|
|
public static function duplicateEntries( $ot, $nt ) {
|
2005-11-26 00:54:07 +00:00
|
|
|
WatchedItem::doDuplicateEntries( $ot->getSubjectPage(), $nt->getSubjectPage() );
|
|
|
|
|
WatchedItem::doDuplicateEntries( $ot->getTalkPage(), $nt->getTalkPage() );
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2008-09-15 17:40:12 +00:00
|
|
|
/**
|
|
|
|
|
* Handle duplicate entries. Backend for duplicateEntries().
|
2011-05-28 19:00:01 +00:00
|
|
|
*
|
|
|
|
|
* @param $ot Title
|
|
|
|
|
* @param $nt Title
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
2008-09-15 17:40:12 +00:00
|
|
|
*/
|
2012-02-10 19:35:14 +00:00
|
|
|
private static function doDuplicateEntries( $ot, $nt ) {
|
2005-11-26 00:54:07 +00:00
|
|
|
$oldnamespace = $ot->getNamespace();
|
|
|
|
|
$newnamespace = $nt->getNamespace();
|
2003-11-09 11:45:12 +00:00
|
|
|
$oldtitle = $ot->getDBkey();
|
|
|
|
|
$newtitle = $nt->getDBkey();
|
|
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-08-02 13:35:19 +00:00
|
|
|
$res = $dbw->select( 'watchlist', 'wl_user',
|
2004-07-18 08:48:43 +00:00
|
|
|
array( 'wl_namespace' => $oldnamespace, 'wl_title' => $oldtitle ),
|
2009-02-26 12:52:21 +00:00
|
|
|
__METHOD__, 'FOR UPDATE'
|
2004-07-18 08:48:43 +00:00
|
|
|
);
|
|
|
|
|
# Construct array to replace into the watchlist
|
|
|
|
|
$values = array();
|
2010-10-13 23:11:40 +00:00
|
|
|
foreach ( $res as $s ) {
|
2004-07-18 08:48:43 +00:00
|
|
|
$values[] = array(
|
|
|
|
|
'wl_user' => $s->wl_user,
|
|
|
|
|
'wl_namespace' => $newnamespace,
|
|
|
|
|
'wl_title' => $newtitle
|
|
|
|
|
);
|
2003-11-09 11:45:12 +00:00
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2005-10-28 06:26:16 +00:00
|
|
|
if( empty( $values ) ) {
|
|
|
|
|
// Nothing to do
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2004-07-18 08:48:43 +00:00
|
|
|
|
|
|
|
|
# Perform replace
|
|
|
|
|
# Note that multi-row replace is very efficient for MySQL but may be inefficient for
|
|
|
|
|
# some other DBMSes, mostly due to poor simulation by us
|
2009-02-26 12:52:21 +00:00
|
|
|
$dbw->replace( 'watchlist', array( array( 'wl_user', 'wl_namespace', 'wl_title' ) ), $values, __METHOD__ );
|
2003-11-09 11:45:12 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|