WatchAction.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. /**
  3. * Performs the watch actions on a page
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *
  19. * @file
  20. * @ingroup Actions
  21. */
  22. use MediaWiki\MediaWikiServices;
  23. /**
  24. * Page addition to a user's watchlist
  25. *
  26. * @ingroup Actions
  27. */
  28. class WatchAction extends FormAction {
  29. public function getName() {
  30. return 'watch';
  31. }
  32. public function requiresUnblock() {
  33. return false;
  34. }
  35. protected function getDescription() {
  36. return '';
  37. }
  38. public function onSubmit( $data ) {
  39. return self::doWatch( $this->getTitle(), $this->getUser() );
  40. }
  41. protected function checkCanExecute( User $user ) {
  42. // Must be logged in
  43. if ( $user->isAnon() ) {
  44. throw new UserNotLoggedIn( 'watchlistanontext', 'watchnologin' );
  45. }
  46. parent::checkCanExecute( $user );
  47. }
  48. protected function usesOOUI() {
  49. return true;
  50. }
  51. protected function getFormFields() {
  52. return [
  53. 'intro' => [
  54. 'type' => 'info',
  55. 'vertical-label' => true,
  56. 'raw' => true,
  57. 'default' => $this->msg( 'confirm-watch-top' )->parse()
  58. ]
  59. ];
  60. }
  61. protected function alterForm( HTMLForm $form ) {
  62. $form->setWrapperLegendMsg( 'addwatch' );
  63. $form->setSubmitTextMsg( 'confirm-watch-button' );
  64. $form->setTokenSalt( 'watch' );
  65. }
  66. public function onSuccess() {
  67. $msgKey = $this->getTitle()->isTalkPage() ? 'addedwatchtext-talk' : 'addedwatchtext';
  68. $this->getOutput()->addWikiMsg( $msgKey, $this->getTitle()->getPrefixedText() );
  69. }
  70. /**
  71. * Watch or unwatch a page
  72. * @since 1.22
  73. * @param bool $watch Whether to watch or unwatch the page
  74. * @param Title $title Page to watch/unwatch
  75. * @param User $user User who is watching/unwatching
  76. * @return Status
  77. */
  78. public static function doWatchOrUnwatch( $watch, Title $title, User $user ) {
  79. if ( $user->isLoggedIn() &&
  80. $user->isWatched( $title, User::IGNORE_USER_RIGHTS ) != $watch
  81. ) {
  82. // If the user doesn't have 'editmywatchlist', we still want to
  83. // allow them to add but not remove items via edits and such.
  84. if ( $watch ) {
  85. return self::doWatch( $title, $user, User::IGNORE_USER_RIGHTS );
  86. } else {
  87. return self::doUnwatch( $title, $user );
  88. }
  89. }
  90. return Status::newGood();
  91. }
  92. /**
  93. * Watch a page
  94. * @since 1.22 Returns Status, $checkRights parameter added
  95. * @param Title $title Page to watch/unwatch
  96. * @param User $user User who is watching/unwatching
  97. * @param bool $checkRights Passed through to $user->addWatch()
  98. * Pass User::CHECK_USER_RIGHTS or User::IGNORE_USER_RIGHTS.
  99. * @return Status
  100. */
  101. public static function doWatch(
  102. Title $title,
  103. User $user,
  104. $checkRights = User::CHECK_USER_RIGHTS
  105. ) {
  106. $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
  107. if ( $checkRights && !$permissionManager->userHasRight( $user, 'editmywatchlist' ) ) {
  108. return User::newFatalPermissionDeniedStatus( 'editmywatchlist' );
  109. }
  110. $page = WikiPage::factory( $title );
  111. $status = Status::newFatal( 'hookaborted' );
  112. if ( Hooks::run( 'WatchArticle', [ &$user, &$page, &$status ] ) ) {
  113. $status = Status::newGood();
  114. $user->addWatch( $title, $checkRights );
  115. Hooks::run( 'WatchArticleComplete', [ &$user, &$page ] );
  116. }
  117. return $status;
  118. }
  119. /**
  120. * Unwatch a page
  121. * @since 1.22 Returns Status
  122. * @param Title $title Page to watch/unwatch
  123. * @param User $user User who is watching/unwatching
  124. * @return Status
  125. */
  126. public static function doUnwatch( Title $title, User $user ) {
  127. if ( !MediaWikiServices::getInstance()
  128. ->getPermissionManager()
  129. ->userHasRight( $user, 'editmywatchlist' ) ) {
  130. return User::newFatalPermissionDeniedStatus( 'editmywatchlist' );
  131. }
  132. $page = WikiPage::factory( $title );
  133. $status = Status::newFatal( 'hookaborted' );
  134. if ( Hooks::run( 'UnwatchArticle', [ &$user, &$page, &$status ] ) ) {
  135. $status = Status::newGood();
  136. $user->removeWatch( $title );
  137. Hooks::run( 'UnwatchArticleComplete', [ &$user, &$page ] );
  138. }
  139. return $status;
  140. }
  141. /**
  142. * Get token to watch (or unwatch) a page for a user
  143. *
  144. * @param Title $title Title object of page to watch
  145. * @param User $user User for whom the action is going to be performed
  146. * @param string $action Optionally override the action to 'unwatch'
  147. * @return string Token
  148. * @since 1.18
  149. */
  150. public static function getWatchToken( Title $title, User $user, $action = 'watch' ) {
  151. if ( $action != 'unwatch' ) {
  152. $action = 'watch';
  153. }
  154. // Match ApiWatch and ResourceLoaderUserTokensModule
  155. return $user->getEditToken( $action );
  156. }
  157. public function doesWrites() {
  158. return true;
  159. }
  160. }