UserSettingsLoader::getInfo()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
nc 1
nop 0
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
3
/**
4
 * This file does all of the data loading for members.
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * This file contains code covered by:
11
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
12
 *
13
 * @version 2.0 dev
14
 *
15
 */
16
17
namespace ElkArte;
18
19
use ElkArte\Cache\Cache;
20
use ElkArte\Database\QueryInterface;
21
use ElkArte\Exceptions\Exception;
22
use ElkArte\Helper\ValuesContainer;
23
use ElkArte\Helper\ValuesContainerReadOnly;
24
25
/**
26
 * This class holds all the data belonging to a certain member.
27
 */
28
class UserSettingsLoader
29
{
30
	/** @var int */
31
	public const HASH_LENGTH = 16;
32
33
	/** @var int */
34
	public const BAN_OFFSET = 10;
35
36
	/** @var mixed|string */
37
	public $member_name;
38
39
	/** @var int The user id */
40
	protected $id = 0;
41
42
	/** @var string The member_name field from the db */
43
	protected $username = '';
44
45
	/** @var ValuesContainerReadOnly The settings data */
46
	protected $settings;
47
48
	/** @var ValuesContainer The into data */
49
	protected $info;
50
51
	/**
52
	 * Constructor
53
	 *
54
	 * @param QueryInterface $db
55
	 * @param Cache $cache
56
	 * @param Request $req
57
	 */
58
	public function __construct(protected $db, protected $cache, protected $req)
59
	{
60
	}
61
62
	/**
63
	 * Returns the user settings
64
	 *
65
	 * @return ValuesContainerReadOnly
66
	 */
67
	public function getSettings()
68
	{
69
		return $this->settings;
70
	}
71
72
	/**
73
	 * Returns the user into
74
	 *
75
	 * @return ValuesContainer
76
	 */
77
	public function getInfo()
78
	{
79
		return $this->info;
80
	}
81
82
	/**
83
	 * Loads from the db the data of a user based on the member id
84
	 *
85
	 * @param int $id
86
	 * @param bool $already_verified
87
	 * @param string $session_password
88
	 *
89
	 * @event integrate_user_info
90
	 */
91
	public function loadUserById($id, $already_verified, $session_password)
92
	{
93
		$this->id = (int) $id;
94 5
95
		if ($this->id !== 0)
96 5
		{
97 5
			$this->loadUserData($already_verified, $session_password);
98 5
			$user_info = $this->initUser();
99 5
		}
100
		else
101
		{
102
			$user_info = $this->initGuest();
103
		}
104
105
		Hooks::instance()->hook('integrate_user_info', [$user_info]);
106 5
107
		$this->compileInfo($user_info);
108 5
	}
109
110
	/**
111
	 * Loads the data of a certain member from the database
112
	 *
113
	 * @param bool $already_verified
114
	 * @param string $session_password
115
	 */
116 3
	protected function loadUserData($already_verified, $session_password)
117
	{
118 3
		$user_settings = [];
119
120
		// Is the member data cached?
121
		if ($this->cache->levelLowerThan(2) || $this->cache->getVar($user_settings, 'user_settings-' . $this->id, 60) === false)
122
		{
123
			$this_user = $this->db->fetchQuery('
124
				SELECT 
125
					mem.*, COALESCE(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type
126
				FROM {db_prefix}members AS mem
127
					LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = {int:id_member})
128
				WHERE mem.id_member = {int:id_member}
129
				LIMIT 1',
130
				array(
131 5
					'id_member' => $this->id,
132
				)
133 5
			);
134
135 5
			$user_settings = $this_user->fetch_assoc();
136
			$this_user->free_result();
137 2
138 2
			if ($this->cache->levelHigherThan(1))
139
			{
140
				$this->cache->put('user_settings-' . $this->id, $user_settings, 60);
141
			}
142 3
		}
143
144
		// Did we find 'im?  If not, junk it.
145 5
		if (!empty($user_settings))
146
		{
147 5
			// Make the ID specifically an integer
148 5
			$user_settings['id_member'] = (int) ($user_settings['id_member'] ?? 0);
149
150
			// As much as the password should be right, we can assume the integration set things up.
151
			if (!empty($already_verified) && $already_verified === true)
152
			{
153
				$check = true;
154
			}
155
			// SHA-256 passwords should be 64 characters long.
156
			elseif (strlen($session_password) === 64)
157 2
			{
158
				$check = hash_equals(hash('sha256', ($user_settings['passwd'] . $user_settings['password_salt'])), $session_password);
159 2
			}
160
			else
161
			{
162 2
				$check = false;
163
			}
164 2
165
			// Wrong password or not activated - either way, you're going nowhere.
166
			$this->id = (int) $check && ($user_settings['is_activated'] == 1 || $user_settings['is_activated'] == 11) ? $user_settings['id_member'] : 0;
167
		}
168
		else
169
		{
170
			$this->id = 0;
171 2
			$user_settings = null;
172
		}
173
174
		$this->initSettings($user_settings);
175 2
176 2
		// If we no longer have the member maybe they're being all hackey, stop brute force!
177
		if (empty($this->id))
178 2
		{
179
			validatePasswordFlood($this->settings->id_member($this->id), $this->settings->passwd_flood(false), $this->id != 0);
0 ignored issues
show
Bug introduced by
The method id_member() does not exist on ElkArte\UserSettings. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

179
			validatePasswordFlood($this->settings->/** @scrutinizer ignore-call */ id_member($this->id), $this->settings->passwd_flood(false), $this->id != 0);
Loading history...
Bug introduced by
The method passwd_flood() does not exist on ElkArte\UserSettings. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

179
			validatePasswordFlood($this->settings->id_member($this->id), $this->settings->/** @scrutinizer ignore-call */ passwd_flood(false), $this->id != 0);
Loading history...
180
		}
181
	}
182
183
	/**
184
	 * Prepares the $this->settings property
185 2
	 *
186
	 * @param array $user_settings
187
	 */
188 2
	protected function initSettings($user_settings)
189
	{
190
		$this->settings = new UserSettings($user_settings);
191 2
	}
192
193 2
	/**
194
	 * Prepares the basic data necessary for $this->info
195
	 *
196
	 * @return array
197
	 */
198
	protected function initUser()
199
	{
200
		global $modSettings;
201
202
		// Let's not update the last visit time in these cases...
203
		// 1. SSI doesn't count as visiting the forum.
204
		// 2. RSS feeds and XMLHTTP requests don't count either.
205
		// 3. If it was set within this session, no need to set it again.
206 2
		// 4. New session, yet updated < five hours ago? Maybe cache can help.
207
		if (
208
			ELK !== 'SSI'
0 ignored issues
show
introduced by
The condition ElkArte\ELK !== 'SSI' is always false.
Loading history...
209
			&& !isset($_REQUEST['api']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] !== '.xml')
210
			&& empty($_SESSION['id_msg_last_visit'])
211
			&& (!$this->cache->isEnabled() || !$this->cache->getVar($_SESSION['id_msg_last_visit'], 'user_last_visit-' . $this->id, 5 * 3600))
212
		)
213
		{
214 2
			// @todo can this be cached?
215
			// Do a quick query to make sure this isn't a mistake.
216
			require_once(SUBSDIR . '/Messages.subs.php');
217 2
			$visitOpt = basicMessageInfo($this->settings['id_msg_last_visit'], true);
218
219
			$_SESSION['id_msg_last_visit'] = $this->settings['id_msg_last_visit'];
220
221 2
			// If it was *at least* five hours ago...
222
			if ($visitOpt === false || $visitOpt['poster_time'] < time() - 5 * 3600)
223
			{
224
				require_once(SUBSDIR . '/Members.subs.php');
225
				updateMemberData($this->id, array('id_msg_last_visit' => (int) $modSettings['maxMsgID'], 'last_login' => time(), 'member_ip' => $this->req->client_ip(), 'member_ip2' => $this->req->ban_ip()));
226
				$this->settings->updateLastLogin();
227
228 5
				if ($this->cache->levelHigherThan(1))
229
				{
230 5
					$this->cache->put('user_settings-' . $this->id, $this->settings->toArray(), 60);
231 5
				}
232
233
				$this->cache->put('user_last_visit-' . $this->id, $_SESSION['id_msg_last_visit'], 5 * 3600);
234
			}
235
		}
236
		elseif (empty($_SESSION['id_msg_last_visit']))
237
		{
238 2
			$_SESSION['id_msg_last_visit'] = $this->settings['id_msg_last_visit'];
239
		}
240 2
241
		$this->member_name = $this->settings['member_name'];
242
243
		if (empty($this->settings['additional_groups']))
244
		{
245
			$user_info = array(
246
				'groups' => array($this->settings['id_group'], $this->settings['id_post_group'])
247
			);
248 2
		}
249 2
		else
250 2
		{
251 2
			$user_info = array(
252
				'groups' => array_merge(
253
					array($this->settings['id_group'], $this->settings['id_post_group']),
254
					explode(',', $this->settings['additional_groups'])
0 ignored issues
show
Bug introduced by
It seems like $this->settings['additional_groups'] can also be of type null; however, parameter $string of explode() 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

254
					explode(',', /** @scrutinizer ignore-type */ $this->settings['additional_groups'])
Loading history...
255
				)
256 2
			);
257 2
		}
258
259 2
		// Because history has proven that it is possible for groups to go bad - clean up in case.
260
		foreach ($user_info['groups'] as $k => $v)
261
		{
262 2
			$user_info['groups'][$k] = (int) $v;
263
		}
264 2
265 2
		// This is a logged in user, so definitely not a spider.
266 2
		$user_info['possibly_robot'] = false;
267
268 2
		// Lets upgrade the salt if needed.
269
		if ($this->settings->fixSalt())
0 ignored issues
show
Bug introduced by
The method fixSalt() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

269
		if ($this->settings->/** @scrutinizer ignore-call */ fixSalt())
Loading history...
270
		{
271
			require_once(SUBSDIR . '/Members.subs.php');
272
			require_once(SUBSDIR . '/Auth.subs.php');
273 2
274
			updateMemberData($this->settings['id_member'], array('password_salt' => $this->settings['password_salt']));
275
			setLoginCookie(60 * $modSettings['cookieTime'], $this->settings['id_member'], hash('sha256', ($this->settings['passwd'] . $this->settings['password_salt'])));
276
		}
277
278
		return $user_info;
279
	}
