aboutsummaryrefslogtreecommitdiffstats
path: root/includes/user/Options/UserOptionsLookup.php
blob: 525e9f9e04d079a576fd40cf4e36d7e864628c96 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?php
/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 */

namespace MediaWiki\User\Options;

use MediaWiki\User\UserIdentity;
use MediaWiki\User\UserNameUtils;
use Wikimedia\Rdbms\IDBAccessObject;

/**
 * Provides access to user options
 * @since 1.35
 */
abstract class UserOptionsLookup {

	/**
	 * Exclude user options that are set to their default value.
	 */
	public const EXCLUDE_DEFAULTS = 1;

	/**
	 * The suffix appended to preference names for the associated preference
	 * that tracks whether they have a local override.
	 * @since 1.43
	 */
	public const LOCAL_EXCEPTION_SUFFIX = '-local-exception';

	private UserNameUtils $userNameUtils;

	public function __construct( UserNameUtils $userNameUtils ) {
		$this->userNameUtils = $userNameUtils;
	}

	/**
	 * Combine the language default options with any site-specific and user-specific defaults
	 * and add the default language variants.
	 *
	 * @param UserIdentity|null $userIdentity User to look the default up for; set to null to
	 * ignore any user-specific defaults (since 1.42)
	 * @return array
	 */
	abstract public function getDefaultOptions( ?UserIdentity $userIdentity = null ): array;

	/**
	 * Get a given default option value.
	 *
	 * @param string $opt Name of option to retrieve
	 * @param UserIdentity|null $userIdentity User to look the defaults up for; set to null to
	 * ignore any user-specific defaults (since 1.42)
	 * @return mixed|null Default option value
	 */
	public function getDefaultOption(
		string $opt,
		?UserIdentity $userIdentity = null
	) {
		$defaultOptions = $this->getDefaultOptions( $userIdentity );
		return $defaultOptions[$opt] ?? null;
	}

	/**
	 * Get the user's current setting for a given option.
	 *
	 * @param UserIdentity $user The user to get the option for
	 * @param string $oname The option to check
	 * @param mixed|null $defaultOverride A default value returned if the option does not exist
	 * @param bool $ignoreHidden Whether to ignore the effects of $wgHiddenPrefs
	 * @param int $queryFlags A bit field composed of READ_XXX flags
	 * @return mixed|null User's current value for the option,
	 *   Note that while option values retrieved from the database are always strings, default
	 *   values and values set within the current request and not yet saved may be of another type.
	 * @see getBoolOption()
	 * @see getIntOption()
	 */
	abstract public function getOption(
		UserIdentity $user,
		string $oname,
		$defaultOverride = null,
		bool $ignoreHidden = false,
		int $queryFlags = IDBAccessObject::READ_NORMAL
	);

	/**
	 * Get all user's options
	 *
	 * @param UserIdentity $user The user to get the option for
	 * @param int $flags Bitwise combination of:
	 *   UserOptionsManager::EXCLUDE_DEFAULTS  Exclude user options that are set
	 *                                         to the default value. Options
	 *                                         that are set to their conditionally
	 *                                         default value are not excluded.
	 * @param int $queryFlags A bit field composed of READ_XXX flags
	 * @return array
	 */
	abstract public function getOptions(
		UserIdentity $user,
		int $flags = 0,
		int $queryFlags = IDBAccessObject::READ_NORMAL
	): array;

	/**
	 * Get the user's current setting for a given option, as a boolean value.
	 *
	 * @param UserIdentity $user The user to get the option for
	 * @param string $oname The option to check
	 * @param int $queryFlags A bit field composed of READ_XXX flags
	 * @return bool User's current value for the option
	 * @see getOption()
	 */
	public function getBoolOption(
		UserIdentity $user,
		string $oname,
		int $queryFlags = IDBAccessObject::READ_NORMAL
	): bool {
		return (bool)$this->getOption(
			$user, $oname, null, false, $queryFlags );
	}

	/**
	 * Get the user's current setting for a given option, as an integer value.
	 *
	 * @param UserIdentity $user The user to get the option for
	 * @param string $oname The option to check
	 * @param int $defaultOverride A default value returned if the option does not exist
	 * @param int $queryFlags A bit field composed of READ_XXX flags
	 * @return int User's current value for the option
	 * @see getOption()
	 */
	public function getIntOption(
		UserIdentity $user,
		string $oname,
		int $defaultOverride = 0,
		int $queryFlags = IDBAccessObject::READ_NORMAL
	): int {
		$val = $this->getOption(
			$user, $oname, $defaultOverride, false, $queryFlags );
		if ( $val == '' ) {
			$val = $defaultOverride;
		}
		return intval( $val );
	}

	/**
	 * Get a cache key for a user
	 * @param UserIdentity $user
	 * @return string
	 */
	protected function getCacheKey( UserIdentity $user ): string {
		$name = $user->getName();
		if ( $this->userNameUtils->isIP( $name ) || $this->userNameUtils->isTemp( $name ) ) {
			// IP and temporary users may not have custom preferences, so they can share a key
			return 'anon';
		} elseif ( $user->isRegistered() ) {
			return "u:{$user->getId()}";
		} else {
			// Allow users with no local account to have preferences provided by alternative
			// UserOptionsStore implementations (e.g. in GlobalPreferences)
			$canonical = $this->userNameUtils->getCanonical( $name ) ?: $name;
			return "a:$canonical";
		}
	}

	/**
	 * Determine if a user option came from a source other than the local store
	 * or the defaults. If this is true, setting the option will be ignored
	 * unless GLOBAL_OVERRIDE or GLOBAL_UPDATE is passed to setOption().
	 *
	 * @param UserIdentity $user
	 * @param string $key
	 * @return bool
	 */
	public function isOptionGlobal( UserIdentity $user, string $key ) {
		return false;
	}

	/**
	 * Get a single option for a batch of users, given their names.
	 *
	 * Results are uncached. Use getOption() to get options with a per-user
	 * cache.
	 *
	 * User names are used because that's what GenderCache has. If you're
	 * calling this and you're not GenderCache, consider adding a method
	 * taking an array of UserIdentity objects instead.
	 *
	 * @since 1.44
	 * @param string[] $users A normalized list of usernames
	 * @param string $key The option to get
	 * @return array The option values, indexed by the provided usernames
	 */
	abstract public function getOptionBatchForUserNames( array $users, string $key );
}
/** @deprecated class alias since 1.42 */
class_alias( UserOptionsLookup::class, 'MediaWiki\\User\\UserOptionsLookup' );