MediaWiki master
ApiWatchlistTrait.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Api;
4
14
27
29 private $watchlistExpiryEnabled;
30
32 private $watchlistMaxDuration;
33
34 private ?WatchlistManager $watchlistManager = null;
35 private WatchedItemStoreInterface $watchedItemStore;
36 private ?UserOptionsLookup $userOptionsLookup = null;
37
38 private function initServices() {
39 // This trait is used outside of core and therefor fallback to global state - T263904
40 $this->watchlistManager ??= MediaWikiServices::getInstance()->getWatchlistManager();
41 $this->watchedItemStore ??= MediaWikiServices::getInstance()->getWatchedItemStore();
42 $this->userOptionsLookup ??= MediaWikiServices::getInstance()->getUserOptionsLookup();
43 }
44
55 protected function getWatchlistParams( array $watchOptions = [] ): array {
56 if ( !$watchOptions ) {
57 $watchOptions = [
58 'watch',
59 'unwatch',
60 'preferences',
61 'nochange',
62 ];
63 }
64
65 $result = [
66 'watchlist' => [
67 ParamValidator::PARAM_DEFAULT => 'preferences',
68 ParamValidator::PARAM_TYPE => $watchOptions,
69 ],
70 ];
71
72 if ( $this->watchlistExpiryEnabled ) {
73 $result['watchlistexpiry'] = [
74 ParamValidator::PARAM_TYPE => 'expiry',
75 ExpiryDef::PARAM_MAX => $this->watchlistMaxDuration,
76 ExpiryDef::PARAM_USE_MAX => true,
77 ];
78 }
79
80 return $result;
81 }
82
92 protected function setWatch(
93 string $watch,
94 PageIdentity $page,
95 User $user,
96 ?string $userOption = null,
97 ?string $expiry = null
98 ): void {
99 $value = $this->getWatchlistValue( $watch, $page, $user, $userOption );
100 $this->watchlistManager->setWatch( $value, $user, $page, $expiry );
101 }
102
112 protected function getWatchlistValue(
113 string $watchlist,
114 PageIdentity $page,
115 User $user,
116 ?string $userOption = null
117 ): bool {
118 $this->initServices();
119 $userWatching = $this->watchlistManager->isWatchedIgnoringRights( $user, $page );
120
121 switch ( $watchlist ) {
122 case 'watch':
123 return true;
124
125 case 'unwatch':
126 return false;
127
128 case 'preferences':
129 // If the user is already watching, don't bother checking
130 if ( $userWatching ) {
131 return true;
132 }
133 // If the user is a bot, act as 'nochange' to avoid big watchlists on single users
134 if ( $user->isBot() ) {
135 return $userWatching;
136 }
137 // If no user option was passed, use watchdefault and watchcreations
138 if ( $userOption === null ) {
139 return $this->userOptionsLookup->getBoolOption( $user, 'watchdefault' ) ||
140 ( $this->userOptionsLookup->getBoolOption( $user, 'watchcreations' ) && !$page->exists() );
141 }
142
143 // Watch the article based on the user preference
144 return $this->userOptionsLookup->getBoolOption( $user, $userOption );
145
146 // case 'nochange':
147 default:
148 return $userWatching;
149 }
150 }
151
163 protected function getExpiryFromParams(
164 array $params,
165 ?PageIdentity $page = null,
166 ?UserIdentity $user = null,
167 string $userOption = 'watchdefault-expiry'
168 ): ?string {
169 $watchlistExpiry = null;
170 if ( $this->watchlistExpiryEnabled ) {
171 // At this point, the ParamValidator has already normalized $params['watchlistexpiry'].
172 // Use the value provided in the API call, if any.
173 $watchlistExpiry = $params['watchlistexpiry'] ?? null;
174 // If expiry was not provided, and the user is already watching the page, keep the expiry value.
175 if ( $user && $page && $watchlistExpiry === null && $this->watchedItemStore->isWatched( $user, $page ) ) {
176 return $this->getWatchlistExpiry( $this->watchedItemStore, $page, $user );
177 }
178 // If the user is not watching the page, and expiry was not provided, use the default.
179 if ( $user && $watchlistExpiry === null ) {
180 $watchlistExpiry = ExpiryDef::normalizeExpiry(
181 $this->userOptionsLookup->getOption( $user, $userOption )
182 );
183 }
184 }
185
186 return ApiResult::formatExpiry( $watchlistExpiry );
187 }
188
197 protected function getWatchlistExpiry(
199 PageIdentity $page,
200 UserIdentity $user
201 ): ?string {
202 $watchedItem = $store->getWatchedItem( $user, $page );
203
204 if ( $watchedItem ) {
205 $expiry = $watchedItem->getExpiry();
206
207 if ( $expiry !== null ) {
208 return ApiResult::formatExpiry( $expiry );
209 }
210 }
211
212 return null;
213 }
214}
215
217class_alias( ApiWatchlistTrait::class, 'ApiWatchlistTrait' );
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:68
static formatExpiry( $expiry, $infinity='infinity')
Format an expiry timestamp for API output.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Provides access to user options.
User class for the MediaWiki software.
Definition User.php:130
Service for formatting and validating API parameters.
Type definition for expiry timestamps.
Definition ExpiryDef.php:18
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Interface for objects (potentially) representing an editable wiki page.
exists()
Checks if the page currently exists.
Interface for objects representing user identity.
setWatch(string $watch, PageIdentity $page, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
getWatchlistValue(string $watchlist, PageIdentity $page, User $user, ?string $userOption=null)
Return true if we're to watch the page, false if not.
getWatchlistParams(array $watchOptions=[])
Get additional allow params specific to watchlisting.
getExpiryFromParams(array $params, ?PageIdentity $page=null, ?UserIdentity $user=null, string $userOption='watchdefault-expiry')
Get formatted expiry from the given parameters.
getWatchlistExpiry(WatchedItemStoreInterface $store, PageIdentity $page, UserIdentity $user)
Get existing expiry from the database.