MediaWiki  master
UserOptionsManager.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\User;
22 
24 use HTMLCheckMatrix;
25 use HTMLFormField;
27 use IContextSource;
28 use InvalidArgumentException;
29 use LanguageCode;
35 use Psr\Log\LoggerInterface;
36 use User;
38 
44 
48  public const CONSTRUCTOR_OPTIONS = [
49  'HiddenPrefs',
50  'LocalTZoffset',
51  ];
52 
54  private $serviceOptions;
55 
58 
61 
63  private $loadBalancer;
64 
66  private $logger;
67 
69  private $modifiedOptions = [];
70 
76  private $originalOptionsCache = [];
77 
82  private $optionsFromDb = [];
83 
85  private $hookRunner;
86 
89 
98  public function __construct(
99  ServiceOptions $options,
103  LoggerInterface $logger,
104  HookContainer $hookContainer
105  ) {
106  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
107  $this->serviceOptions = $options;
108  $this->defaultOptionsLookup = $defaultOptionsLookup;
109  $this->languageConverterFactory = $languageConverterFactory;
110  $this->loadBalancer = $loadBalancer;
111  $this->logger = $logger;
112  $this->hookRunner = new HookRunner( $hookContainer );
113  }
114 
118  public function getDefaultOptions(): array {
119  return $this->defaultOptionsLookup->getDefaultOptions();
120  }
121 
125  public function getOption(
126  UserIdentity $user,
127  string $oname,
128  $defaultOverride = null,
129  bool $ignoreHidden = false,
130  int $queryFlags = self::READ_NORMAL
131  ) {
132  # We want 'disabled' preferences to always behave as the default value for
133  # users, even if they have set the option explicitly in their settings (ie they
134  # set it, and then it was disabled removing their ability to change it). But
135  # we don't want to erase the preferences in the database in case the preference
136  # is re-enabled again. So don't touch $mOptions, just override the returned value
137  if ( !$ignoreHidden && in_array( $oname, $this->serviceOptions->get( 'HiddenPrefs' ) ) ) {
138  return $this->defaultOptionsLookup->getDefaultOption( $oname );
139  }
140 
141  $options = $this->loadUserOptions( $user, $queryFlags );
142  if ( array_key_exists( $oname, $options ) ) {
143  return $options[$oname];
144  }
145  return $defaultOverride;
146  }
147 
151  public function getOptions(
152  UserIdentity $user,
153  int $flags = 0,
154  int $queryFlags = self::READ_NORMAL
155  ): array {
156  $options = $this->loadUserOptions( $user, $queryFlags );
157 
158  # We want 'disabled' preferences to always behave as the default value for
159  # users, even if they have set the option explicitly in their settings (ie they
160  # set it, and then it was disabled removing their ability to change it). But
161  # we don't want to erase the preferences in the database in case the preference
162  # is re-enabled again. So don't touch $mOptions, just override the returned value
163  foreach ( $this->serviceOptions->get( 'HiddenPrefs' ) as $pref ) {
164  $default = $this->defaultOptionsLookup->getDefaultOption( $pref );
165  if ( $default !== null ) {
166  $options[$pref] = $default;
167  }
168  }
169 
170  if ( $flags & self::EXCLUDE_DEFAULTS ) {
171  $options = array_diff_assoc( $options, $this->defaultOptionsLookup->getDefaultOptions() );
172  }
173 
174  return $options;
175  }
176 
186  public function setOption( UserIdentity $user, string $oname, $val ) {
187  // Explicitly NULL values should refer to defaults
188  if ( $val === null ) {
189  $val = $this->defaultOptionsLookup->getDefaultOption( $oname );
190  }
191  $this->modifiedOptions[$this->getCacheKey( $user )][$oname] = $val;
192  }
193 
208  public function resetOptions(
209  UserIdentity $user,
211  $resetKinds = [ 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' ]
212  ) {
213  $oldOptions = $this->loadUserOptions( $user, self::READ_LATEST );
214  $defaultOptions = $this->defaultOptionsLookup->getDefaultOptions();
215 
216  if ( !is_array( $resetKinds ) ) {
217  $resetKinds = [ $resetKinds ];
218  }
219 
220  if ( in_array( 'all', $resetKinds ) ) {
221  $newOptions = $defaultOptions + array_fill_keys( array_keys( $oldOptions ), null );
222  } else {
223  $optionKinds = $this->getOptionKinds( $user, $context );
224  $resetKinds = array_intersect( $resetKinds, $this->listOptionKinds() );
225  $newOptions = [];
226 
227  // Use default values for the options that should be deleted, and
228  // copy old values for the ones that shouldn't.
229  foreach ( $oldOptions as $key => $value ) {
230  if ( in_array( $optionKinds[$key], $resetKinds ) ) {
231  if ( array_key_exists( $key, $defaultOptions ) ) {
232  $newOptions[$key] = $defaultOptions[$key];
233  }
234  } else {
235  $newOptions[$key] = $value;
236  }
237  }
238  }
239 
240  // TODO: Deprecate passing full user to the hook
241  $this->hookRunner->onUserResetAllOptions(
242  User::newFromIdentity( $user ), $newOptions, $oldOptions, $resetKinds
243  );
244 
245  $this->modifiedOptions[$this->getCacheKey( $user )] = $newOptions;
246  }
247 
271  public function listOptionKinds(): array {
272  return [
273  'registered',
274  'registered-multiselect',
275  'registered-checkmatrix',
276  'userjs',
277  'special',
278  'unused'
279  ];
280  }
281 
295  public function getOptionKinds(
296  UserIdentity $userIdentity,
298  $options = null
299  ): array {
300  if ( $options === null ) {
301  $options = $this->loadUserOptions( $userIdentity );
302  }
303 
304  // TODO: injecting the preferences factory creates a cyclic dependency between
305  // PreferencesFactory and UserOptionsManager. See T250822
306  $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
307  $user = User::newFromIdentity( $userIdentity );
308  $prefs = $preferencesFactory->getFormDescriptor( $user, $context );
309  $mapping = [];
310 
311  // Pull out the "special" options, so they don't get converted as
312  // multiselect or checkmatrix.
313  $specialOptions = array_fill_keys( $preferencesFactory->getSaveBlacklist(), true );
314  foreach ( $specialOptions as $name => $value ) {
315  unset( $prefs[$name] );
316  }
317 
318  // Multiselect and checkmatrix options are stored in the database with
319  // one key per option, each having a boolean value. Extract those keys.
320  $multiselectOptions = [];
321  foreach ( $prefs as $name => $info ) {
322  if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
323  ( isset( $info['class'] ) && $info['class'] == HTMLMultiSelectField::class )
324  ) {
325  $opts = HTMLFormField::flattenOptions( $info['options'] ?? $info['options-messages'] );
326  $prefix = $info['prefix'] ?? $name;
327 
328  foreach ( $opts as $value ) {
329  $multiselectOptions["$prefix$value"] = true;
330  }
331 
332  unset( $prefs[$name] );
333  }
334  }
335  $checkmatrixOptions = [];
336  foreach ( $prefs as $name => $info ) {
337  if ( ( isset( $info['type'] ) && $info['type'] == 'checkmatrix' ) ||
338  ( isset( $info['class'] ) && $info['class'] == HTMLCheckMatrix::class )
339  ) {
340  $columns = HTMLFormField::flattenOptions( $info['columns'] );
341  $rows = HTMLFormField::flattenOptions( $info['rows'] );
342  $prefix = $info['prefix'] ?? $name;
343 
344  foreach ( $columns as $column ) {
345  foreach ( $rows as $row ) {
346  $checkmatrixOptions["$prefix$column-$row"] = true;
347  }
348  }
349 
350  unset( $prefs[$name] );
351  }
352  }
353 
354  // $value is ignored
355  foreach ( $options as $key => $value ) {
356  if ( isset( $prefs[$key] ) ) {
357  $mapping[$key] = 'registered';
358  } elseif ( isset( $multiselectOptions[$key] ) ) {
359  $mapping[$key] = 'registered-multiselect';
360  } elseif ( isset( $checkmatrixOptions[$key] ) ) {
361  $mapping[$key] = 'registered-checkmatrix';
362  } elseif ( isset( $specialOptions[$key] ) ) {
363  $mapping[$key] = 'special';
364  } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
365  $mapping[$key] = 'userjs';
366  } else {
367  $mapping[$key] = 'unused';
368  }
369  }
370 
371  return $mapping;
372  }
373 
381  public function saveOptions( UserIdentity $user ) {
382  if ( !$user->isRegistered() ) {
383  throw new InvalidArgumentException( __METHOD__ . ' was called on anon user' );
384  }
385 
386  $userKey = $this->getCacheKey( $user );
387  $modifiedOptions = $this->modifiedOptions[$userKey] ?? [];
388  $originalOptions = $this->loadOriginalOptions( $user, self::READ_LATEST );
389  if ( !$this->hookRunner->onSaveUserOptions( $user, $modifiedOptions, $originalOptions ) ) {
390  return;
391  }
392 
393  // TODO: only needed for old hook.
394  $optionsToSave = array_merge( $originalOptions, $modifiedOptions );
395  // Allow hooks to abort, for instance to save to a global profile.
396  // Reset options to default state before saving.
397  if ( !$this->hookRunner->onUserSaveOptions(
398  User::newFromIdentity( $user ), $optionsToSave, $originalOptions )
399  ) {
400  return;
401  }
402 
403  // Delete any rows that were in the DB but are not in $optionsToSave
404  $keysToDelete = array_keys(
405  array_diff_key( $this->optionsFromDb[$userKey], $optionsToSave )
406  );
407 
408  // Update rows that have changed
409  $userId = $user->getId();
410  $rowsToInsert = []; // all the new preference rows
411  $rowsToPreserve = [];
412  foreach ( $optionsToSave as $key => $value ) {
413  // Don't store unchanged or default values
414  $defaultValue = $this->defaultOptionsLookup->getDefaultOption( $key );
415  $oldValue = $this->optionsFromDb[$userKey][$key] ?? null;
416  if ( !$this->isValueEqual( $value, $defaultValue ) ) {
417  $row = [
418  'up_user' => $userId,
419  'up_property' => $key,
420  'up_value' => $value,
421  ];
422  if ( !$this->isValueEqual( $value, $oldValue ) ) {
423  // Update by deleting and reinserting
424  $rowsToInsert[] = $row;
425  if ( $oldValue !== null ) {
426  $keysToDelete[] = $key;
427  }
428  } else {
429  // Preserve old value -- save the row for caching
430  $rowsToPreserve[] = $row;
431  }
432  } elseif ( $oldValue !== null ) {
433  // Delete row that is being set to its default
434  $keysToDelete[] = $key;
435  }
436  }
437 
438  if ( !count( $keysToDelete ) && !count( $rowsToInsert ) ) {
439  // Nothing to do
440  return;
441  }
442 
443  // Do the DELETE
444  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
445  if ( $keysToDelete ) {
446  $dbw->delete(
447  'user_properties',
448  [
449  'up_user' => $userId,
450  'up_property' => $keysToDelete
451  ],
452  __METHOD__
453  );
454  }
455  if ( $rowsToInsert ) {
456  // Insert the new preference rows
457  $dbw->insert( 'user_properties', $rowsToInsert, __METHOD__, [ 'IGNORE' ] );
458  }
459 
460  // We are storing these into the database, so that's what we will get if we fetch again
461  // So, set the just saved options to the cache, but don't prevent some other part of the
462  // code from locking the options again but saying READ_LATEST was used for caching.
463  $this->setOptionsFromDb( $user, self::READ_LATEST,
464  array_merge( $rowsToPreserve, $rowsToInsert ) );
465 
466  // It's pretty cheap to recalculate new original later
467  // to apply whatever adjustments we apply when fetching from DB
468  // and re-merge with the defaults.
469  unset( $this->originalOptionsCache[$userKey] );
470  // And nothing is modified anymore
471  unset( $this->modifiedOptions[$userKey] );
472  }
473 
488  public function loadUserOptions(
489  UserIdentity $user,
490  int $queryFlags = self::READ_NORMAL,
491  array $data = null
492  ): array {
493  $userKey = $this->getCacheKey( $user );
494  $originalOptions = $this->loadOriginalOptions( $user, $queryFlags, $data );
495  return array_merge( $originalOptions, $this->modifiedOptions[$userKey] ?? [] );
496  }
497 
503  public function clearUserOptionsCache( UserIdentity $user ) {
504  $cacheKey = $this->getCacheKey( $user );
505  unset( $this->modifiedOptions[$cacheKey] );
506  unset( $this->optionsFromDb[$cacheKey] );
507  unset( $this->originalOptionsCache[$cacheKey] );
508  unset( $this->queryFlagsUsedForCaching[$cacheKey] );
509  }
510 
519  private function loadOptionsFromDb(
520  UserIdentity $user,
521  int $queryFlags,
522  array $prefetchedOptions = null
523  ): array {
524  if ( $prefetchedOptions === null ) {
525  $this->logger->debug( 'Loading options from database', [ 'user_id' => $user->getId() ] );
526  [ $dbr, $options ] = $this->getDBAndOptionsForQueryFlags( $queryFlags );
527  $res = $dbr->select(
528  'user_properties',
529  [ 'up_property', 'up_value' ],
530  [ 'up_user' => $user->getId() ],
531  __METHOD__,
532  $options
533  );
534  } else {
535  $res = [];
536  foreach ( $prefetchedOptions as $name => $value ) {
537  $res[] = [
538  'up_property' => $name,
539  'up_value' => $value,
540  ];
541  }
542  }
543  return $this->setOptionsFromDb( $user, $queryFlags, $res );
544  }
545 
554  private function setOptionsFromDb(
555  UserIdentity $user,
556  int $queryFlags,
557  iterable $rows
558  ): array {
559  $userKey = $this->getCacheKey( $user );
560  $options = [];
561  foreach ( $rows as $row ) {
562  $row = (object)$row;
563  // Convert '0' to 0. PHP's boolean conversion considers them both
564  // false, but e.g. JavaScript considers the former as true.
565  // @todo: T54542 Somehow determine the desired type (string/int/bool)
566  // and convert all values here.
567  if ( $row->up_value === '0' ) {
568  $row->up_value = 0;
569  }
570  $options[$row->up_property] = $row->up_value;
571  }
572  $this->optionsFromDb[$userKey] = $options;
573  $this->queryFlagsUsedForCaching[$userKey] = $queryFlags;
574  return $options;
575  }
576 
586  private function loadOriginalOptions(
587  UserIdentity $user,
588  int $queryFlags = self::READ_NORMAL,
589  array $data = null
590  ): array {
591  $userKey = $this->getCacheKey( $user );
592  $defaultOptions = $this->defaultOptionsLookup->getDefaultOptions();
593  if ( !$user->isRegistered() ) {
594  // For unlogged-in users, load language/variant options from request.
595  // There's no need to do it for logged-in users: they can set preferences,
596  // and handling of page content is done by $pageLang->getPreferredVariant() and such,
597  // so don't override user's choice (especially when the user chooses site default).
598  $variant = $this->languageConverterFactory->getLanguageConverter()->getDefaultVariant();
599  $defaultOptions['variant'] = $variant;
600  $defaultOptions['language'] = $variant;
601  $this->originalOptionsCache[$userKey] = $defaultOptions;
602  return $defaultOptions;
603  }
604 
605  // In case options were already loaded from the database before and no options
606  // changes were saved to the database, we can use the cached original options.
607  if ( $this->canUseCachedValues( $user, $queryFlags )
608  && isset( $this->originalOptionsCache[$userKey] )
609  ) {
610  return $this->originalOptionsCache[$userKey];
611  }
612 
613  $options = $this->loadOptionsFromDb( $user, $queryFlags, $data ) + $defaultOptions;
614  // Replace deprecated language codes
615  $options['language'] = LanguageCode::replaceDeprecatedCodes( $options['language'] );
616  // Fix up timezone offset (Due to DST it can change from what was stored in the DB)
617  // ZoneInfo|offset|TimeZoneName
618  if ( isset( $options['timecorrection'] ) ) {
619  $options['timecorrection'] = ( new UserTimeCorrection(
620  $options['timecorrection'],
621  null,
622  $this->serviceOptions->get( 'LocalTZoffset' )
623  ) )->toString();
624  }
625 
626  // Need to store what we have so far before the hook to prevent
627  // infinite recursion if the hook attempts to reload options
628  $this->originalOptionsCache[$userKey] = $options;
629  $this->queryFlagsUsedForCaching[$userKey] = $queryFlags;
630  // TODO: Remove deprecated hook.
631  $this->hookRunner->onUserLoadOptions(
632  User::newFromIdentity( $user ), $options
633  );
634  $this->hookRunner->onLoadUserOptions( $user, $options );
635  $this->originalOptionsCache[$userKey] = $options;
636  return $options;
637  }
638 
644  private function getCacheKey( UserIdentity $user ): string {
645  return $user->isRegistered() ? "u:{$user->getId()}" : 'anon';
646  }
647 
652  private function getDBAndOptionsForQueryFlags( $queryFlags ): array {
653  list( $mode, $options ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
654  return [ $this->loadBalancer->getConnectionRef( $mode, [] ), $options ];
655  }
656 
663  private function canUseCachedValues( UserIdentity $user, int $queryFlags ): bool {
664  if ( !$user->isRegistered() ) {
665  // Anon users don't have options stored in the database,
666  // so $queryFlags are ignored.
667  return true;
668  }
669  $userKey = $this->getCacheKey( $user );
670  $queryFlagsUsed = $this->queryFlagsUsedForCaching[$userKey] ?? self::READ_NONE;
671  return $queryFlagsUsed >= $queryFlags;
672  }
673 
683  private function isValueEqual( $a, $b ) {
684  if ( is_bool( $a ) ) {
685  $a = (int)$a;
686  }
687  if ( is_bool( $b ) ) {
688  $b = (int)$b;
689  }
690  return (string)$a === (string)$b;
691  }
692 }
MediaWiki\User\UserOptionsManager\setOption
setOption(UserIdentity $user, string $oname, $val)
Set the given option for a user.
Definition: UserOptionsManager.php:186
LanguageCode\replaceDeprecatedCodes
static replaceDeprecatedCodes( $code)
Replace deprecated language codes that were used in previous versions of MediaWiki to up-to-date,...
Definition: LanguageCode.php:161
MediaWiki\User\UserTimeCorrection
Utility class to parse the TimeCorrection string value.
Definition: UserTimeCorrection.php:41
MediaWiki\User\UserOptionsManager\$modifiedOptions
array $modifiedOptions
options modified withing this request
Definition: UserOptionsManager.php:69
MediaWiki\User\UserOptionsManager\isValueEqual
isValueEqual( $a, $b)
Determines whether two values are sufficiently similar that the database does not need to be updated ...
Definition: UserOptionsManager.php:683
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:186
MediaWiki\User\UserOptionsManager\saveOptions
saveOptions(UserIdentity $user)
Saves the non-default options for this user, as previously set e.g.
Definition: UserOptionsManager.php:381
MediaWiki\User\UserOptionsManager\$optionsFromDb
array $optionsFromDb
Cached original user options as fetched from database, no adjustments applied.
Definition: UserOptionsManager.php:82
MediaWiki\User\UserOptionsManager\getDefaultOptions
getDefaultOptions()
Combine the language default options with any site-specific options and add the default language vari...
Definition: UserOptionsManager.php:118
MediaWiki\User\UserOptionsManager\$hookRunner
HookRunner $hookRunner
Definition: UserOptionsManager.php:85
MediaWiki\User\UserOptionsManager\getOptions
getOptions(UserIdentity $user, int $flags=0, int $queryFlags=self::READ_NORMAL)
Get all user's options.The user to get the option for Bitwise combination of: UserOptionsManager::EXC...
Definition: UserOptionsManager.php:151
User\newFromIdentity
static newFromIdentity(UserIdentity $identity)
Returns a User object corresponding to the given UserIdentity.
Definition: User.php:679
MediaWiki\User\UserIdentity\getId
getId( $wikiId=self::LOCAL)
DBAccessObjectUtils\getDBOptions
static getDBOptions( $bitfield)
Get an appropriate DB index, options, and fallback DB index for a query.
Definition: DBAccessObjectUtils.php:52
$res
$res
Definition: testCompression.php:57
MediaWiki\Languages\LanguageConverterFactory
An interface for creating language converters.
Definition: LanguageConverterFactory.php:46
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
MediaWiki\User\UserOptionsManager\listOptionKinds
listOptionKinds()
Return a list of the types of user options currently returned by UserOptionsManager::getOptionKinds()...
Definition: UserOptionsManager.php:271
MediaWiki\User\UserOptionsManager\getOption
getOption(UserIdentity $user, string $oname, $defaultOverride=null, bool $ignoreHidden=false, int $queryFlags=self::READ_NORMAL)
Get the user's current setting for a given option.The user to get the option for The option to check ...
Definition: UserOptionsManager.php:125
$dbr
$dbr
Definition: testCompression.php:54
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:247
MediaWiki\User\DefaultOptionsLookup
A service class to control default user options.
Definition: DefaultOptionsLookup.php:35
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
MediaWiki\User\UserOptionsManager\$loadBalancer
ILoadBalancer $loadBalancer
Definition: UserOptionsManager.php:63
MediaWiki\User\UserIdentity\isRegistered
isRegistered()
MediaWiki\User\UserOptionsManager\getCacheKey
getCacheKey(UserIdentity $user)
Gets a key for various caches.
Definition: UserOptionsManager.php:644
MediaWiki\User\UserOptionsManager\$originalOptionsCache
array $originalOptionsCache
Cached original user options with all the adjustments like time correction and hook changes applied.
Definition: UserOptionsManager.php:76
HTMLFormField
The parent class to generate form fields.
Definition: HTMLFormField.php:11
MediaWiki\User\UserOptionsManager\getDBAndOptionsForQueryFlags
getDBAndOptionsForQueryFlags( $queryFlags)
Definition: UserOptionsManager.php:652
MediaWiki\User\UserOptionsManager\clearUserOptionsCache
clearUserOptionsCache(UserIdentity $user)
Clears cached user options.
Definition: UserOptionsManager.php:503
MediaWiki\User\UserOptionsManager\$defaultOptionsLookup
DefaultOptionsLookup $defaultOptionsLookup
Definition: UserOptionsManager.php:57
MediaWiki\User\UserOptionsManager\getOptionKinds
getOptionKinds(UserIdentity $userIdentity, IContextSource $context, $options=null)
Return an associative array mapping preferences keys to the kind of a preference they're used for.
Definition: UserOptionsManager.php:295
IDBAccessObject\READ_NONE
const READ_NONE
Constants for object loading bitfield flags (higher => higher QoS)
Definition: IDBAccessObject.php:75
DBAccessObjectUtils
Helper class for DAO classes.
Definition: DBAccessObjectUtils.php:29
MediaWiki\User\UserOptionsManager\$queryFlagsUsedForCaching
array $queryFlagsUsedForCaching
Query flags used to retrieve options from database.
Definition: UserOptionsManager.php:88
MediaWiki\User\UserOptionsManager\loadUserOptions
loadUserOptions(UserIdentity $user, int $queryFlags=self::READ_NORMAL, array $data=null)
Loads user options either from cache or from the database.
Definition: UserOptionsManager.php:488
MediaWiki\User\UserOptionsManager\resetOptions
resetOptions(UserIdentity $user, IContextSource $context, $resetKinds=[ 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused'])
Reset certain (or all) options to the site defaults.
Definition: UserOptionsManager.php:208
MediaWiki\User\UserOptionsManager\$logger
LoggerInterface $logger
Definition: UserOptionsManager.php:66
DB_PRIMARY
const DB_PRIMARY
Definition: defines.php:27
MediaWiki\User
Definition: ActorCache.php:21
MediaWiki\User\UserOptionsLookup
Provides access to user options.
Definition: UserOptionsLookup.php:29
MediaWiki\User\UserOptionsManager\$serviceOptions
ServiceOptions $serviceOptions
Definition: UserOptionsManager.php:54
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
MediaWiki\User\UserOptionsManager
A service class to control user options.
Definition: UserOptionsManager.php:43
HTMLCheckMatrix
A checkbox matrix Operates similarly to HTMLMultiSelectField, but instead of using an array of option...
Definition: HTMLCheckMatrix.php:27
MediaWiki\User\UserOptionsManager\$languageConverterFactory
LanguageConverterFactory $languageConverterFactory
Definition: UserOptionsManager.php:60
HTMLMultiSelectField
Multi-select field.
Definition: HTMLMultiSelectField.php:8
MediaWiki\User\UserOptionsManager\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: UserOptionsManager.php:48
MediaWiki\User\UserOptionsManager\loadOriginalOptions
loadOriginalOptions(UserIdentity $user, int $queryFlags=self::READ_NORMAL, array $data=null)
Loads the original user options from the database and applies various transforms, like timecorrection...
Definition: UserOptionsManager.php:586
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
LanguageCode
Methods for dealing with language codes.
Definition: LanguageCode.php:27
HTMLFormField\flattenOptions
static flattenOptions( $options)
flatten an array of options to a single array, for instance, a set of "<options>" inside "<optgroups>...
Definition: HTMLFormField.php:1157
MediaWiki\User\UserOptionsManager\canUseCachedValues
canUseCachedValues(UserIdentity $user, int $queryFlags)
Determines if it's ok to use cached options values for a given user and query flags.
Definition: UserOptionsManager.php:663
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:554
MediaWiki\User\UserOptionsManager\loadOptionsFromDb
loadOptionsFromDb(UserIdentity $user, int $queryFlags, array $prefetchedOptions=null)
Fetches the options directly from the database with no caches.
Definition: UserOptionsManager.php:519
MediaWiki\$context
IContextSource $context
Definition: MediaWiki.php:40
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
MediaWiki\User\UserOptionsManager\setOptionsFromDb
setOptionsFromDb(UserIdentity $user, int $queryFlags, iterable $rows)
Builds associative options array from rows fetched from DB.
Definition: UserOptionsManager.php:554
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71
MediaWiki\User\UserOptionsManager\__construct
__construct(ServiceOptions $options, DefaultOptionsLookup $defaultOptionsLookup, LanguageConverterFactory $languageConverterFactory, ILoadBalancer $loadBalancer, LoggerInterface $logger, HookContainer $hookContainer)
Definition: UserOptionsManager.php:98