MediaWiki REL1_39
WatchAction.php
Go to the documentation of this file.
1<?php
26
32class WatchAction extends FormAction {
33
36
38 protected $expiryFormFieldName = 'expiry';
39
41 protected $watchedItem = false;
42
44 private $watchlistManager;
45
54 public function __construct(
55 Page $page,
56 IContextSource $context,
57 WatchlistManager $watchlistManager,
58 WatchedItemStore $watchedItemStore
59 ) {
60 parent::__construct( $page, $context );
61 $this->watchlistExpiry = $this->getContext()->getConfig()->get( MainConfigNames::WatchlistExpiry );
62 if ( $this->watchlistExpiry ) {
63 // The watchedItem is only used in this action's form if $wgWatchlistExpiry is enabled.
64 $this->watchedItem = $watchedItemStore->getWatchedItem(
65 $this->getUser(),
66 $this->getTitle()
67 );
68 }
69 $this->watchlistManager = $watchlistManager;
70 }
71
72 public function getName() {
73 return 'watch';
74 }
75
76 public function requiresUnblock() {
77 return false;
78 }
79
80 protected function getDescription() {
81 return '';
82 }
83
84 public function onSubmit( $data ) {
85 // Even though we're never unwatching here, use WatchlistManager::setWatch()
86 // because it also checks for changed expiry.
87 $result = $this->watchlistManager->setWatch(
88 true,
89 $this->getAuthority(),
90 $this->getTitle(),
91 $this->getRequest()->getVal( 'wp' . $this->expiryFormFieldName )
92 );
93
94 return Status::wrap( $result );
95 }
96
97 protected function checkCanExecute( User $user ) {
98 if ( !$user->isNamed() ) {
99 throw new UserNotLoggedIn( 'watchlistanontext', 'watchnologin' );
100 }
101
102 parent::checkCanExecute( $user );
103 }
104
105 protected function usesOOUI() {
106 return true;
107 }
108
109 protected function getFormFields() {
110 // If watchlist expiry is not enabled, return a simple confirmation message.
111 if ( !$this->watchlistExpiry ) {
112 return [
113 'intro' => [
114 'type' => 'info',
115 'raw' => true,
116 'default' => $this->msg( 'confirm-watch-top' )->parse(),
117 ],
118 ];
119 }
120
121 // Otherwise, use a select-list of expiries.
122 $expiryOptions = static::getExpiryOptions( $this->getContext(), $this->watchedItem );
123 return [
124 $this->expiryFormFieldName => [
125 'type' => 'select',
126 'label-message' => 'confirm-watch-label',
127 'options' => $expiryOptions['options'],
128 'default' => $expiryOptions['default'],
129 ]
130 ];
131 }
132
145 public static function getExpiryOptions( MessageLocalizer $msgLocalizer, $watchedItem ) {
146 $expiryOptions = self::getExpiryOptionsFromMessage( $msgLocalizer );
147 $default = in_array( 'infinite', $expiryOptions )
148 ? 'infinite'
149 : current( $expiryOptions );
150 if ( $watchedItem instanceof WatchedItem && $watchedItem->getExpiry() ) {
151 // If it's already being temporarily watched,
152 // add the existing expiry as the default option in the dropdown.
153 $default = $watchedItem->getExpiry( TS_ISO_8601 );
154 $daysLeft = $watchedItem->getExpiryInDaysText( $msgLocalizer, true );
155 $expiryOptions = array_merge( [ $daysLeft => $default ], $expiryOptions );
156 }
157 return [
158 'options' => $expiryOptions,
159 'default' => $default,
160 ];
161 }
162
171 private static function getExpiryOptionsFromMessage(
172 MessageLocalizer $msgLocalizer, ?string $lang = null
173 ): array {
174 $expiryOptionsMsg = $msgLocalizer->msg( 'watchlist-expiry-options' );
175 $optionsText = !$lang ? $expiryOptionsMsg->text() : $expiryOptionsMsg->inLanguage( $lang )->text();
177 $optionsText
178 );
179
180 $expiryOptions = [];
181 foreach ( $options as $label => $value ) {
182 if ( strtotime( $value ) || wfIsInfinity( $value ) ) {
183 $expiryOptions[$label] = $value;
184 }
185 }
186
187 // If message options is invalid try to recover by returning
188 // english options (T267611)
189 if ( !$expiryOptions && $expiryOptionsMsg->getLanguage()->getCode() !== 'en' ) {
190 return self::getExpiryOptionsFromMessage( $msgLocalizer, 'en' );
191 }
192
193 return $expiryOptions;
194 }
195
196 protected function alterForm( HTMLForm $form ) {
197 $msg = $this->watchlistExpiry && $this->watchedItem ? 'updatewatchlist' : 'addwatch';
198 $form->setWrapperLegendMsg( $msg );
199 $submitMsg = $this->watchlistExpiry ? 'confirm-watch-button-expiry' : 'confirm-watch-button';
200 $form->setSubmitTextMsg( $submitMsg );
201 $form->setTokenSalt( 'watch' );
202 }
203
216 public function onSuccess() {
217 $msgKey = $this->getTitle()->isTalkPage() ? 'addedwatchtext-talk' : 'addedwatchtext';
218 $expiryLabel = null;
219 $submittedExpiry = $this->getContext()->getRequest()->getText( 'wp' . $this->expiryFormFieldName );
220 if ( $submittedExpiry ) {
221 // We can't use $this->watcheditem to get the expiry because it's not been saved at this
222 // point in the request and so its values are those from before saving.
223 $expiry = ExpiryDef::normalizeExpiry( $submittedExpiry, TS_ISO_8601 );
224
225 // If the expiry label isn't one of the predefined ones in the dropdown, calculate 'x days'.
226 $expiryDays = WatchedItem::calculateExpiryInDays( $expiry );
227 $defaultLabels = static::getExpiryOptions( $this->getContext(), false )['options'];
228 $localizedExpiry = array_search( $submittedExpiry, $defaultLabels );
229 $expiryLabel = $expiryDays && $localizedExpiry === false
230 ? $this->getContext()->msg( 'days', $expiryDays )->text()
231 : $localizedExpiry;
232
233 // Determine which message to use, depending on whether this is a talk page or not
234 // and whether an expiry was selected.
235 $isTalk = $this->getTitle()->isTalkPage();
236 if ( wfIsInfinity( $expiry ) ) {
237 $msgKey = $isTalk ? 'addedwatchindefinitelytext-talk' : 'addedwatchindefinitelytext';
238 } elseif ( $expiryDays > 0 ) {
239 $msgKey = $isTalk ? 'addedwatchexpirytext-talk' : 'addedwatchexpirytext';
240 } elseif ( $expiryDays < 1 ) {
241 $msgKey = $isTalk ? 'addedwatchexpiryhours-talk' : 'addedwatchexpiryhours';
242 }
243 }
244 $this->getOutput()->addWikiMsg( $msgKey, $this->getTitle()->getPrefixedText(), $expiryLabel );
245 }
246
247 public function doesWrites() {
248 return true;
249 }
250}
getUser()
getAuthority()
wfIsInfinity( $str)
Determine input string is represents as infinity.
getContext()
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition Action.php:242
getRequest()
Get the WebRequest being used for this instance.
Definition Action.php:150
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:150
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.
A class containing constants representing the names of configuration variables.
Redirect a user to the login page.
internal since 1.36
Definition User.php:70
isNamed()
Is the user a normal non-temporary registered user?
Definition User.php:3563
Page addition to a user's watchlist.
static getExpiryOptions(MessageLocalizer $msgLocalizer, $watchedItem)
Get options and default for a watchlist expiry select list.
getDescription()
Returns the description that goes below the <h1> element.
string $expiryFormFieldName
bool $watchlistExpiry
The value of the $wgWatchlistExpiry configuration variable.
requiresUnblock()
Whether this action can still be executed by a blocked user.
getFormFields()
Get an HTMLForm descriptor array.
usesOOUI()
Whether the form should use OOUI.
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
false WatchedItem $watchedItem
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 localizing messages in MediaWiki.
Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
Definition Page.php:29
if(!isset( $args[0])) $lang