Completed
Push — develop ( 6a0ab2...965bce )
by Greg
11:38
created

edituser.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * webtrees: online genealogy
4
 * Copyright (C) 2016 webtrees development team
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 3 of the License, or
8
 * (at your option) any later version.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 * GNU General Public License for more details.
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
 */
16
namespace Fisharebest\Webtrees;
17
18
/**
19
 * Defined in session.php
20
 *
21
 * @global Tree $WT_TREE
22
 */
23
global $WT_TREE;
24
25
use Fisharebest\Webtrees\Controller\PageController;
26
use Fisharebest\Webtrees\Functions\FunctionsEdit;
27
use Fisharebest\Webtrees\Functions\FunctionsPrint;
28
29
define('WT_SCRIPT_NAME', 'edituser.php');
30
require './includes/session.php';
31
32
// Need to be logged in
33
if (!Auth::check()) {
34
	header('Location: ' . WT_BASE_URL);
35
36
	return;
37
}
38
39
// Extract form variables
40
$form_action         = Filter::post('form_action');
41
$form_username       = Filter::post('form_username');
42
$form_realname       = Filter::post('form_realname');
43
$form_pass1          = Filter::post('form_pass1', WT_REGEX_PASSWORD);
44
$form_pass2          = Filter::post('form_pass2', WT_REGEX_PASSWORD);
45
$form_email          = Filter::postEmail('form_email');
46
$form_rootid         = Filter::post('form_rootid', WT_REGEX_XREF);
47
$form_theme          = Filter::post('form_theme', implode('|', array_keys(Theme::themeNames())), '');
48
$form_language       = Filter::post('form_language');
49
$form_timezone       = Filter::post('form_timezone');
50
$form_contact_method = Filter::post('form_contact_method');
51
$form_visible_online = Filter::postBool('form_visible_online');
52
53
// Respond to form action
54
if ($form_action && Filter::checkCsrf()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $form_action of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
55
	switch ($form_action) {
56
	case 'update':
57
		if ($form_username !== Auth::user()->getUserName() && User::findByUserName($form_username)) {
58
			FlashMessages::addMessage(I18N::translate('Duplicate username. A user with that username already exists. Please choose another username.'));
59
		} elseif ($form_email !== Auth::user()->getEmail() && User::findByEmail($form_email)) {
60
			FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.'));
61
		} else {
62
			// Change username
63
			if ($form_username !== Auth::user()->getUserName()) {
64
				Log::addAuthenticationLog('User ' . Auth::user()->getUserName() . ' renamed to ' . $form_username);
65
				Auth::user()->setUserName($form_username);
66
			}
67
68
			// Change password
69
			if ($form_pass1 && $form_pass1 === $form_pass2) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $form_pass1 of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
70
				Auth::user()->setPassword($form_pass1);
71
			}
72
73
			// Change other settings
74
			Auth::user()
75
				->setRealName($form_realname)
76
				->setEmail($form_email)
77
				->setPreference('language', $form_language)
78
				->setPreference('TIMEZONE', $form_timezone)
79
				->setPreference('contactmethod', $form_contact_method)
80
				->setPreference('visibleonline', $form_visible_online ? '1' : '0');
81
82
			if ($form_theme === null) {
83
				Auth::user()->deletePreference('theme');
84
			} else {
85
				Auth::user()->setPreference('theme', $form_theme);
86
			}
87
88
			$WT_TREE->setUserPreference(Auth::user(), 'rootid', $form_rootid);
89
		}
90
		break;
91
92
	case 'delete':
93
		// An administrator can only be deleted by another administrator
94
		if (!Auth::user()->getPreference('canadmin')) {
95
			// Keep a reference to the currently logged in user because after logging out this user,
96
			// a call to Auth::user() will not return this user anymore
97
			$currentUser = Auth::user();
98
			Auth::logout();
99
			$currentUser->delete();
100
		}
101
		break;
102
	}
103
104
	header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME);
105
106
	return;
107
}
108
109
$controller = new PageController;
110
$controller
111
	->setPageTitle(I18N::translate('My account'))
112
	->pageHeader()
113
	->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)
114
	->addInlineJavascript('autocomplete();');
