Merge "Use HTMLForm to generate the form on Special:ListFiles"
[lhc/web/wiklou.git] / includes / WatchedItem.php
index a6e7516..93d6c0b 100644 (file)
@@ -41,19 +41,36 @@ class WatchedItem {
         */
        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
         * @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.
+        * @param User $user The user to use for (un)watching
+        * @param Title $title The title we're going to (un)watch
+        * @param int $checkRights Whether to check the 'viewmywatchlist' and 'editmywatchlist' rights.
         *     Pass either WatchedItem::IGNORE_USER_RIGHTS or WatchedItem::CHECK_USER_RIGHTS.
-        * @return WatchedItem object
+        * @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;
@@ -146,7 +163,7 @@ class WatchedItem {
 
        /**
         * Check permissions
-        * @param $what string: 'viewmywatchlist' or 'editmywatchlist'
+        * @param string $what 'viewmywatchlist' or 'editmywatchlist'
         */
        private function isAllowed( $what ) {
                return !$this->mCheckRights || $this->mUser->isAllowed( $what );
@@ -168,8 +185,8 @@ class WatchedItem {
        /**
         * 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
+        * @return bool|null|string False if the page is not watched, the value of
+        *   the wl_notificationtimestamp field otherwise
         */
        public function getNotificationTimestamp() {
                if ( !$this->isAllowed( 'viewmywatchlist' ) ) {
@@ -187,8 +204,8 @@ class WatchedItem {
        /**
         * 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.
+        * @param bool $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 = '', $oldid = 0 ) {
@@ -253,46 +270,61 @@ class WatchedItem {
        }
 
        /**
-        * 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
@@ -345,8 +377,8 @@ class WatchedItem {
         * 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.
         *
-        * @param $ot Title: page title to duplicate entries from, if present
-        * @param $nt Title: page title to add watches on
+        * @param Title $ot Page title to duplicate entries from, if present
+        * @param Title $nt Page title to add watches on
         */
        public static function duplicateEntries( $ot, $nt ) {
                WatchedItem::doDuplicateEntries( $ot->getSubjectPage(), $nt->getSubjectPage() );
@@ -356,8 +388,8 @@ class WatchedItem {
        /**
         * Handle duplicate entries. Backend for duplicateEntries().
         *
-        * @param $ot Title
-        * @param $nt Title
+        * @param Title $ot
+        * @param Title $nt
         *
         * @return bool
         */
@@ -390,7 +422,13 @@ class WatchedItem {
                # 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;
        }
 }