280
281 2
	/**
282
	 * Initialize the data necessary to "load" a guest
283 2
	 *
284
	 * @return array
285
	 */
286 2
	protected function initGuest()
287
	{
288
		global $cookiename, $context, $modSettings;
289
290
		// This is what a guest's variables should be.
291
		$this->member_name = '';
292
		$user_info = ['groups' => [-1]];
293
		$this->initSettings([]);
294
295
		if (isset($_COOKIE[$cookiename]))
296
		{
297
			$_COOKIE[$cookiename] = '';
298
		}
299
300 2
		// Create a login token if it doesn't exist yet.
301
		if (!isset($_SESSION['token']['post-login']))
302 2
		{
303
			createToken('login');
304
		}
305
		else
306 2
		{
307
			[$context['login_token_var'], , , $context['login_token']] = $_SESSION['token']['post-login'];
308 2
		}
309
310
		// Do we perhaps think this is a search robot?
311
		require_once(SUBSDIR . '/SearchEngines.subs.php');
312
		$user_info['possibly_robot'] = spiderCheck();
313
314
		// If detected as a robot, are we moving them to a special spider_group
315
		if (!empty($user_info['possibly_robot']) && !empty($modSettings['spider_group']) && !empty($modSettings['spider_no_guest']))
316 3
		{
317
			$user_info['groups'] = [$modSettings['spider_group']];
318 3
		}
319
320
		return $user_info;
321 3
	}