115
116
$my_individual_record = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'gedcomid'), $WT_TREE);
117
$default_individual   = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'rootid'), $WT_TREE);
118
119
// Form validation
120
?>
121
<script>
122
function checkform(frm) {
123
	if (frm.form_username.value=="") {
124
		alert("<?php echo I18N::translate('You must enter a username.'); ?>");
125
		frm.form_username.focus();
126
		return false;
127
	}
128
	if (frm.form_realname.value=="") {
129
		alert("<?php echo I18N::translate('You must enter a real name.'); ?>");
130
		frm.form_realname.focus();
131
		return false;
132
	}
133
	if (frm.form_pass1.value!=frm.form_pass2.value) {
134
		alert("<?php echo I18N::translate('The passwords do not match.'); ?>");
135
		frm.form_pass1.focus();
136
		return false;
137
	}
138
	if (frm.form_pass1.value.length > 0 && frm.form_pass1.value.length < 6) {
139
		alert("<?php echo I18N::translate('Passwords must contain at least 6 characters.'); ?>");
140
		frm.form_pass1.focus();
141
		return false;
142
	}
143
	return true;
144
}
145
</script>
146
147
<div id="edituser-page">
148
	<h2><?php echo $controller->getPageTitle(); ?></h2>
149
150
	<form name="editform" method="post" action="?" onsubmit="return checkform(this);">
151
152
		<input type="hidden" id="form_action" name="form_action" value="update">
153
		<?php echo Filter::getCsrf(); ?>
154
155
		<div id="edituser-table">
156
			<div class="label">
157
				<label for="form_username">
158
					<?php echo I18N::translate('Username'); ?>
159
				</label>
160
			</div>
161
			<div class="value">
162
				<input type="text" id="form_username" name="form_username" value="<?php echo Filter::escapeHtml(Auth::user()->getUserName()); ?>" dir="auto">
163
				<p class="small text-muted">
164
					<?php echo I18N::translate('Usernames are case-insensitive and ignore accented letters, so that “chloe”, “chloë”, and “Chloe” are considered to be the same.'); ?>
165
				</p>
166
			</div>
167
168
			<div class="label">
169
				<label for="form_realname">
170
					<?php echo I18N::translate('Real name'); ?>
171
				</label>
172
			</div>
173
			<div class="value">
174
				<input type="text" id="form_realname" name="form_realname" value="<?php echo Filter::escapeHtml(Auth::user()->getRealName()); ?>" dir="auto">
175
				<p class="small text-muted">
176
					<?php echo I18N::translate('This is your real name, as you would like it displayed on screen.'); ?>
177
				</p>
178
			</div>
179
180
			<div class="label">
181
				<?php echo I18N::translate('Individual record'); ?>
182
			</div>
183
			<div class="value">
184
				<?php if ($my_individual_record): ?>
185
				<?php echo $my_individual_record->formatList('span'); ?>
186
				<?php else: ?>
187
					<?php echo I18N::translateContext('unknown people', 'Unknown'); ?>
188
				<?php endif; ?>
189
				<p class="small text-muted">
190
					<?php echo I18N::translate('This is a link to your own record in the family tree. If this is the wrong individual, contact an administrator.'); ?>
191
				</p>
192
			</div>
193
194
			<div class="label">
195
				<label for="form_rootid">
196
					<?php echo I18N::translate('Default individual'); ?>
197
				</label>
198
			</div>
199
			<div class="value">
200
				<input data-autocomplete-type="INDI" type="text" name="form_rootid" id="form_rootid" value="<?php echo $WT_TREE->getUserPreference(Auth::user(), 'rootid'); ?>">
201
				<?php echo FunctionsPrint::printFindIndividualLink('form_rootid'); ?>
202
				<br>
203
				<?php if ($default_individual): ?>
204
				<?php echo $default_individual->formatList('span'); ?>
205
				<?php endif; ?>
206
				<p class="small text-muted">
207
					<?php echo I18N::translate('This individual will be selected by default when viewing charts and reports.'); ?>
208
				</p>
209
			</div>
210
211
			<div class="label">
212
				<label for="form_pass1">
213
					<?php echo I18N::translate('Password'); ?>
214
				</label>
215
			</div>
216
			<div class="value">
217
				<input type="password" id="form_pass1" name="form_pass1">
218
				<p class="small text-muted">
219
					<?php echo I18N::translate('Passwords must be at least 6 characters long and are case-sensitive, so that “secret” is different from “SECRET”.'); ?>
220
					<?php echo I18N::translate('Leave the password blank if you want to keep the current password.'); ?>
221
				</p>
222
			</div>
223
224
			<div class="label">
225
				<label for="form_pass2">
226
					<?php echo I18N::translate('Confirm password'); ?>
227
				</label>
228
			</div>
229
			<div class="value">
230
				<input type="password" id="form_pass2" name="form_pass2">
231
				<p class="small text-muted">
