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;
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 $userFactory;
67 
69  private $logger;
70 
72  private $modifiedOptions = [];
73 
79  private $originalOptionsCache = [];
80 
85  private $optionsFromDb = [];
86 
88  private $hookRunner;
89 
92 
102  public function __construct(
103  ServiceOptions $options,
107  LoggerInterface $logger,
108  HookContainer $hookContainer,
110  ) {
111  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
112  $this->serviceOptions = $options;
113  $this->defaultOptionsLookup = $defaultOptionsLookup;
114  $this->languageConverterFactory = $languageConverterFactory;
115  $this->loadBalancer = $loadBalancer;
116  $this->logger = $logger;
117  $this->hookRunner = new HookRunner( $hookContainer );
118  $this->userFactory = $userFactory;
119  }
120 
124  public function getDefaultOptions(): array {
125  return $this->defaultOptionsLookup->getDefaultOptions();
126  }
127 
131  public function getOption(
132  UserIdentity $user,
133  string $oname,
134  $defaultOverride = null,
135  bool $ignoreHidden = false,
136  int $queryFlags = self::READ_NORMAL
137  ) {
138  # We want 'disabled' preferences to always behave as the default value for
139  # users, even if they have set the option explicitly in their settings (ie they
140  # set it, and then it was disabled removing their ability to change it). But
141  # we don't want to erase the preferences in the database in case the preference
142  # is re-enabled again. So don't touch $mOptions, just override the returned value
143  if ( !$ignoreHidden && in_array( $oname, $this->serviceOptions->get( 'HiddenPrefs' ) ) ) {
144  return $this->defaultOptionsLookup->getDefaultOption( $oname );
145  }
146 
147  $options = $this->loadUserOptions( $user, $queryFlags );
148  if ( array_key_exists( $oname, $options ) ) {
149  return $options[$oname];
150  }
151  return $defaultOverride;
152  }
153 
157  public function getOptions(
158  UserIdentity $user,
159  int $flags = 0,
160  int $queryFlags = self::READ_NORMAL
161  ): array {
162  $options = $this->loadUserOptions( $user, $queryFlags );
163 
164  # We want 'disabled' preferences to always behave as the default value for
165  # users, even if they have set the option explicitly in their settings (ie they
166  # set it, and then it was disabled removing their ability to change it). But
167  # we don't want to erase the preferences in the database in case the preference
168  # is re-enabled again. So don't touch $mOptions, just override the returned value
169  foreach ( $this->serviceOptions->get( 'HiddenPrefs' ) as $pref ) {
170  $default = $this->defaultOptionsLookup->getDefaultOption( $pref );
171  if ( $default !== null ) {
172  $options[$pref] = $default;
173  }
174  }
175 
176  if ( $flags & self::EXCLUDE_DEFAULTS ) {
177  $defaultOptions = $this->defaultOptionsLookup->getDefaultOptions();
178  foreach ( $options as $option => $value ) {
179  if ( array_key_exists( $option, $defaultOptions )
180  && $this->isValueEqual( $value, $defaultOptions[$option] )
181  ) {
182  unset( $options[$option] );
183  }
184  }
185  }
186 
187  return $options;
188  }
189 
199  public function setOption( UserIdentity $user, string $oname, $val ) {
200  // Explicitly NULL values should refer to defaults
201  if ( $val === null ) {
202  $val = $this->defaultOptionsLookup->getDefaultOption( $oname );
203  }
204  $this->modifiedOptions[$this->getCacheKey( $user )][$oname] = $val;
205  }
206 
221  public function resetOptions(
222  UserIdentity $user,
224  $resetKinds = [ 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused' ]
225  ) {
226  $oldOptions = $this->loadUserOptions( $user, self::READ_LATEST );
227  $defaultOptions = $this->defaultOptionsLookup->getDefaultOptions();
228 
229  if ( !is_array( $resetKinds ) ) {
230  $resetKinds = [ $resetKinds ];
231  }
232 
233  if ( in_array( 'all', $resetKinds ) ) {
234  $newOptions = $defaultOptions + array_fill_keys( array_keys( $oldOptions ), null );
235  } else {
236  $optionKinds = $this->getOptionKinds( $user, $context );
237  $resetKinds = array_intersect( $resetKinds, $this->listOptionKinds() );
238  $newOptions = [];
239 
240  // Use default values for the options that should be deleted, and
241  // copy old values for the ones that shouldn't.
242  foreach ( $oldOptions as $key => $value ) {
243  if ( in_array( $optionKinds[$key], $resetKinds ) ) {
244  if ( array_key_exists( $key, $defaultOptions ) ) {
245  $newOptions[$key] = $defaultOptions[$key];
246  }
247  } else {
248  $newOptions[$key] = $value;
249  }
250  }
251  }
252  $this->modifiedOptions[$this->getCacheKey( $user )] = $newOptions;
253  }
254 
278  public function listOptionKinds(): array {
279  return [
280  'registered',
281  'registered-multiselect',
282  'registered-checkmatrix',
283  'userjs',
284  'special',
285  'unused'
286  ];
287  }
288 
302  public function getOptionKinds(
303  UserIdentity $userIdentity,
305  $options = null
306  ): array {
307  if ( $options === null ) {
308  $options = $this->loadUserOptions( $userIdentity );
309  }
310 
311  // TODO: injecting the preferences factory creates a cyclic dependency between
312  // PreferencesFactory and UserOptionsManager. See T250822
313  $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
314  $user = $this->userFactory->newFromUserIdentity( $userIdentity );
315  $prefs = $preferencesFactory->getFormDescriptor( $user, $context );
316  $mapping = [];
317 
318  // Pull out the "special" options, so they don't get converted as
319  // multiselect or checkmatrix.
320  $specialOptions = array_fill_keys( $preferencesFactory->getSaveBlacklist(), true );
321  foreach ( $specialOptions as $name => $value ) {
322  unset( $prefs[$name] );
323  }
324 
325  // Multiselect and checkmatrix options are stored in the database with
326  // one key per option, each having a boolean value. Extract those keys.
327  $multiselectOptions = [];
328  foreach ( $prefs as $name => $info ) {
329  if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
330  ( isset( $info['class'] ) && $info['class'] == HTMLMultiSelectField::class )
331  ) {
332  $opts = HTMLFormField::flattenOptions( $info['options'] ?? $info['options-messages'] );
333  $prefix = $info['prefix'] ?? $name;
334 
335  foreach ( $opts as $value ) {
336  $multiselectOptions["$prefix$value"] = true;
337  }
338 
339  unset( $prefs[$name] );
340  }
341  }
342  $checkmatrixOptions = [];
343  foreach ( $prefs as $name => $info ) {
344  if ( ( isset( $info['type'] ) && $info['type'] == 'checkmatrix' ) ||
345  ( isset( $info['class'] ) && $info['class'] == HTMLCheckMatrix::class )
346  ) {
347  $columns = HTMLFormField::flattenOptions( $info['columns'] );
348  $rows = HTMLFormField::flattenOptions( $info['rows'] );
349  $prefix = $info['prefix'] ?? $name;
350 
351  foreach ( $columns as $column ) {
352  foreach ( $rows as $row ) {
353  $checkmatrixOptions["$prefix$column-$row"] = true;
354  }
355  }
356 
357  unset( $prefs[$name] );
358  }
359  }
360 
361  // $value is ignored
362  foreach ( $options as $key => $value ) {
363  if ( isset( $prefs[$key] ) ) {
364  $mapping[$key] = 'registered';
365  } elseif ( isset( $multiselectOptions[$key] ) ) {
366  $mapping[$key] = 'registered-multiselect';
367  } elseif ( isset( $checkmatrixOptions[$key] ) ) {
368  $mapping[$key] = 'registered-checkmatrix';
369  } elseif ( isset( $specialOptions[$key] ) ) {
370  $mapping[$key] = 'special';
371  } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
372  $mapping[$key] = 'userjs';
373  } else {
374  $mapping[$key] = 'unused';
375  }
376  }
377 
378  return $mapping;
379  }
380 
388  public function saveOptions( UserIdentity $user ) {
389  $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
390  $changed = $this->saveOptionsInternal( $user, $dbw );
391  $legacyUser = $this->userFactory->newFromUserIdentity( $user );
392  // Before UserOptionsManager, User::saveSettings was used for user options
393  // saving. Some extensions might depend on UserSaveSettings hook being run
394  // when options are saved, so run this hook for legacy reasons.
395  // Once UserSaveSettings hook is deprecated and replaced with a different hook
396  // with more modern interface, extensions should use 'SaveUserOptions' hook.
397  $this->hookRunner->onUserSaveSettings( $legacyUser );
398  if ( $changed ) {
399  $dbw->onTransactionCommitOrIdle( static function () use ( $legacyUser ) {
400  $legacyUser->checkAndSetTouched();
401  }, __METHOD__ );
402  }
403  }
404 
414  public function saveOptionsInternal( UserIdentity $user, IDatabase $dbw ): bool {
415  if ( !$user->isRegistered() ) {
416  throw new InvalidArgumentException( __METHOD__ . ' was called on anon user' );
417  }
418 
419  $userKey = $this->getCacheKey( $user );
420  $modifiedOptions = $this->modifiedOptions[$userKey] ?? [];
421  $originalOptions = $this->loadOriginalOptions( $user );
422  if ( !$this->hookRunner->onSaveUserOptions( $user, $modifiedOptions, $originalOptions ) ) {
423  return false;
424  }
425 
426  $rowsToInsert = [];
427  $keysToDelete = [];
428  foreach ( $modifiedOptions as $key => $value ) {
429  // Don't store unchanged or default values
430  $defaultValue = $this->defaultOptionsLookup->getDefaultOption( $key );
431  $oldValue = $this->optionsFromDb[$userKey][$key] ?? null;
432  if ( $value === null || $this->isValueEqual( $value, $defaultValue ) ) {
433  $keysToDelete[] = $key;
434  } elseif ( !$this->isValueEqual( $value, $oldValue ) ) {
435  // Update by deleting and reinserting
436  $rowsToInsert[] = [
437  'up_user' => $user->getId(),
438  'up_property' => $key,
439  'up_value' => $value,
440  ];
441  if ( $oldValue !== null ) {
442  $keysToDelete[] = $key;
443  }
444  }
445  }
446 
447  if ( !count( $keysToDelete ) && !count( $rowsToInsert ) ) {
448  // Nothing to do
449  return false;
450  }
451 
452  // Do the DELETE
453  if ( $keysToDelete ) {
454  $dbw->delete(
455  'user_properties',
456  [
457  'up_user' => $user->getId(),
458  'up_property' => $keysToDelete
459  ],
460  __METHOD__
461  );
462  }
463  if ( $rowsToInsert ) {
464  // Insert the new preference rows
465  $dbw->insert( 'user_properties', $rowsToInsert, __METHOD__, [ 'IGNORE' ] );
466  }
467 
468  // It's pretty cheap to recalculate new original later
469  // to apply whatever adjustments we apply when fetching from DB
470  // and re-merge with the defaults.
471  unset( $this->originalOptionsCache[$userKey] );
472  // And nothing is modified anymore
473  unset( $this->modifiedOptions[$userKey] );
474  return true;
475  }
476 
491  public function loadUserOptions(
492  UserIdentity $user,
493  int $queryFlags = self::READ_NORMAL,
494  array $data = null
495  ): array {
496  $userKey = $this->getCacheKey( $user );
497  $originalOptions = $this->loadOriginalOptions( $user, $queryFlags, $data );
498  return array_merge( $originalOptions, $this->modifiedOptions[$userKey] ?? [] );
499  }
500 
506  public function clearUserOptionsCache( UserIdentity $user ) {
507  $cacheKey = $this->getCacheKey( $user );
508  unset( $this->modifiedOptions[$cacheKey] );
509  unset( $this->optionsFromDb[$cacheKey] );
510  unset( $this->originalOptionsCache[$cacheKey] );
511  unset( $this->queryFlagsUsedForCaching[$cacheKey] );
512  }
513 
522  private function loadOptionsFromDb(
523  UserIdentity $user,
524  int $queryFlags,
525  array $prefetchedOptions = null
526  ): array {
527  if ( $prefetchedOptions === null ) {
528  $this->logger->debug( 'Loading options from database', [ 'user_id' => $user->getId() ] );
529  [ $dbr, $options ] = $this->getDBAndOptionsForQueryFlags( $queryFlags );
530  $res = $dbr->select(
531  'user_properties',
532  [ 'up_property', 'up_value' ],
533  [ 'up_user' => $user->getId() ],
534  __METHOD__,
535  $options
536  );
537  } else {
538  $res = [];
539  foreach ( $prefetchedOptions as $name => $value ) {
540  $res[] = [
541  'up_property' => $name,
542  'up_value' => $value,
543  ];
544  }
545  }
546  return $this->setOptionsFromDb( $user, $queryFlags, $res );
547  }
548 
557  private function setOptionsFromDb(
558  UserIdentity $user,
559  int $queryFlags,
560  iterable $rows
561  ): array {
562  $userKey = $this->getCacheKey( $user );
563  $options = [];
564  foreach ( $rows as $row ) {
565  $row = (object)$row;
566  // Convert '0' to 0. PHP's boolean conversion considers them both
567  // false, but e.g. JavaScript considers the former as true.
568  // @todo: T54542 Somehow determine the desired type (string/int/bool)
569  // and convert all values here.
570  if ( $row->up_value === '0' ) {
571  $row->up_value = 0;
572  }
573  $options[$row->up_property] = $row->up_value;
574  }
575  $this->optionsFromDb[$userKey] = $options;
576  $this->queryFlagsUsedForCaching[$userKey] = $queryFlags;
577  return $options;
578  }
579 
589  private function loadOriginalOptions(
590  UserIdentity $user,
591  int $queryFlags = self::READ_NORMAL,
592  array $data = null
593  ): array {
594  $userKey = $this->getCacheKey( $user );
595  $defaultOptions = $this->defaultOptionsLookup->getDefaultOptions();
596  if ( !$user->isRegistered() ) {
597  // For unlogged-in users, load language/variant options from request.
598  // There's no need to do it for logged-in users: they can set preferences,
599  // and handling of page content is done by $pageLang->getPreferredVariant() and such,
600  // so don't override user's choice (especially when the user chooses site default).
601  $variant = $this->languageConverterFactory->getLanguageConverter()->getDefaultVariant();
602  $defaultOptions['variant'] = $variant;
603  $defaultOptions['language'] = $variant;
604  $this->originalOptionsCache[$userKey] = $defaultOptions;
605  return $defaultOptions;
606  }
607 
608  // In case options were already loaded from the database before and no options
609  // changes were saved to the database, we can use the cached original options.
610  if ( $this->canUseCachedValues( $user, $queryFlags )
611  && isset( $this->originalOptionsCache[$userKey] )
612  ) {
613  return $this->originalOptionsCache[$userKey];
614  }
615 
616  $options = $this->loadOptionsFromDb( $user, $queryFlags, $data ) + $defaultOptions;
617  // Replace deprecated language codes
618  $options['language'] = LanguageCode::replaceDeprecatedCodes( $options['language'] );
619  // Fix up timezone offset (Due to DST it can change from what was stored in the DB)
620  // ZoneInfo|offset|TimeZoneName
621  if ( isset( $options['timecorrection'] ) ) {
622  $options['timecorrection'] = ( new UserTimeCorrection(
623  $options['timecorrection'],
624  null,
625  $this->serviceOptions->get( 'LocalTZoffset' )
626  ) )->toString();
627  }
628 
629  // Need to store what we have so far before the hook to prevent
630  // infinite recursion if the hook attempts to reload options
631  $this->originalOptionsCache[$userKey] = $options;
632  $this->queryFlagsUsedForCaching[$userKey] = $queryFlags;
633  $this->hookRunner->onLoadUserOptions( $user, $options );
634  $this->originalOptionsCache[$userKey] = $options;
635  return $options;
636  }
637 
643  private function getCacheKey( UserIdentity $user ): string {
644  return $user->isRegistered() ? "u:{$user->getId()}" : 'anon';
645  }
646 
651  private function getDBAndOptionsForQueryFlags( $queryFlags ): array {
652  list( $mode, $options ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
653  return [ $this->loadBalancer->getConnectionRef( $mode, [] ), $options ];
654  }
655 
662  private function canUseCachedValues( UserIdentity $user, int $queryFlags ): bool {
663  if ( !$user->isRegistered() ) {
664  // Anon users don't have options stored in the database,
665  // so $queryFlags are ignored.
666  return true;
667  }
668  $userKey = $this->getCacheKey( $user );
669  $queryFlagsUsed = $this->queryFlagsUsedForCaching[$userKey] ?? self::READ_NONE;
670  return $queryFlagsUsed >= $queryFlags;
671  }
672 
682  private function isValueEqual( $a, $b ) {
683  if ( is_bool( $a ) ) {
684  $a = (int)$a;
685  }
686  if ( is_bool( $b ) ) {
687  $b = (int)$b;
688  }
689  return (string)$a === (string)$b;
690  }
691 }
MediaWiki\User\UserOptionsManager\__construct
__construct(ServiceOptions $options, DefaultOptionsLookup $defaultOptionsLookup, LanguageConverterFactory $languageConverterFactory, ILoadBalancer $loadBalancer, LoggerInterface $logger, HookContainer $hookContainer, UserFactory $userFactory)
Definition: UserOptionsManager.php:102
MediaWiki\User\UserOptionsManager\setOption
setOption(UserIdentity $user, string $oname, $val)
Set the given option for a user.
Definition: UserOptionsManager.php:199
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:72
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:682
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:203
MediaWiki\User\UserOptionsManager\saveOptions
saveOptions(UserIdentity $user)
Saves the non-default options for this user, as previously set e.g.
Definition: UserOptionsManager.php:388
MediaWiki\User\UserOptionsManager\$optionsFromDb
array $optionsFromDb
Cached original user options as fetched from database, no adjustments applied.
Definition: UserOptionsManager.php:85
MediaWiki\User\UserOptionsManager\getDefaultOptions
getDefaultOptions()
Combine the language default options with any site-specific options and add the default language vari...
Definition: UserOptionsManager.php:124
MediaWiki\User\UserOptionsManager\$hookRunner
HookRunner $hookRunner
Definition: UserOptionsManager.php:88
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:157
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
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
MediaWiki\User\UserOptionsManager\listOptionKinds
listOptionKinds()
Return a list of the types of user options currently returned by UserOptionsManager::getOptionKinds()...
Definition: UserOptionsManager.php:278
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:131
$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:264
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:643
MediaWiki\User\UserOptionsManager\$originalOptionsCache
array $originalOptionsCache
Cached original user options with all the adjustments like time correction and hook changes applied.
Definition: UserOptionsManager.php:79
HTMLFormField
The parent class to generate form fields.
Definition: HTMLFormField.php:9
MediaWiki\User\UserOptionsManager\getDBAndOptionsForQueryFlags
getDBAndOptionsForQueryFlags( $queryFlags)
Definition: UserOptionsManager.php:651
MediaWiki\User\UserOptionsManager\clearUserOptionsCache
clearUserOptionsCache(UserIdentity $user)
Clears cached user options.
Definition: UserOptionsManager.php:506
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:302
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:91
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:491
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:221
MediaWiki\User\UserOptionsManager\$logger
LoggerInterface $logger
Definition: UserOptionsManager.php:69
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
Wikimedia\Rdbms\IDatabase\insert
insert( $table, $rows, $fname=__METHOD__, $options=[])
Insert the given row(s) into a table.
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:589
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:1178
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:662
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:557
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:522
MediaWiki\$context
IContextSource $context
Definition: MediaWiki.php:40
MediaWiki\User\UserOptionsManager\$userFactory
UserFactory $userFactory
Definition: UserOptionsManager.php:66
MediaWiki\User\UserFactory
Creates User objects.
Definition: UserFactory.php:41
MediaWiki\User\UserOptionsManager\setOptionsFromDb
setOptionsFromDb(UserIdentity $user, int $queryFlags, iterable $rows)
Builds associative options array from rows fetched from DB.
Definition: UserOptionsManager.php:557
Wikimedia\Rdbms\IDatabase\delete
delete( $table, $conds, $fname=__METHOD__)
Delete all rows in a table that match a condition.
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
MediaWiki\User\UserOptionsManager\saveOptionsInternal
saveOptionsInternal(UserIdentity $user, IDatabase $dbw)
Saves the non-default options for this user, as previously set e.g.
Definition: UserOptionsManager.php:414
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71