322 3
323 3
	/**
324
	 * Fills up the $this->info variable
325 3
	 *
326
	 * @param array $user_info
327
	 */
328
	protected function compileInfo($user_info)
329
	{
330
		global $modSettings;
331 3
332
		// Set up the $user_info array.
333 3
		$user_info += array(
334
			'id' => $this->id,
335
			'username' => $this->member_name,
336
			'name' => $this->settings->real_name(''),
0 ignored issues
show
Bug introduced by
The method real_name() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

336
			'name' => $this->settings->/** @scrutinizer ignore-call */ real_name(''),
Loading history...
337
			'email' => $this->settings->email_address(''),
0 ignored issues
show
Bug introduced by
The method email_address() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

337
			'email' => $this->settings->/** @scrutinizer ignore-call */ email_address(''),
Loading history...
338
			'passwd' => $this->settings->passwd(''),
0 ignored issues
show
Bug introduced by
The method passwd() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

338
			'passwd' => $this->settings->/** @scrutinizer ignore-call */ passwd(''),
Loading history...
339
			'language' => $this->getLanguage(),
340
			'is_guest' => $this->id === 0,
341 3
			'is_admin' => in_array(1, $user_info['groups']),
342
			'is_mod' => false,
343
			'theme' => (int) $this->settings->id_theme,
0 ignored issues
show
Bug Best Practice introduced by
The property id_theme does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
344
			'last_login' => (int) $this->settings->last_login,
0 ignored issues
show
Bug Best Practice introduced by
The property last_login does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
345
			'ip' => $this->req->client_ip(),
346 3
			'ip2' => $this->req->ban_ip(),
347
			'posts' => (int) $this->settings->posts,
0 ignored issues
show
Bug Best Practice introduced by
The property posts does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
348
			'time_format' => $this->settings->getEmpty('time_format', $modSettings['time_format']),
349
			'time_offset' => (int) $this->settings->time_offset,
0 ignored issues
show
Bug Best Practice introduced by
The property time_offset does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
350
			'avatar' => $this->buildAvatarArray(),
351
			'messages' => (int) $this->settings->personal_messages,
0 ignored issues
show
Bug Best Practice introduced by
The property personal_messages does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
352
			'mentions' => max(0, (int) $this->settings->mentions),
0 ignored issues
show
Bug Best Practice introduced by
The property mentions does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
353 3
			'unread_messages' => (int) $this->settings->unread_messages,
0 ignored issues
show
Bug Best Practice introduced by
The property unread_messages does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
354 3
			'total_time_logged_in' => (int) $this->settings->total_time_logged_in,
0 ignored issues
show
Bug Best Practice introduced by
The property total_time_logged_in does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
355
			'buddies' => empty($modSettings['enable_buddylist']) ? [] : (empty($this->settings->buddy_list) ? [] : explode(',', (string) $this->settings->buddy_list)),
0 ignored issues
show
Bug Best Practice introduced by
The property buddy_list does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
356
			'ignoreboards' => explode(',', (string) $this->settings->ignore_boards),
0 ignored issues
show
Bug Best Practice introduced by
The property ignore_boards does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
357 3
			'ignoreusers' => explode(',', (string) $this->settings->pm_ignore_list),
0 ignored issues
show
Bug Best Practice introduced by
The property pm_ignore_list does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
358
			'warning' => (int) $this->settings->warning,
0 ignored issues
show
Bug Best Practice introduced by
The property warning does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
359
			'permissions' => [],
360
		);
361
		$user_info['groups'] = array_unique($user_info['groups']);
362
363
		// Make sure that the last item in ignore boards array is valid.
364
		//  If the list was too long it could have an ending comma that could cause problems.
365 5
		if (!empty($user_info['ignoreboards']) && empty($user_info['ignoreboards'][$tmp = count($user_info['ignoreboards']) - 1]))
366
		{
367 5
			unset($user_info['ignoreboards'][$tmp]);
368
		}
369
370
		// Just build this here, it makes it easier to change/use - administrators can see all boards.
371 5
		if ($user_info['is_admin'])
372 5
		{
373 5
			$user_info['query_see_board'] = '1=1';
374 5
		}
375 5
		// Otherwise, just the groups in $user_info['groups'].
376 5
		else
377 5
		{
378 5
			$user_info['query_see_board'] = '((FIND_IN_SET(' . implode(', b.member_groups) != 0 OR FIND_IN_SET(', $user_info['groups']) . ', b.member_groups) != 0)' . (empty($modSettings['deny_boards_access']) ? '' : ' AND (FIND_IN_SET(' . implode(', b.deny_member_groups) = 0 AND FIND_IN_SET(', $user_info['groups']) . ', b.deny_member_groups) = 0)') . (isset($user_info['mod_cache']) ? ' OR ' . $user_info['mod_cache']['mq'] : '') . ')';
379
		}
380 5
381 5
		$this->db->setSeeBoard($user_info['query_see_board']);
0 ignored issues
show
Bug introduced by
The method setSeeBoard() does not exist on ElkArte\Database\QueryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to ElkArte\Database\QueryInterface. ( Ignorable by Annotation )

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

381
		$this->db->/** @scrutinizer ignore-call */ 
382
             setSeeBoard($user_info['query_see_board']);
Loading history...
382 5
383 5
		// Build the list of boards they WANT to see.
384 5
		// This will take the place of query_see_boards in certain spots, so it better include the boards they can see also
385 5
386 5
		// If they aren't ignoring any boards then they want to see all the boards they can see
387 5
		if (empty($user_info['ignoreboards']))
388 5
		{
389 5
			$user_info['query_wanna_see_board'] = $user_info['query_see_board'];
390 5
		}
391 5
		// Ok I guess they don't want to see all the boards
392 5
		else
393 5
		{
394 5
			$user_info['query_wanna_see_board'] = '(' . $user_info['query_see_board'] . ' AND b.id_board NOT IN (' . implode(',', $user_info['ignoreboards']) . '))';
395 5
		}
396 5
397
		$this->db->setWannaSeeBoard($user_info['query_wanna_see_board']);
0 ignored issues
show
Bug introduced by
The method setWannaSeeBoard() does not exist on ElkArte\Database\QueryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to ElkArte\Database\QueryInterface. ( Ignorable by Annotation )

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

397
		$this->db->/** @scrutinizer ignore-call */ 
398
             setWannaSeeBoard($user_info['query_wanna_see_board']);
Loading history...
398
399 5
		$this->info = new UserInfo($user_info);
400
	}
