Completed
Push — 3.0 ( 80deee...572da2 )
by Jeroen
99:03 queued 39:21
created

engine/lib/user_settings.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * Elgg user settings functions.
4
 * Functions for adding and manipulating options on the user settings panel.
5
 *
6
 * @package Elgg.Core
7
 * @subpackage Settings.User
8
 */
9
10
use Elgg\Request;
11
use Elgg\Http\ResponseBuilder;
12
13
/**
14
 * Set a user's password
15
 * Returns null if no change is required
16
 * Returns true or false indicating success or failure if change was needed
17
 *
18
 * @elgg_plugin_hook usersettings:save user
19
 *
20
 * @param \Elgg\Hook $hook 'usersettings:save', 'user'
21
 *
22
 * @return bool|null|void
23
 * @since 1.8.0
24
 * @access private
25
 */
26
function _elgg_set_user_password(\Elgg\Hook $hook) {
27
28 13
	$actor = elgg_get_logged_in_user_entity();
29 13
	if (!$actor instanceof ElggUser) {
30
		return;
31
	}
32
33 13
	$user = $hook->getUserParam();
34 13
	$request = $hook->getParam('request');
35
	
36 13
	if (!$user instanceof ElggUser || !$request instanceof Request) {
37
		return;
38
	}
39
40 13
	$password = $request->getParam('password', null, false);
41 13
	$password2 = $request->getParam('password2', null, false);
42
43 13
	if (!$password) {
44 9
		return null;
45
	}
46
47 4
	if (!$actor->isAdmin() || $user->guid === $actor->guid) {
48
		// let admin user change anyone's password without knowing it except his own.
49
50 4
		$current_password = $request->getParam('current_password', null, false);
51
52
		try {
53 4
			elgg()->accounts->assertCurrentPassword($user, $current_password);
54 1
		} catch (RegistrationException $e) {
55 1
			$request->validation()->fail('password', '', elgg_echo('LoginException:ChangePasswordFailure'));
56
57 1
			return false;
58
		}
59
	}
60
61
	try {
62 3
		elgg()->accounts->assertValidPassword([$password, $password2]);
63 2
	} catch (RegistrationException $e) {
64 2
		$request->validation()->fail('password', '', $e->getMessage());
65
66 2
		return false;
67
	}
68
69 1
	$user->setPassword($password);
70 1
	_elgg_services()->persistentLogin->handlePasswordChange($user, $actor);
71
72 1
	$request->validation()->pass('password', '', elgg_echo('user:password:success'));
73 1
}
74
75
/**
76
 * Set a user's display name
77
 * Returns null if no change is required or input is not present in the form
78
 * Returns true or false indicating success or failure if change was needed
79
 *
80
 * @elgg_plugin_hook usersettings:save user
81
 *
82
 * @param \Elgg\Hook $hook Hook
83
 *
84
 * @return bool|null
85
 * @since 1.8.0
86
 * @access private
87
 */
88
function _elgg_set_user_name(\Elgg\Hook $hook) {
89
90 13
	$user = $hook->getUserParam();
91 13
	$request = $hook->getParam('request');
92
	/* @var $request \Elgg\Request */
93
94 13
	$name = $request->getParam('name');
95 13
	if (!isset($name)) {
96 11
		return null;
97
	}
98
99 2
	$name = strip_tags($name);
100 2
	if (empty($name)) {
101 1
		$request->validation()->fail('name', $request->getParam('name'), elgg_echo('user:name:fail'));
102
103 1
		return false;
104
	}
105
106 1
	if ($name === $user->name) {
107
		return null;
108
	}
109
110 1
	$request->validation()->pass('name', $name, elgg_echo('user:name:success'));
111
112 1
	$user->name = $name;
113
114 1
}
115
116
/**
117
 * Set a user's username
118
 * Returns null if no change is required or input is not present in the form
119
 * Returns true or false indicating success or failure if change was needed
120
 *
121
 * @elgg_plugin_hook usersettings:save user
122
 *
123
 * @param \Elgg\Hook $hook Hook
124
 *
125
 * @return bool|null
126
 *
127
 * @since 3.0
128
 * @access private
129
 */
