1 | <?php |
||||||
2 | |||||||
3 | /** |
||||||
4 | * @package ElkArte Forum |
||||||
5 | * @copyright ElkArte Forum contributors |
||||||
6 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||||||
7 | * |
||||||
8 | * This file contains code covered by: |
||||||
9 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||||||
10 | * |
||||||
11 | * @version 2.0 dev |
||||||
12 | * |
||||||
13 | */ |
||||||
14 | |||||||
15 | namespace ElkArte; |
||||||
16 | |||||||
17 | use ElkArte\Cache\Cache; |
||||||
18 | use ElkArte\Helper\ValuesContainer; |
||||||
19 | use ElkArte\Helper\ValuesContainerReadOnly; |
||||||
20 | |||||||
21 | /** |
||||||
22 | * This class holds all the data belonging to a certain member. |
||||||
23 | */ |
||||||
24 | class User |
||||||
25 | { |
||||||
26 | /** @var ValuesContainer Contains data regarding the user in a form that may be useful in the code Basically the former $user_info */ |
||||||
27 | public static $info; |
||||||
28 | |||||||
29 | /** @var ValuesContainerReadOnly Contains the data read from the db. Read-only by means of ValuesContainerReadOnly */ |
||||||
30 | public static $settings; |
||||||
31 | |||||||
32 | /** @var UserSettings The user object */ |
||||||
33 | protected static $instance; |
||||||
34 | |||||||
35 | /** @var int The user id */ |
||||||
36 | protected static $id = 0; |
||||||
37 | |||||||
38 | /** @var string The hashed password read from the cookies */ |
||||||
39 | protected static $session_password = ''; |
||||||
40 | |||||||
41 | /** |
||||||
42 | * Load all the important user information. |
||||||
43 | * |
||||||
44 | * @param bool $compat_mode if true sets the deprecated $user_info global |
||||||
45 | * @throws \Exception |
||||||
46 | */ |
||||||
47 | public static function load($compat_mode = false) |
||||||
48 | { |
||||||
49 | if (self::$instance === null) |
||||||
50 | { |
||||||
51 | $db = database(); |
||||||
52 | $cache = Cache::instance(); |
||||||
53 | $req = Request::instance(); |
||||||
54 | |||||||
55 | self::$instance = new UserSettingsLoader($db, $cache, $req); |
||||||
0 ignored issues
–
show
|
|||||||
56 | $already_verified = self::loadFromIntegration(); |
||||||
57 | self::loadFromCookie($req->user_agent()); |
||||||
58 | self::$instance->loadUserById(self::$id, $already_verified, self::$session_password); |
||||||
59 | self::$settings = self::$instance->getSettings(); |
||||||
60 | self::$info = self::$instance->getInfo(); |
||||||
61 | if ($compat_mode) |
||||||
62 | { |
||||||
63 | global $user_info; |
||||||
64 | $user_info = User::$info; |
||||||
65 | } |
||||||
66 | } |
||||||
67 | 143 | } |
|||||
68 | |||||||
69 | 143 | /** |
|||||
70 | * Tests any hook set to integrate_verify_user to set users |
||||||
71 | 1 | * according to alternative validations |
|||||
72 | 1 | * |
|||||
73 | 1 | * @event integrate_verify_user allow for integration to verify a user |
|||||
74 | */ |
||||||
75 | 1 | protected static function loadFromIntegration() |
|||||
76 | 1 | { |
|||||
77 | 1 | // Check first the integration, then the cookie, and last the session. |
|||||
78 | 1 | if (count($integration_ids = Hooks::instance()->hook('integrate_verify_user')) > 0) |
|||||
79 | 1 | { |
|||||
80 | 1 | foreach ($integration_ids as $integration_id) |
|||||
81 | 1 | { |
|||||
82 | $integration_id = (int) $integration_id; |
||||||
83 | 1 | if ($integration_id > 0) |
|||||
84 | 1 | { |
|||||
85 | self::$id = $integration_id; |
||||||
86 | |||||||
87 | 143 | return true; |
|||||
88 | } |
||||||
89 | } |
||||||
90 | } |
||||||
91 | |||||||
92 | return false; |
||||||
93 | } |
||||||
94 | |||||||
95 | 1 | /** |
|||||
96 | * Reads data from the cookie to load the user identity |
||||||
97 | * |
||||||
98 | 1 | * @param string $user_agent the Browser user agent, used to do some checkes |
|||||
99 | * based on the session data to reduce spamming and hacking |
||||||
100 | */ |
||||||
101 | protected static function loadFromCookie($user_agent) |
||||||
102 | { |
||||||
103 | global $cookiename, $modSettings; |
||||||
104 | |||||||
105 | if (empty(self::$id) && isset($_COOKIE[$cookiename])) |
||||||
106 | { |
||||||
107 | [$id, self::$session_password] = serializeToJson($_COOKIE[$cookiename], static function ($array_from) use ($cookiename) { |
||||||
108 | global $modSettings; |
||||||
109 | require_once(SUBSDIR . '/Auth.subs.php'); |
||||||
110 | $_COOKIE[$cookiename] = json_encode($array_from); |
||||||
111 | setLoginCookie(60 * $modSettings['cookieTime'], $array_from[0], $array_from[1]); |
||||||
112 | 1 | }); |
|||||
113 | |||||||
114 | self::$id = !empty($id) && self::$session_password !== '' ? (int) $id : 0; |
||||||
115 | } |
||||||
116 | elseif (empty(self::$id) && isset($_SESSION['login_' . $cookiename]) && (!empty($modSettings['disableCheckUA']) || (!empty($_SESSION['USER_AGENT']) && $_SESSION['USER_AGENT'] == $user_agent))) |
||||||
117 | { |
||||||
118 | // @todo Perhaps we can do some more checking on this, such as on the first octet of the IP? |
||||||
119 | [$id, self::$session_password, $login_span] = serializeToJson($_SESSION['login_' . $cookiename], static function ($array_from) use ($cookiename) { |
||||||
120 | $_SESSION['login_' . $cookiename] = json_encode($array_from); |
||||||
121 | 1 | }); |
|||||
122 | |||||||
123 | 1 | self::$id = !empty($id) && strlen(self::$session_password) === 64 && $login_span > time() ? (int) $id : 0; |
|||||
124 | } |
||||||
125 | 1 | } |
|||||
126 | |||||||
127 | /** |
||||||
128 | * Logout by setting user to guest |
||||||
129 | * |
||||||
130 | * @param false $compat_mode |
||||||
131 | */ |
||||||
132 | public static function logOutUser($compat_mode = false) |
||||||
133 | { |
||||||
134 | self::$instance->loadUserById(0, true, ''); |
||||||
0 ignored issues
–
show
The method
loadUserById() 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
![]() |
|||||||
135 | self::reloadByUser(self::$instance, $compat_mode); |
||||||
0 ignored issues
–
show
self::instance of type ElkArte\UserSettings is incompatible with the type ElkArte\UserSettingsLoader expected by parameter $user of ElkArte\User::reloadByUser() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
136 | } |
||||||
137 | 1 | ||||||
138 | /** |
||||||
139 | * Reload all the important user information into the static variables |
||||||
140 | * based on the \ElkArte\UserSettings object passed to it |
||||||
141 | * |
||||||
142 | * @param \ElkArte\UserSettingsLoader $user An user |
||||||
143 | * @param bool $compat_mode if true sets the deprecated $user_info global |
||||||
144 | */ |
||||||
145 | public static function reloadByUser(UserSettingsLoader $user, $compat_mode = false) |
||||||
146 | 1 | { |
|||||
147 | self::$instance = $user; |
||||||
0 ignored issues
–
show
It seems like
$user of type ElkArte\UserSettingsLoader is incompatible with the declared type ElkArte\UserSettings of property $instance .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||||||
148 | self::$settings = self::$instance->getSettings(); |
||||||
149 | self::$info = self::$instance->getInfo(); |
||||||
150 | if ($compat_mode) |
||||||
151 | { |
||||||
152 | global $user_info; |
||||||
153 | $user_info = User::$info; |
||||||
154 | } |
||||||
155 | } |
||||||
156 | } |
||||||
157 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..