401
402 5
	/**
403
	 * Determines the language to be used.
404 5
	 * Checks the current user setting, the $_GET['language'], the session and $modSettings
405
	 *
406
	 * @return string
407
	 */
408 5
	protected function getLanguage()
409
	{
410 2
		global $modSettings, $language;
411
412
		$user_lang = $this->settings->getEmpty('lngfile', $language);
413
414
		// Do we have any languages to validate this?
415 3
		if (!empty($modSettings['userLanguage']) && (!empty($_GET['language']) || !empty($_SESSION['language'])))
416
		{
417
			$languages = getLanguages();
418 5
419
			// Allow the user to change their language if its valid.
420
			if (!empty($modSettings['userLanguage']) && !empty($_GET['language']) && isset($languages[strtr($_GET['language'], './\\:', '____')]))
421
			{
422
				$user_lang = strtr($_GET['language'], './\\:', '____');
423
				$_SESSION['language'] = $user_lang;
424 5
			}
425
			elseif (!empty($modSettings['userLanguage']) && !empty($_SESSION['language']) && isset($languages[strtr($_SESSION['language'], './\\:', '____')]))
426 5
			{
427
				$user_lang = strtr($_SESSION['language'], './\\:', '____');
428
			}
429
		}
430
431
		return $user_lang;
432
	}