130
function _elgg_set_user_username(\Elgg\Hook $hook) {
131
132 13
	$user = $hook->getUserParam();
133 13
	$request = $hook->getParam('request');
134
	
135 13
	if (!$user instanceof ElggUser || !$request instanceof Request) {
136
		return null;
137
	}
138
139 13
	$username = $request->getParam('username');
140 13
	if (!isset($username)) {
141 11
		return null;
142
	}
143
144 2
	if (!elgg_is_admin_logged_in()) {
145
		return null;
146
	}
147
148 2
	if ($user->username === $username) {
149
		return null;
150
	}
151
152
	// check if username is valid and does not exist
153
	try {
154 2
		elgg()->accounts->assertValidUsername($username, true);
155 1
	} catch (RegistrationException $ex) {
156 1
		$request->validation()->fail('username', $username, $ex->getMessage());
157
158 1
		return false;
159
	}
160
161 1
	$user->username = $username;
162
163 1
	$request->validation()->pass('username', $username, elgg_echo('user:username:success'));
164
165
	// correctly forward after after a username change
166
	elgg_register_plugin_hook_handler('response', 'action:usersettings/save', function (\Elgg\Hook $hook) use ($username) {
167
		$response = $hook->getValue();
168
		if (!$response instanceof ResponseBuilder) {
169
			return;
170
		}
171
172
		if ($response->getForwardURL() === REFERRER) {
173
			$response->setForwardURL(elgg_generate_url('settings:account', [
1 ignored issue
show
It seems like elgg_generate_url('setti...sername' => $username)) can also be of type false; however, parameter $forward_url of Elgg\Http\ResponseBuilder::setForwardURL() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

173
			$response->setForwardURL(/** @scrutinizer ignore-type */ elgg_generate_url('settings:account', [
Loading history...
174
				'username' => $username,
175
			]));
176
		}
177
178
		return $response;
179 1
	});
180 1
}
181
182
/**
183
 * Set a user's language
184
 * Returns null if no change is required or input is not present in the form
185
 * Returns true or false indicating success or failure if change was needed
186
 *
187
 * @elgg_plugin_hook usersettings:save user
188
 *
189
 * @param \Elgg\Hook $hook Hook
190
 *
191
 * @return bool|null
192
 * @since 1.8.0
193
 * @access private
194
 */
195
function _elgg_set_user_language(\Elgg\Hook $hook) {
196
197 13
	$user = $hook->getUserParam();
198 13
	$request = $hook->getParam('request');
199
	
200 13
	if (!$user instanceof ElggUser || !$request instanceof Request) {
201
		return null;
202
	}
203
204 13
	$language = $request->getParam('language');
205 13
	if (!isset($language)) {
206 12
		return null;
207
	}
208
209 1
	if ($language === $user->language) {
210
		return null;
211
	}
212
213 1
	$user->language = $language;
214
215 1
	$request->validation()->pass('language', $language, elgg_echo('user:language:success'));
216 1
}
217
218
/**
219
 * Set a user's email address
220
 * Returns null if no change is required or input is not present in the form
221
 * Returns true or false indicating success or failure if change was needed
222
 *
223
 * @elgg_plugin_hook usersettings:save user
224
 *
225
 * @param \Elgg\Hook $hook Hook
226
 *
227
 * @return bool|null
228
 * @since 1.8.0
229
 * @access private
230
 */
231
function _elgg_set_user_email(\Elgg\Hook $hook) {
232
	
233 13
	$actor = elgg_get_logged_in_user_entity();
234 13
	if (!$actor instanceof ElggUser) {
235
		return null;
236
	}
237
238 13
	$user = $hook->getUserParam();
239 13
	$request = $hook->getParam('request');
240
	
241 13
	if (!$user instanceof ElggUser || !$request instanceof Request) {
242
		return null;
243
	}
244
245 13
	$email = $request->getParam('email');
246 13
	if (!isset($email)) {
247 10
		return null;
248
	}
249
250 3
	if (strcmp($email, $user->email) === 0) {
251
		// no change
252
		return null;
253
	}
254
255
	try {
256 3
		elgg()->accounts->assertValidEmail($email, true);
257 1
	} catch (RegistrationException $ex) {
258 1
		$request->validation()->fail('email', $email, $ex->getMessage());
259
260 1
		return false;
261
	}
262
263 2
	if (elgg()->config->security_email_require_password && $user->guid === $actor->guid) {
264
		try {
265
			// validate password
266 2
			elgg()->accounts->assertCurrentPassword($user, $request->getParam('email_password'));
267 1
		} catch (RegistrationException $e) {
268 1
			$request->validation()->fail('email', $email, elgg_echo('email:save:fail:password'));
269 1
			return false;
270
		}
271
	}
272
273 1
	$hook_params = $hook->getParams();
274 1
	$hook_params['email'] = $email;
275
276 1
	if (elgg_trigger_plugin_hook('change:email', 'user', $hook_params, true)) {
277 1
		$user->email = $email;
278 1
		$request->validation()->pass('email', $email, elgg_echo('email:save:success'));
279
	}
280 1
}
281
282
/**
283
 * Set a user's default access level
284
 * Returns null if no change is required or input is not present in the form
285
 * Returns true or false indicating success or failure if change was needed
286
 *
287
 * @elgg_plugin_hook usersettings:save user
288
 *
289
 * @param \Elgg\Hook $hook Hook
290
 *
291
 * @return bool|null
292
 * @since 1.8.0
293
 * @access private
294
 * @throws DatabaseException
295
 */
296
function _elgg_set_user_default_access(\Elgg\Hook $hook) {
297
298 13
	if (!elgg()->config->allow_user_default_access) {
299 12
		return null;
300
	}
301
302 1
	$user = $hook->getUserParam();
303 1
	$request = $hook->getParam('request');
304
	/* @var $request \Elgg\Request */
305
306 1
	$default_access = $request->getParam('default_access');
307 1
	if (!isset($default_access)) {
308
		return null;
309
	}
310
311 1
	if ($user->setPrivateSetting('elgg_default_access', $default_access)) {
312 1
		$request->validation()->pass('default_access', $default_access, elgg_echo('user:default_access:success'));
313
	} else {
314
		$request->validation()->fail('default_access', $default_access, elgg_echo(elgg_echo('user:default_access:failure')));
315
	}
316 1
}
317
318
/**
319
 * Register menu items for the user settings page menu
320
 *
321
 * @param string         $hook   'register'
322
 * @param string         $type   'menu:page'
323
 * @param ElggMenuItem[] $return current return value
324
 * @param array          $params supplied params
325
 *
326
 * @return void|ElggMenuItem[]
327
 *
328
 * @access private
329
 * @since 3.0
330
 */
331
function _elgg_user_settings_menu_register($hook, $type, $return, $params) {
332 2
	$user = elgg_get_page_owner_entity();
333 2
	if (!$user) {
334 1
		return;
335
	}
336
337 1
	if (!elgg_in_context('settings')) {
338 1
		return;
339
	}
340
341
	$return[] = \ElggMenuItem::factory([
342
		'name' => '1_account',
343
		'text' => elgg_echo('usersettings:user:opt:linktext'),
344
		'href' => "settings/user/{$user->username}",
345
		'section' => 'configure',
346
	]);
347
348
	$return[] = \ElggMenuItem::factory([
349
		'name' => '1_plugins',
350
		'text' => elgg_echo('usersettings:plugins:opt:linktext'),
351
		'href' => '#',
352
		'section' => 'configure',
353
	]);
354
355
	$return[] = \ElggMenuItem::factory([
356
		'name' => '1_statistics',
357
		'text' => elgg_echo('usersettings:statistics:opt:linktext'),
358
		'href' => "settings/statistics/{$user->username}",
359
		'section' => 'configure',
360
	]);
361
362
	// register plugin user settings menu items
363
	$active_plugins = elgg_get_plugins();
364
365
	foreach ($active_plugins as $plugin) {
366
		$plugin_id = $plugin->getID();
367
		if (!elgg_view_exists("usersettings/$plugin_id/edit") && !elgg_view_exists("plugins/$plugin_id/usersettings")) {
368
			continue;
369
		}
370
371
		if (elgg_language_key_exists($plugin_id . ':usersettings:title')) {
372
			$title = elgg_echo($plugin_id . ':usersettings:title');
373
		} else {
374
			$title = $plugin->getDisplayName();
375
		}
376
377
		$return[] = \ElggMenuItem::factory([
378
			'name' => $plugin_id,
379
			'text' => $title,
380
			'href' => elgg_generate_url('settings:tools', [
381
				'username' => $user->username,
382
				'plugin_id' => $plugin_id,
383
			]),
384
			'parent_name' => '1_plugins',
385
			'section' => 'configure',
386
		]);
387
	}
388
389
	return $return;
390
}
391
392
/**
393
 * Prepares the page menu to strip out empty plugins menu item for user settings
394
 *
395
 * @param string $hook   prepare
396
 * @param string $type   menu:page
397
 * @param array  $value  array of menu items
398
 * @param array  $params menu related parameters
399
 *
400
 * @return array
401
 * @access private
402
 */
403
function _elgg_user_settings_menu_prepare($hook, $type, $value, $params) {
404 3
	if (empty($value)) {
405 1
		return $value;
406
	}
407
408 2
	if (!elgg_in_context("settings")) {
409 2
		return $value;
410
	}
411
412
	$configure = elgg_extract("configure", $value);
413
	if (empty($configure)) {
414
		return $value;
415
	}
416
417
	foreach ($configure as $index => $menu_item) {
418
		if (!($menu_item instanceof ElggMenuItem)) {
419
			continue;
420
		}
421
422
		if ($menu_item->getName() == "1_plugins") {
423
			if (!$menu_item->getChildren()) {
424
				// no need for this menu item if it has no children
425
				unset($value["configure"][$index]);
426
			}
427
		}
428
	}
429
430
	return $value;
431
}
432
433
/**
434
 * Initialize the user settings library
435
 *
436
 * @return void
437
 * @access private
438
 */
439
function _elgg_user_settings_init() {
440
441 80
	elgg_register_plugin_hook_handler('register', 'menu:page', '_elgg_user_settings_menu_register');
442 80
	elgg_register_plugin_hook_handler('prepare', 'menu:page', '_elgg_user_settings_menu_prepare');
443
444 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_language');
445 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_password');
446 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_default_access');
447 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_name');
448 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_username');
449 80
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_set_user_email');
450
451
	// extend the account settings form
452 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/username', 100);
453 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/name', 100);
454 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/password', 100);
455 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/email', 100);
456 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/language', 100);
457 80
	elgg_extend_view('forms/usersettings/save', 'core/settings/account/default_access', 100);
458 80
}
459
460
/**
461
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
462
 */
463
return function (\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
464 69
	$events->registerHandler('init', 'system', '_elgg_user_settings_init');
465
};
466