*/
const CHECK_USER_RIGHTS = 1;
- var $mTitle, $mUser, $mCheckRights;
- private $loaded = false, $watched, $timestamp;
+ /** @var Title */
+ public $mTitle;
+
+ /** @var User */
+ public $mUser;
+
+ /** @var int */
+ public $mCheckRights;
+
+ /** @var bool */
+ private $loaded = false;
+
+ /** @var bool */
+ private $watched;
+
+ /** @var string */
+ private $timestamp;
/**
* Create a WatchedItem object with the given user and title
* Pass either WatchedItem::IGNORE_USER_RIGHTS or WatchedItem::CHECK_USER_RIGHTS.
* @return WatchedItem
*/
- public static function fromUserTitle( $user, $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
+ public static function fromUserTitle( $user, $title,
+ $checkRights = WatchedItem::CHECK_USER_RIGHTS
+ ) {
$wl = new WatchedItem;
$wl->mUser = $user;
$wl->mTitle = $title;
}
/**
- * Given a title and user (assumes the object is setup), add the watch to the database.
+ * @param WatchedItem[] $items
* @return bool
*/
- public function addWatch() {
- wfProfileIn( __METHOD__ );
+ static public function batchAddWatch( array $items ) {
+ $section = new ProfileSection( __METHOD__ );
- // Only loggedin user can have a watchlist
- if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) {
- wfProfileOut( __METHOD__ );
+ if ( wfReadOnly() ) {
return false;
}
- // Use INSERT IGNORE to avoid overwriting the notification timestamp
- // if there's already an entry for this page
- $dbw = wfGetDB( DB_MASTER );
- $dbw->insert( 'watchlist',
- array(
- 'wl_user' => $this->getUserId(),
- 'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ),
- 'wl_title' => $this->getTitleDBkey(),
+ $rows = array();
+ foreach ( $items as $item ) {
+ // Only loggedin user can have a watchlist
+ if ( $item->mUser->isAnon() || !$item->isAllowed( 'editmywatchlist' ) ) {
+ continue;
+ }
+ $rows[] = array(
+ 'wl_user' => $item->getUserId(),
+ 'wl_namespace' => MWNamespace::getSubject( $item->getTitleNs() ),
+ 'wl_title' => $item->getTitleDBkey(),
+ 'wl_notificationtimestamp' => null,
+ );
+ // Every single watched page needs now to be listed in watchlist;
+ // namespace:page and namespace_talk:page need separate entries:
+ $rows[] = array(
+ 'wl_user' => $item->getUserId(),
+ 'wl_namespace' => MWNamespace::getTalk( $item->getTitleNs() ),
+ 'wl_title' => $item->getTitleDBkey(),
'wl_notificationtimestamp' => null
- ), __METHOD__, 'IGNORE' );
+ );
+ $item->watched = true;
+ }
- // Every single watched page needs now to be listed in watchlist;
- // namespace:page and namespace_talk:page need separate entries:
- $dbw->insert( 'watchlist',
- array(
- 'wl_user' => $this->getUserId(),
- 'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ),
- 'wl_title' => $this->getTitleDBkey(),
- 'wl_notificationtimestamp' => null
- ), __METHOD__, 'IGNORE' );
+ if ( !$rows ) {
+ return false;
+ }
- $this->watched = true;
+ $dbw = wfGetDB( DB_MASTER );
+ foreach( array_chunk( $rows, 100 ) as $toInsert ) {
+ // Use INSERT IGNORE to avoid overwriting the notification timestamp
+ // if there's already an entry for this page
+ $dbw->insert( 'watchlist', $toInsert, __METHOD__, 'IGNORE' );
+ }
- wfProfileOut( __METHOD__ );
return true;
}
+ /**
+ * Given a title and user (assumes the object is setup), add the watch to the database.
+ * @return bool
+ */
+ public function addWatch() {
+ return self::batchAddWatch( array( $this ) );
+ }
+
/**
* Same as addWatch, only the opposite.
* @return bool
# 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
- $dbw->replace( 'watchlist', array( array( 'wl_user', 'wl_namespace', 'wl_title' ) ), $values, __METHOD__ );
+ $dbw->replace(
+ 'watchlist',
+ array( array( 'wl_user', 'wl_namespace', 'wl_title' ) ),
+ $values,
+ __METHOD__
+ );
+
return true;
}
}