433 5
434
	/**
435 5
	 * Prepares the data of the avatar (path, url, etc.)
436 5
	 *
437
	 * @return array
438
	 */
439
	protected function buildAvatarArray()
440
	{
441
		return array_merge([
442
			'url' => $this->settings->avatar(''),
0 ignored issues
show
Bug introduced by
The method avatar() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

442
			'url' => $this->settings->/** @scrutinizer ignore-call */ avatar(''),
Loading history...
443
			'filename' => $this->settings->getEmpty('filename', ''),
444
			'custom_dir' => $this->settings['attachment_type'] == 1,
445
			'id_attach' => (int) $this->settings->id_attach
0 ignored issues
show
Bug Best Practice introduced by
The property id_attach does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __get, consider adding a @property annotation.
Loading history...
446 5
		], determineAvatar($this->settings));
0 ignored issues
show
Bug introduced by
$this->settings of type ElkArte\Helper\ValuesContainerReadOnly is incompatible with the type array expected by parameter $profile of determineAvatar(). ( Ignorable by Annotation )

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

446
		], determineAvatar(/** @scrutinizer ignore-type */ $this->settings));
Loading history...
447
	}
448 5
449
	/**
450 5
	 * Repeat the hashing of the password, either because it was not previously
451
	 * hashed or because it needs a new one
452
	 *
453 5
	 * @param string $password
454
	 */