232
					<?php echo I18N::translate('Type your password again, to make sure you have typed it correctly.'); ?>
233
				</p>
234
			</div>
235
236
			<div class="label">
237
				<label for="form_language">
238
					<?php echo I18N::translate('Language'); ?>
239
				</label>
240
			</div>
241
			<div class="value">
242
				<?php echo FunctionsEdit::editFieldLanguage('form_language', Auth::user()->getPreference('language')); ?>
243
			</div>
244
245
			<div class="label">
246
				<label for="form_timezone">
247
					<?php echo I18N::translate('Time zone'); ?>
248
				</label>
249
			</div>
250
			<div class="value">
251
				<?php echo FunctionsEdit::selectEditControl('form_timezone', array_combine(\DateTimeZone::listIdentifiers(), \DateTimeZone::listIdentifiers()), null, Auth::user()->getPreference('TIMEZONE') ?: 'UTC', 'class="form-control"'); ?>
252
				<p class="small text-muted">
253
					<?php echo I18N::translate('The time zone is required for date calculations, such as knowing today’s date.'); ?>
254
				</p>
255
			</div>
256
257
			<div class="label">
258
				<label for="form_email">
259
					<?php echo I18N::translate('Email address'); ?>
260
				</label>
261
			</div>
262
			<div class="value">
263
				<input type="email" id="form_email" name="form_email" value="<?php echo Filter::escapeHtml(Auth::user()->getEmail()); ?>" size="50">
264
				<p class="small text-muted">
265
					<?php echo I18N::translate('This email address will be used to send password reminders, website notifications, and messages from other family members who are registered on the website.'); ?>
266
				</p>
267
			</div>
268
			<?php if (Site::getPreference('ALLOW_USER_THEMES')): ?>
269
270
			<div class="label">
271
				<label for="form_theme">
272
					<?php echo I18N::translate('Theme'); ?>
273
				</label>
274
			</div>
275
			<div class="value">
276
				<select id="form_theme" name="form_theme">
277
					<option value="">
278
						<?php echo Filter::escapeHtml(/* I18N: default option in list of themes */ I18N::translate('<default theme>')); ?>
279
					</option>
280
					<?php foreach (Theme::themeNames() as $theme_id => $theme_name): ?>
281
					<option value="<?php echo $theme_id; ?>" <?php echo $theme_id === Auth::user()->getPreference('theme') ? 'selected' : ''; ?>>
282
						<?php echo $theme_name; ?>
283
					</option>
284
					<?php endforeach; ?>
285
				</select>
286
				<p class="small text-muted">
287
					<?php echo /* I18N: Help text for the "Default theme" site configuration setting */ I18N::translate('You can change the appearance of webtrees using “themes”. Each theme has a different style, layout, color scheme, etc.'); ?>
288
				</p>
289
			</div>
290
			<?php endif; ?>
291
292
			<div class="label">
293
				<label for="form_contact_method">
294
					<?php echo I18N::translate('Contact method'); ?>
295
				</label>
296
			</div>
297
			<div class="value">
298
				<?php echo FunctionsEdit::editFieldContact('form_contact_method', Auth::user()->getPreference('contactmethod')); ?>
299
				<p class="small text-muted">
300
					<?php echo I18N::translate('Site members can send each other messages. You can choose to how these messages are sent to you, or choose not receive them at all.'); ?>
301
				</p>
302
			</div>
303
304
			<div class="label">
305
				<label for="form_visible_online">
306
					<?php echo I18N::translate('Visible to other users when online'); ?>
307
				</label>
308
			</div>
309
			<div class="value">
310
				<?php echo FunctionsEdit::checkbox('form_visible_online', Auth::user()->getPreference('visibleonline')); ?>
0 ignored issues
show
\Fisharebest\Webtrees\Au...erence('visibleonline') is of type string|null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
311
				<p class="small text-muted">
312
					<?php echo I18N::translate('You can choose whether to appear in the list of users who are currently signed-in.'); ?>
313
				</p>
314
			</div>
315
		</div>
316
		<div id="edituser_submit">
317
			<input type="submit" value="<?php echo I18N::translate('save'); ?>">
318
		</div>
319
		<?php if (!Auth::user()->getPreference('canadmin')): ?>
320
		<a href="#" onclick="if (confirm('<?php echo I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Auth::user()->getUserName())); ?>')) {jQuery('#form_action').val('delete'); document.editform.submit(); }">
321
			<?php echo I18N::translate('Delete your account'); ?>
322
		</a>
323
		<?php endif; ?>
324
	</form>
325
</div>
326