UserRightsProxy::getId()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Representation of an user on a other locally-hosted wiki.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 */
22
23
/**
24
 * Cut-down copy of User interface for local-interwiki-database
25
 * user rights manipulation.
26
 */
27
class UserRightsProxy {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
28
29
	/**
30
	 * Constructor.
31
	 *
32
	 * @see newFromId()
33
	 * @see newFromName()
34
	 * @param IDatabase $db Db connection
35
	 * @param string $database Database name
36
	 * @param string $name User name
37
	 * @param int $id User ID
38
	 */
39
	private function __construct( $db, $database, $name, $id ) {
40
		$this->db = $db;
0 ignored issues
show
Bug introduced by
The property db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
41
		$this->database = $database;
0 ignored issues
show
Bug introduced by
The property database does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
42
		$this->name = $name;
0 ignored issues
show
Bug introduced by
The property name does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
43
		$this->id = intval( $id );
0 ignored issues
show
Bug introduced by
The property id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
44
		$this->newOptions = [];
0 ignored issues
show
Bug introduced by
The property newOptions does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
45
	}
46
47
	/**
48
	 * Accessor for $this->database
49
	 *
50
	 * @return string Database name
51
	 */
52
	public function getDBName() {
53
		return $this->database;
54
	}
55
56
	/**
57
	 * Confirm the selected database name is a valid local interwiki database name.
58
	 *
59
	 * @param string $database Database name
60
	 * @return bool
61
	 */
62
	public static function validDatabase( $database ) {
63
		global $wgLocalDatabases;
64
		return in_array( $database, $wgLocalDatabases );
65
	}
66
67
	/**
68
	 * Same as User::whoIs()
69
	 *
70
	 * @param string $database Database name
71
	 * @param int $id User ID
72
	 * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
73
	 * @return string User name or false if the user doesn't exist
74
	 */
75
	public static function whoIs( $database, $id, $ignoreInvalidDB = false ) {
76
		$user = self::newFromId( $database, $id, $ignoreInvalidDB );
77
		if ( $user ) {
78
			return $user->name;
79
		} else {
80
			return false;
81
		}
82
	}
83
84
	/**
85
	 * Factory function; get a remote user entry by ID number.
86
	 *
87
	 * @param string $database Database name
88
	 * @param int $id User ID
89
	 * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
90
	 * @return UserRightsProxy|null If doesn't exist
91
	 */
92
	public static function newFromId( $database, $id, $ignoreInvalidDB = false ) {
93
		return self::newFromLookup( $database, 'user_id', intval( $id ), $ignoreInvalidDB );
94
	}
95
96
	/**
97
	 * Factory function; get a remote user entry by name.
98
	 *
99
	 * @param string $database Database name
100
	 * @param string $name User name
101
	 * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
102
	 * @return UserRightsProxy|null If doesn't exist
103
	 */
104
	public static function newFromName( $database, $name, $ignoreInvalidDB = false ) {
105
		return self::newFromLookup( $database, 'user_name', $name, $ignoreInvalidDB );
106
	}
107
108
	/**
109
	 * @param string $database
110
	 * @param string $field
111
	 * @param string $value
112
	 * @param bool $ignoreInvalidDB
113
	 * @return null|UserRightsProxy
114
	 */
115
	private static function newFromLookup( $database, $field, $value, $ignoreInvalidDB = false ) {
116
		global $wgSharedDB, $wgSharedTables;
117
		// If the user table is shared, perform the user query on it,
118
		// but don't pass it to the UserRightsProxy,
119
		// as user rights are normally not shared.
120
		if ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) {
121
			$userdb = self::getDB( $wgSharedDB, $ignoreInvalidDB );
122
		} else {
123
			$userdb = self::getDB( $database, $ignoreInvalidDB );
124
		}
125
126
		$db = self::getDB( $database, $ignoreInvalidDB );
127
128
		if ( $db && $userdb ) {
129
			$row = $userdb->selectRow( 'user',
130
				[ 'user_id', 'user_name' ],
131
				[ $field => $value ],
132
				__METHOD__ );
133
134
			if ( $row !== false ) {
135
				return new UserRightsProxy( $db, $database,
136
					$row->user_name,
137
					intval( $row->user_id ) );
138
			}
139
		}
140
		return null;
141
	}
