}
/**
- * User-interface handler for the "watch" action
+ * User-interface handler for the "watch" action.
+ * Requires Request to pass a token as of 1.19.
* @deprecated since 1.18
*/
public function watch() {
* @deprecated since 1.18
*/
public function doWatch() {
- return Action::factory( 'watch', $this )->execute();
+ global $wgUser;
+ return WatchAction:doWatch( $this->mTitle, $wgUser );
}
/**
* User interface handler for the "unwatch" action.
+ * Requires Request to pass a token as of 1.19.
* @deprecated since 1.18
*/
public function unwatch() {
* @deprecated since 1.18
*/
public function doUnwatch() {
- return Action::factory( 'unwatch', $this )->execute();
+ global $wgUser;
+ return WatchAction:doUnwatch( $this->mTitle, $wgUser );
}
/**
* Commit the change of watch status
*/
protected function commitWatch() {
+ global $wgUser;
if ( $this->watchthis xor $this->mTitle->userIsWatching() ) {
$dbw = wfGetDB( DB_MASTER );
$dbw->begin();
if ( $this->watchthis ) {
- Action::factory( 'watch', $this->mArticle )->execute();
+ WatchAction::doWatch( $this->mTitle, $wgUser );
} else {
- Action::factory( 'unwatch', $this->mArticle )->execute();
+ WatchAction::doUnwatch( $this->mTitle, $wgUser );
}
$dbw->commit();
}
// delete the associated article first
if( $article->doDeleteArticle( $reason, $suppress, $id, false ) ) {
global $wgRequest;
- if( $wgRequest->getCheck( 'wpWatch' ) && $wgUser->isLoggedIn() ) {
- Action::factory( 'watch', $article )->execute();
- } elseif( $title->userIsWatching() ) {
- Action::factory( 'unwatch', $article )->execute();
+ if ( $wgRequest->getCheck( 'wpWatch' ) && $wgUser->isLoggedIn() ) {
+ WatchAction::doWatch( $title, $wgUser );
+ } elseif ( $title->userIsWatching() ) {
+ WatchAction::doUnwatch( $title, $wgUser );
}
$status = $file->delete( $reason, $suppress );
if( $status->ok ) {
return false;
}
- if( $wgRequest->getCheck( 'mwProtectWatch' ) && $wgUser->isLoggedIn() ) {
- Action::factory( 'watch', $this->mArticle )->execute();
- } elseif( $this->mTitle->userIsWatching() ) {
- Action::factory( 'unwatch', $this->mArticle )->execute();
+ if ( $wgRequest->getCheck( 'mwProtectWatch' ) && $wgUser->isLoggedIn() ) {
+ WatchAction::doWatch( $this->mTitle, $wgUser );
+ } elseif ( $this->mTitle->userIsWatching() ) {
+ WatchAction::doUnwatch( $this->mTitle, $wgUser );
}
return $ok;
}
}
function watchThisPage() {
- global $wgOut;
+ global $wgOut, $wgUser;
++$this->mWatchLinkNum;
+ // Cache
+ $title = $this->getSkin()->getTitle();
+
if ( $wgOut->isArticleRelated() ) {
- if ( $this->getSkin()->getTitle()->userIsWatching() ) {
+ if ( $title->userIsWatching() ) {
$text = wfMsg( 'unwatchthispage' );
- $query = array( 'action' => 'unwatch' );
+ $query = array(
+ 'action' => 'unwatch',
+ 'token' => UnwatchAction::getUnwatchToken( $title, $wgUser ),
+ );
$id = 'mw-unwatch-link' . $this->mWatchLinkNum;
} else {
$text = wfMsg( 'watchthispage' );
- $query = array( 'action' => 'watch' );
+ $query = array(
+ 'action' => 'watch',
+ 'token' => WatchAction::getWatchToken( $title, $wgUser ),
+ );
$id = 'mw-watch-link' . $this->mWatchLinkNum;
}
$s = $this->getSkin()->link(
- $this->getSkin()->getTitle(),
+ $title,
$text,
array( 'id' => $id ),
$query,
* the global versions.
*/
$mode = $title->userIsWatching() ? 'unwatch' : 'watch';
+ $token = WatchAction::getWatchToken( $title, $wgUser, $mode );
$content_navigation['actions'][$mode] = array(
'class' => $onPage && ( $action == 'watch' || $action == 'unwatch' ) ? 'selected' : false,
'text' => wfMsg( $mode ), // uses 'watch' or 'unwatch' message
- 'href' => $title->getLocalURL( 'action=' . $mode )
+ 'href' => $title->getLocalURL( array( 'action' => $mode, 'token' => $token ) )
);
}
<?php
/**
- * Performs the watch and unwatch actions on a page
+ * Performs the delete action on a page
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
public function onSuccess(){
// Watch or unwatch, if requested
if( $this->getRequest()->getCheck( 'wpWatch' ) && $this->getUser()->isLoggedIn() ) {
- Action::factory( 'watch', $this->page )->execute();
+ WatchAction::doWatch( $this->getTitle(), $this->getUser() );
} elseif ( $this->getTitle()->userIsWatching() ) {
- Action::factory( 'unwatch', $this->page )->execute();
+ WatchAction::doUnwatch( $this->getTitle(), $this->getUser() );
}
$this->getOutput()->setPagetitle( wfMsg( 'actioncomplete' ) );
}
protected function checkCanExecute( User $user ) {
+
+ // Must be logged in
if ( $user->isAnon() ) {
throw new ErrorPageError( 'watchnologin', 'watchnologintext' );
}
+
+ // Must have valid token for this action/title
+ $salt = array( $this->getName(), $this->getTitle()->getDBkey() );
+
+ if ( !$user->matchEditToken( $this->getRequest()->getVal( 'token' ), $salt ) ) {
+ throw new ErrorPageError( 'sessionfailure-title', 'sessionfailure' );
+ return;
+ }
+
return parent::checkCanExecute( $user );
}
wfProfileIn( __METHOD__ );
$user = $this->getUser();
- if ( wfRunHooks( 'WatchArticle', array( &$user, &$this->page ) ) ) {
- $this->getUser()->addWatch( $this->getTitle() );
- wfRunHooks( 'WatchArticleComplete', array( &$user, &$this->page ) );
- }
+ self::doWatch( $this->getTitle(), $user );
wfProfileOut( __METHOD__ );
return wfMessage( 'addedwatchtext', $this->getTitle()->getPrefixedText() )->parse();
}
+
+ public static function doWatch( Title $title, User $user ) {
+ $page = new Article( $title );
+
+ if ( wfRunHooks( 'WatchArticle', array( &$user, &$page ) ) ) {
+ $user->addWatch( $title );
+ wfRunHooks( 'WatchArticleComplete', array( &$user, &$page ) );
+ }
+ return true;
+ }
+
+ public static function doUnwatch( Title $title, User $user ) {
+ $page = new Article( $title );
+
+ if ( wfRunHooks( 'UnwatchArticle', array( &$user, &$page ) ) ) {
+ $user->removeWatch( $title );
+ wfRunHooks( 'UnwatchArticleComplete', array( &$user, &$page ) );
+ }
+ return true;
+ }
+
+ /**
+ * Get token to watch (or unwatch) a page for a user
+ *
+ * @param Title $title Title object of page to watch
+ * @param User $title User for whom the action is going to be performed
+ * @param string $action Optionally override the action to 'unwatch'
+ * @return string Token
+ * @since 1.19
+ */
+ public static function getWatchToken( Title $title, User $user, $action = 'watch' ) {
+ if ( $action != 'unwatch' ) {
+ $action = 'watch';
+ }
+ $salt = array( $action, $title->getDBkey() );
+
+ // This token stronger salted and not compatible with ApiWatch
+ // It's title/action specific because index.php is GET and API is POST
+ return $user->editToken( $salt );
+ }
+
+ /**
+ * Get token to unwatch (or watch) a page for a user
+ *
+ * @param Title $title Title object of page to unwatch
+ * @param User $title User for whom the action is going to be performed
+ * @param string $action Optionally override the action to 'watch'
+ * @return string Token
+ * @since 1.19
+ */
+ public static function getUnwatchToken( Title $title, User $user, $action = 'unwatch' ) {
+ return self::getWatchToken( $title, $user, $action );
+ }
+
}
class UnwatchAction extends WatchAction {
wfProfileIn( __METHOD__ );
$user = $this->getUser();
- if ( wfRunHooks( 'UnwatchArticle', array( &$user, &$this->page ) ) ) {
- $this->getUser()->removeWatch( $this->getTitle() );
- wfRunHooks( 'UnwatchArticleComplete', array( &$user, &$this->page ) );
- }
+ self::doUnwatch( $this->getTitle(), $user );
wfProfileOut( __METHOD__ );
* @param $titleObj Title the article's title to change
* @param $userOption String The user option to consider when $watch=preferences
*/
- protected function setWatch ( $watch, $titleObj, $userOption = null ) {
+ protected function setWatch( $watch, $titleObj, $userOption = null ) {
$value = $this->getWatchlistValue( $watch, $titleObj, $userOption );
if ( $value === null ) {
return;
}
- $articleObj = new Article( $titleObj );
+ global $wgUser;
if ( $value ) {
- Action::factory( 'watch', $articleObj )->execute();
+ WatchAction::doWatch( $titleObj, $wgUser );
} else {
- Action::factory( 'unwatch', $articleObj )->execute();
+ WatchAction::doUnwatch( $titleObj, $wgUser );
}
}
if ( $params['unwatch'] ) {
$res['unwatched'] = '';
$res['message'] = wfMsgExt( 'removedwatchtext', array( 'parse' ), $title->getPrefixedText() );
- $success = Action::factory( 'unwatch', $article )->execute();
+ $success = WatchAction::doWatch( $title, $wgUser );
} else {
$res['watched'] = '';
$res['message'] = wfMsgExt( 'addedwatchtext', array( 'parse' ), $title->getPrefixedText() );
- $success = Action::factory( 'watch', $article )->execute();
+ $success = UnwatchAction::doUnwatch( $title, $wgUser );
}
if ( !$success ) {
$this->dieUsageMsg( 'hookaborted' );