MediaWiki REL1_37
WatchAction.php
Go to the documentation of this file.
1<?php
28
34class WatchAction extends FormAction {
35
38
40 protected $expiryFormFieldName = 'expiry';
41
43 protected $watchedItem = false;
44
47
56 public function __construct(
57 Page $page,
58 IContextSource $context,
60 WatchedItemStore $watchedItemStore
61 ) {
62 parent::__construct( $page, $context );
63 $this->watchlistExpiry = $this->getContext()->getConfig()->get( 'WatchlistExpiry' );
64 if ( $this->watchlistExpiry ) {
65 // The watchedItem is only used in this action's form if $wgWatchlistExpiry is enabled.
66 $this->watchedItem = $watchedItemStore->getWatchedItem(
67 $this->getUser(),
68 $this->getTitle()
69 );
70 }
71 $this->watchlistManager = $watchlistManager;
72 }
73
74 public function getName() {
75 return 'watch';
76 }
77
78 public function requiresUnblock() {
79 return false;
80 }
81
82 protected function getDescription() {
83 return '';
84 }
85
86 public function onSubmit( $data ) {
87 // Even though we're never unwatching here, use WatchlistManager::setWatch()
88 // because it also checks for changed expiry.
89 $result = $this->watchlistManager->setWatch(
90 true,
91 $this->getContext()->getAuthority(),
92 $this->getTitle(),
93 $this->getRequest()->getVal( 'wp' . $this->expiryFormFieldName )
94 );
95
96 return Status::wrap( $result );
97 }
98
99 protected function checkCanExecute( User $user ) {
100 // Must be logged in
101 if ( $user->isAnon() ) {
102 throw new UserNotLoggedIn( 'watchlistanontext', 'watchnologin' );
103 }
104
105 parent::checkCanExecute( $user );
106 }
107
108 protected function usesOOUI() {
109 return true;
110 }
111
112 protected function getFormFields() {
113 // If watchlist expiry is not enabled, return a simple confirmation message.
114 if ( !$this->watchlistExpiry ) {
115 return [
116 'intro' => [
117 'type' => 'info',
118 'raw' => true,
119 'default' => $this->msg( 'confirm-watch-top' )->parse(),
120 ],
121 ];
122 }
123
124 // Otherwise, use a select-list of expiries.
125 $expiryOptions = static::getExpiryOptions( $this->getContext(), $this->watchedItem );
126 return [
127 $this->expiryFormFieldName => [
128 'type' => 'select',
129 'label-message' => 'confirm-watch-label',
130 'options' => $expiryOptions['options'],
131 'default' => $expiryOptions['default'],
132 ]
133 ];
134 }
135
148 public static function getExpiryOptions( MessageLocalizer $msgLocalizer, $watchedItem ) {
149 $expiryOptions = self::getExpiryOptionsFromMessage( $msgLocalizer );
150 $default = in_array( 'infinite', $expiryOptions )
151 ? 'infinite'
152 : current( $expiryOptions );
153 if ( $watchedItem instanceof WatchedItem && $watchedItem->getExpiry() ) {
154 // If it's already being temporarily watched,
155 // add the existing expiry as the default option in the dropdown.
156 $default = $watchedItem->getExpiry( TS_ISO_8601 );
157 $daysLeft = $watchedItem->getExpiryInDaysText( $msgLocalizer, true );
158 $expiryOptions = array_merge( [ $daysLeft => $default ], $expiryOptions );
159 }
160 return [
161 'options' => $expiryOptions,
162 'default' => $default,
163 ];
164 }
165
174 private static function getExpiryOptionsFromMessage(
175 MessageLocalizer $msgLocalizer, ?string $lang = null
176 ): array {
177 $expiryOptionsMsg = $msgLocalizer->msg( 'watchlist-expiry-options' );
178 $optionsText = !$lang ? $expiryOptionsMsg->text() : $expiryOptionsMsg->inLanguage( $lang )->text();
180 $optionsText
181 );
182
183 $expiryOptions = [];
184 foreach ( $options as $label => $value ) {
185 if ( strtotime( $value ) || wfIsInfinity( $value ) ) {
186 $expiryOptions[$label] = $value;
187 }
188 }
189
190 // If message options is invalid try to recover by returning
191 // english options (T267611)
192 if ( !$expiryOptions && $expiryOptionsMsg->getLanguage()->getCode() !== 'en' ) {
193 return self::getExpiryOptionsFromMessage( $msgLocalizer, 'en' );
194 }
195
196 return $expiryOptions;
197 }
198
199 protected function alterForm( HTMLForm $form ) {
200 $msg = $this->watchlistExpiry && $this->watchedItem ? 'updatewatchlist' : 'addwatch';
201 $form->setWrapperLegendMsg( $msg );
202 $submitMsg = $this->watchlistExpiry ? 'confirm-watch-button-expiry' : 'confirm-watch-button';
203 $form->setSubmitTextMsg( $submitMsg );
204 $form->setTokenSalt( 'watch' );
205 }
206
219 public function onSuccess() {
220 $msgKey = $this->getTitle()->isTalkPage() ? 'addedwatchtext-talk' : 'addedwatchtext';
221 $expiryLabel = null;
222 $submittedExpiry = $this->getContext()->getRequest()->getText( 'wp' . $this->expiryFormFieldName );
223 if ( $submittedExpiry ) {
224 // We can't use $this->watcheditem to get the expiry because it's not been saved at this
225 // point in the request and so its values are those from before saving.
226 $expiry = ExpiryDef::normalizeExpiry( $submittedExpiry, TS_ISO_8601 );
227
228 // If the expiry label isn't one of the predefined ones in the dropdown, calculate 'x days'.
229 $expiryDays = WatchedItem::calculateExpiryInDays( $expiry );
230 $defaultLabels = static::getExpiryOptions( $this->getContext(), null )['options'];
231 $localizedExpiry = array_search( $submittedExpiry, $defaultLabels );
232 $expiryLabel = $expiryDays && $localizedExpiry === false
233 ? $this->getContext()->msg( 'days', $expiryDays )->text()
234 : $localizedExpiry;
235
236 // Determine which message to use, depending on whether this is a talk page or not
237 // and whether an expiry was selected.
238 $isTalk = $this->getTitle()->isTalkPage();
239 if ( wfIsInfinity( $expiry ) ) {
240 $msgKey = $isTalk ? 'addedwatchindefinitelytext-talk' : 'addedwatchindefinitelytext';
241 } elseif ( $expiryDays > 0 ) {
242 $msgKey = $isTalk ? 'addedwatchexpirytext-talk' : 'addedwatchexpirytext';
243 } elseif ( $expiryDays < 1 ) {
244 $msgKey = $isTalk ? 'addedwatchexpiryhours-talk' : 'addedwatchexpiryhours';
245 }
246 }
247 $this->getOutput()->addWikiMsg( $msgKey, $this->getTitle()->getPrefixedText(), $expiryLabel );
248 }
249
264 public static function doWatchOrUnwatch(
265 $watch,
266 PageIdentity $pageIdentity,
267 Authority $performer,
268 string $expiry = null
269 ) {
270 wfDeprecated( __METHOD__, '1.37' );
271 return Status::wrap( MediaWikiServices::getInstance()->getWatchlistManager()->setWatch(
272 $watch,
273 $performer,
274 $pageIdentity,
275 $expiry
276 ) );
277 }
278
291 public static function doWatch(
292 PageIdentity $pageIdentity,
293 Authority $performer,
294 $checkRights = User::CHECK_USER_RIGHTS,
295 ?string $expiry = null
296 ) {
297 wfDeprecated( __METHOD__, '1.37' );
298 $watchlistManager = MediaWikiServices::getInstance()->getWatchlistManager();
299 if ( $checkRights ) {
300 return Status::wrap( $watchlistManager->addWatch(
301 $performer,
302 $pageIdentity,
303 $expiry
304 ) );
305 }
306 return Status::wrap( $watchlistManager->addWatchIgnoringRights(
307 $performer->getUser(),
308 $pageIdentity,
309 $expiry
310 ) );
311 }
312
323 public static function doUnwatch( PageIdentity $pageIdentity, Authority $performer ) {
324 wfDeprecated( __METHOD__, '1.37' );
325 return Status::wrap( MediaWikiServices::getInstance()->getWatchlistManager()->removeWatch(
326 $performer,
327 $pageIdentity
328 ) );
329 }
330
342 public static function getWatchToken( PageIdentity $page, User $user, $action = 'watch' ) {
343 wfDeprecated( __METHOD__, '1.37' );
344 if ( $action != 'unwatch' ) {
345 $action = 'watch';
346 }
347 // This must match ApiWatch and ResourceLoaderUserOptionsModule
348 return $user->getEditToken( $action );
349 }
350
351 public function doesWrites() {
352 return true;
353 }
354}
getAuthority()
setWatch(string $watch, Title $title, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
WatchlistManager $watchlistManager
wfIsInfinity( $str)
Determine input string is represents as infinity.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
getContext()
getUser()
Shortcut to get the User being used for this instance.
Definition Action.php:166
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition Action.php:228
getRequest()
Get the WebRequest being used for this instance.
Definition Action.php:146
An action which shows a form and does something based on the input from the form.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:143
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setWrapperLegendMsg( $msg)
Prompt the whole form to be wrapped in a "<fieldset>", with this message as its "<legend>" element.
setTokenSalt( $salt)
Set the salt for the edit token.
MediaWikiServices is the service locator for the application scope of MediaWiki.
addWatch(Authority $performer, PageIdentity $target, ?string $expiry=null)
Watch a page if the user has permission to edit their watchlist.
addWatchIgnoringRights(UserIdentity $userIdentity, PageIdentity $target, ?string $expiry=null)
Watch a page.
Redirect a user to the login page.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:69
getEditToken( $salt='', $request=null)
Initialize (if necessary) and return a session token value which can be used in edit forms to show th...
Definition User.php:3715
const CHECK_USER_RIGHTS
Definition User.php:111
isAnon()
Get whether the user is anonymous.
Definition User.php:2986
Page addition to a user's watchlist.
static doWatch(PageIdentity $pageIdentity, Authority $performer, $checkRights=User::CHECK_USER_RIGHTS, ?string $expiry=null)
Watch a page.
static getExpiryOptions(MessageLocalizer $msgLocalizer, $watchedItem)
Get options and default for a watchlist expiry select list.
getDescription()
Returns the description that goes below the <h1> tag.
string $expiryFormFieldName
bool $watchlistExpiry
The value of the $wgWatchlistExpiry configuration variable.
static doUnwatch(PageIdentity $pageIdentity, Authority $performer)
Unwatch a page.
requiresUnblock()
Whether this action can still be executed by a blocked user.
static getExpiryOptionsFromMessage(MessageLocalizer $msgLocalizer, ?string $lang=null)
Parse expiry options message.
WatchlistManager $watchlistManager
getFormFields()
Get an HTMLForm descriptor array.
usesOOUI()
Whether the form should use OOUI.
static getWatchToken(PageIdentity $page, User $user, $action='watch')
Get token to watch (or unwatch) a page for a user.
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
false WatchedItem $watchedItem
static doWatchOrUnwatch( $watch, PageIdentity $pageIdentity, Authority $performer, string $expiry=null)
Watch or unwatch a page.
checkCanExecute(User $user)
Checks if the given user (identified by an object) can perform this action.
__construct(Page $page, IContextSource $context, WatchlistManager $watchlistManager, WatchedItemStore $watchedItemStore)
Only public since 1.21.
onSuccess()
Show one of 8 possible success messages.
onSubmit( $data)
Process the form on POST submission.
getName()
Return the name of the action this object responds to.
Storage layer class for WatchedItems.
getWatchedItem(UserIdentity $user, $target)
Representation of a pair of user and title for watchlist entries.
getExpiryInDaysText(MessageLocalizer $msgLocalizer, $isDropdownOption=false)
Get days remaining until a watched item expires as a text.
getExpiry(?int $style=TS_MW)
When the watched item will expire.
Type definition for expiry timestamps.
Definition ExpiryDef.php:17
static parseOptionsMessage(string $msg)
Parse labels and values out of a comma- and colon-separated list of options, such as is used for expi...
Interface for objects which can provide a MediaWiki context on request.
Interface for objects (potentially) representing an editable wiki page.
This interface represents the authority associated the current execution context, such as a web reque...
Definition Authority.php:37
getUser()
Returns the performer of the actions associated with this authority.
Interface for localizing messages in MediaWiki.
Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
Definition Page.php:29
if(!isset( $args[0])) $lang