142
143
	/**
144
	 * Open a database connection to work on for the requested user.
145
	 * This may be a new connection to another database for remote users.
146
	 *
147
	 * @param string $database
148
	 * @param bool $ignoreInvalidDB If true, don't check if $database is in $wgLocalDatabases
149
	 * @return IDatabase|null If invalid selection
150
	 */
151
	public static function getDB( $database, $ignoreInvalidDB = false ) {
152
		global $wgDBname;
153
		if ( $ignoreInvalidDB || self::validDatabase( $database ) ) {
154
			if ( $database == $wgDBname ) {
155
				// Hmm... this shouldn't happen though. :)
156
				return wfGetDB( DB_MASTER );
157
			} else {
158
				return wfGetDB( DB_MASTER, [], $database );
159
			}
160
		}
161
		return null;
162
	}
163
164
	/**
165
	 * @return int
166
	 */
167
	public function getId() {
168
		return $this->id;
169
	}
170
171
	/**
172
	 * @return bool
173
	 */
174
	public function isAnon() {
175
		return $this->getId() == 0;
176
	}
177
178
	/**
179
	 * Same as User::getName()
180
	 *
181
	 * @return string
182
	 */
183
	public function getName() {
184
		return $this->name . '@' . $this->database;
185
	}
186
187
	/**
188
	 * Same as User::getUserPage()
189
	 *
190
	 * @return Title
191
	 */
192
	public function getUserPage() {
193
		return Title::makeTitle( NS_USER, $this->getName() );
194
	}
195
196
	/**
197
	 * Replaces User::getUserGroups()
198
	 * @return array
199
	 */
200
	function getGroups() {
201
		$res = $this->db->select( 'user_groups',
202
			[ 'ug_group' ],
203
			[ 'ug_user' => $this->id ],
204
			__METHOD__ );
205
		$groups = [];
206
		foreach ( $res as $row ) {
207
			$groups[] = $row->ug_group;
208
		}
209
		return $groups;
210
	}
211
212
	/**
213
	 * Replaces User::addUserGroup()
214
	 * @param string $group
215
	 *
216
	 * @return bool
217
	 */
218
	function addGroup( $group ) {
219
		$this->db->insert( 'user_groups',
220
			[
221
				'ug_user' => $this->id,
222
				'ug_group' => $group,
223
			],
224
			__METHOD__,
225
			[ 'IGNORE' ] );
226
227
		return true;
228
	}
229
230
	/**
231
	 * Replaces User::removeUserGroup()
232
	 * @param string $group
233
	 *
234
	 * @return bool
235
	 */
236
	function removeGroup( $group ) {
237
		$this->db->delete( 'user_groups',
238
			[
239
				'ug_user' => $this->id,
240
				'ug_group' => $group,
241
			],
242
			__METHOD__ );
243
244
		return true;
245
	}
246
247
	/**
248
	 * Replaces User::setOption()
249
	 * @param string $option
250
	 * @param mixed $value
251
	 */
252
	public function setOption( $option, $value ) {
253
		$this->newOptions[$option] = $value;
254
	}
255
256
	public function saveSettings() {
257
		$rows = [];
258
		foreach ( $this->newOptions as $option => $value ) {
259
			$rows[] = [
260
				'up_user' => $this->id,
261
				'up_property' => $option,
262
				'up_value' => $value,
263
			];
264
		}
265
		$this->db->replace( 'user_properties',
266
			[ [ 'up_user', 'up_property' ] ],
267
			$rows, __METHOD__
268
		);
269
		$this->invalidateCache();
270
	}
271
272
	/**
273
	 * Replaces User::touchUser()
274
	 */
275
	function invalidateCache() {
276
		$this->db->update(
277
			'user',
278
			[ 'user_touched' => $this->db->timestamp() ],
279
			[ 'user_id' => $this->id ],
280
			__METHOD__
281
		);
282
283
		$wikiId = $this->db->getWikiID();
284
		$userId = $this->id;
285
		$this->db->onTransactionPreCommitOrIdle(
286
			function () use ( $wikiId, $userId ) {
287
				User::purge( $wikiId, $userId );
288
			},
289
			__METHOD__
290
		);
291
	}
292
}
293