455
	public function rehashPassword($password)
456
	{
457
		$this->settings->rehashPassword($password);
0 ignored issues
show
Bug introduced by
The method rehashPassword() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

457
		$this->settings->/** @scrutinizer ignore-call */ 
458
                   rehashPassword($password);
Loading history...
458
	}
459
460
	/**
461
	 * Checks the provided password is the same as the one in the database.
462
	 *
463
	 * @param string $password
464
	 * @return bool
465
	 */
466
	public function validatePassword($password)
467
	{
468
		return $this->settings->validatePassword($password);
0 ignored issues
show
Bug introduced by
The method validatePassword() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

468
		return $this->settings->/** @scrutinizer ignore-call */ validatePassword($password);
Loading history...
469 5
	}
470
471
	/**
472
	 * Check activation status of the current user.
473
	 *
474
	 * What it does:
475
	 * is_activated value key is as follows:
476
	 * - > 10 Banned with activation status as value - 10
477 5
	 * - 5 = Awaiting COPPA consent
478
	 * - 4 = Awaiting Deletion approval
479 5
	 * - 3 = Awaiting Admin approval
480 5
	 * - 2 = Awaiting reactivation from email change
481 5
	 * - 1 = Approved and active
482 5
	 * - 0 = Not active
483 5
	 *
484 5
	 * @param bool $undelete - whether the current request is to revert the
485
	 *                         request to delete the account or not
486
	 *
487
	 * @return bool
488
	 * @throws Exception
489
	 */
490
	public function checkActivation($undelete)
491
	{
492
		global $context, $txt, $modSettings;
493
494
		if (!isset($context['login_errors']))
495
		{
496
			$context['login_errors'] = array();
497
		}
498
499
		// What is the true activation status of this account?
500
		$activation_status = $this->settings->getActivationStatus();
0 ignored issues
show
Bug introduced by
The method getActivationStatus() does not exist on ElkArte\Helper\ValuesContainerReadOnly. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

500
		/** @scrutinizer ignore-call */ 
501
  $activation_status = $this->settings->getActivationStatus();
Loading history...
501
502
		// Check if the account is activated - COPPA first...
503
		if ($activation_status === 5)
504
		{
505
			$context['login_errors'][] = $txt['coppa_no_concent'] . ' <a href="' . getUrl('action', ['action' => 'about', 'sa' => 'coppa', 'member' => $this->settings['id_member']]) . '">' . $txt['coppa_need_more_details'] . '</a>';
506
507
			return false;
508
		}
509
510
		// Awaiting approval still?
511
		if ($activation_status === 3)
512
		{
513
			throw new Exception('still_awaiting_approval', 'user');
514
		}
515
516
		// Awaiting deletion, changed their mind?
517
		if ($activation_status === 4)
518
		{
519
			if ($undelete)
520
			{
521
				require_once(SUBSDIR . '/Members.subs.php');
522
				updateMemberData($this->settings['id_member'], array('is_activated' => 1));
523
				updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > 0 ? $modSettings['unapprovedMembers'] - 1 : 0)));
524
525
				return true;
526
			}
527
528
			$context['login_errors'][] = $txt['awaiting_delete_account'];
529
			$context['login_show_undelete'] = true;
530
531
			return false;
532
		}
533
534
		// Standard activation?
535
		if ($activation_status !== 1)
536
		{
537
			\ElkArte\Errors\Errors::instance()->log_error($txt['activate_not_completed1'] . ' - <span class="remove">' . $this->settings['member_name'] . '</span>', false);
0 ignored issues
show
Bug introduced by
The type ElkArte\Errors\Errors was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
538
539
			$context['login_errors'][] = $txt['activate_not_completed1'] . ' <a class="linkbutton" href="' . getUrl('action', ['action' => 'register', 'sa' => 'activate', 'resend', 'u' => $this->settings['id_member']]) . '">' . $txt['activate_not_completed2'] . '</a>';
540
541
			return false;
542
		}
543
544
		return true;
545
	}
546
}
547