1
|
|
|
<?php |
|
|
|
|
2
|
|
|
require_once('MODx.php'); |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* Class modUsers |
6
|
|
|
*/ |
7
|
|
|
class modUsers extends MODxAPI |
|
|
|
|
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* @var array |
11
|
|
|
*/ |
12
|
|
|
protected $default_field = array( |
13
|
|
|
'user' => array( |
14
|
|
|
'username' => '', |
15
|
|
|
'password' => '', |
16
|
|
|
'cachepwd' => '' |
17
|
|
|
), |
18
|
|
|
'attribute' => array( |
19
|
|
|
'fullname' => '', |
20
|
|
|
'role' => '', |
21
|
|
|
'email' => '', |
22
|
|
|
'phone' => '', |
23
|
|
|
'mobilephone' => '', |
24
|
|
|
'blocked' => 0, |
25
|
|
|
'blockeduntil' => 0, |
26
|
|
|
'blockedafter' => 0, |
27
|
|
|
'logincount' => 0, |
28
|
|
|
'lastlogin' => 0, |
29
|
|
|
'thislogin' => 0, |
30
|
|
|
'failedlogincount' => 0, |
31
|
|
|
'sessionid' => '', |
32
|
|
|
'dob' => 0, |
33
|
|
|
'gender' => 0, |
34
|
|
|
'country' => '', |
35
|
|
|
'state' => '', |
36
|
|
|
'city' => '', |
37
|
|
|
'street' => '', |
38
|
|
|
'zip' => '', |
39
|
|
|
'fax' => '', |
40
|
|
|
'photo' => '', |
41
|
|
|
'comment' => '', |
42
|
|
|
'createdon' => 0, |
43
|
|
|
'editedon' => 0 |
44
|
|
|
), |
45
|
|
|
'hidden' => array( |
46
|
|
|
'internalKey' |
47
|
|
|
) |
48
|
|
|
); |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var string |
52
|
|
|
*/ |
53
|
|
|
protected $givenPassword = ''; |
54
|
|
|
protected $groupIds = array(); |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @var integer |
58
|
|
|
*/ |
59
|
|
|
private $rememberTime; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* MODxAPI constructor. |
63
|
|
|
* @param DocumentParser $modx |
64
|
|
|
* @param bool $debug |
65
|
|
|
* @throws Exception |
66
|
|
|
*/ |
67
|
|
|
public function __construct(DocumentParser $modx, $debug = false) |
68
|
|
|
{ |
69
|
|
|
$this->setRememberTime(60 * 60 * 24 * 365 * 5); |
70
|
|
|
parent::__construct($modx, $debug); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @param $val |
75
|
|
|
* @return $this |
76
|
|
|
*/ |
77
|
|
|
protected function setRememberTime($val){ |
78
|
|
|
$this->rememberTime = (int)$val; |
79
|
|
|
return $this; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @return integer |
84
|
|
|
*/ |
85
|
|
|
public function getRememberTime(){ |
86
|
|
|
return $this->rememberTime; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @param $key |
91
|
|
|
* @return bool |
92
|
|
|
*/ |
93
|
|
|
public function issetField($key) |
94
|
|
|
{ |
95
|
|
|
return (array_key_exists($key, $this->default_field['user']) || array_key_exists($key, |
96
|
|
|
$this->default_field['attribute']) || in_array($key, $this->default_field['hidden'])); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @param string $data |
101
|
|
|
* @return string|false |
102
|
|
|
*/ |
103
|
|
|
protected function findUser($data) |
104
|
|
|
{ |
105
|
|
|
switch (true) { |
106
|
|
|
case (is_int($data) || ((int)$data > 0 && (string)intval($data) === $data)): |
107
|
|
|
$find = 'attribute.internalKey'; |
108
|
|
|
break; |
109
|
|
|
case filter_var($data, FILTER_VALIDATE_EMAIL): |
110
|
|
|
$find = 'attribute.email'; |
111
|
|
|
break; |
112
|
|
|
case is_scalar($data): |
113
|
|
|
$find = 'user.username'; |
114
|
|
|
break; |
115
|
|
|
default: |
116
|
|
|
$find = false; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
return $find; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @param array $data |
124
|
|
|
* @return $this |
125
|
|
|
*/ |
126
|
|
|
public function create($data = array()) |
127
|
|
|
{ |
128
|
|
|
parent::create($data); |
129
|
|
|
$this->set('createdon', time()); |
130
|
|
|
|
131
|
|
|
return $this; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @param $id |
136
|
|
|
* @return $this |
137
|
|
|
*/ |
138
|
|
|
public function edit($id) |
139
|
|
|
{ |
140
|
|
|
$id = is_scalar($id) ? trim($id) : ''; |
141
|
|
|
if ($this->getID() != $id) { |
142
|
|
|
$this->close(); |
143
|
|
|
$this->newDoc = false; |
144
|
|
|
|
145
|
|
|
if (!$find = $this->findUser($id)) { |
146
|
|
|
$this->id = null; |
147
|
|
|
} else { |
148
|
|
|
$this->set('editedon', time()); |
149
|
|
|
$this->editQuery($find, $id); |
150
|
|
|
$this->id = empty($this->field['internalKey']) ? null : $this->get('internalKey'); |
151
|
|
|
$this->store($this->toArray()); |
152
|
|
|
unset($this->field['id']); |
153
|
|
|
unset($this->field['internalKey']); |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
return $this; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @param string $find |
162
|
|
|
* @param string $id |
163
|
|
|
*/ |
164
|
|
|
protected function editQuery($find, $id) { |
165
|
|
|
$result = $this->query(" |
166
|
|
|
SELECT * from {$this->makeTable('web_user_attributes')} as attribute |
167
|
|
|
LEFT JOIN {$this->makeTable('web_users')} as user ON user.id=attribute.internalKey |
168
|
|
|
WHERE BINARY {$find}='{$this->escape($id)}' |
169
|
|
|
"); |
170
|
|
|
$this->field = $this->modx->db->getRow($result); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param string $key |
175
|
|
|
* @param $value |
176
|
|
|
* @return $this |
177
|
|
|
*/ |
178
|
|
|
public function set($key, $value) |
179
|
|
|
{ |
180
|
|
|
if (is_scalar($value) && is_scalar($key) && !empty($key)) { |
181
|
|
|
switch ($key) { |
182
|
|
|
case 'password': |
183
|
|
|
$this->givenPassword = $value; |
184
|
|
|
$value = $this->getPassword($value); |
185
|
|
|
break; |
186
|
|
|
case 'sessionid': |
187
|
|
|
session_regenerate_id(false); |
188
|
|
|
$value = session_id(); |
189
|
|
|
if ($mid = $this->modx->getLoginUserID('mgr')) { |
190
|
|
|
$this->modx->db->query("UPDATE {$this->makeTable('active_user_locks')} SET `sid`='{$value}' WHERE `internalKey`={$mid}"); |
191
|
|
|
$this->modx->db->query("UPDATE {$this->makeTable('active_user_sessions')} SET `sid`='{$value}' WHERE `internalKey`={$mid}"); |
192
|
|
|
$this->modx->db->query("UPDATE {$this->makeTable('active_users')} SET `sid`='{$value}' WHERE `internalKey`={$mid}"); |
193
|
|
|
} |
194
|
|
|
break; |
195
|
|
|
case 'editedon': |
196
|
|
|
case 'createdon': |
197
|
|
|
$value = $this->getTime($value); |
198
|
|
|
break; |
199
|
|
|
} |
200
|
|
|
$this->field[$key] = $value; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
return $this; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* @param $pass |
208
|
|
|
* @return string |
209
|
|
|
*/ |
210
|
|
|
public function getPassword($pass) |
211
|
|
|
{ |
212
|
|
|
return md5($pass); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @param bool $fire_events |
217
|
|
|
* @param bool $clearCache |
218
|
|
|
* @return bool|int|null|void |
219
|
|
|
*/ |
220
|
|
|
public function save($fire_events = false, $clearCache = false) |
221
|
|
|
{ |
222
|
|
|
if ($this->get('email') == '' || $this->get('username') == '' || $this->get('password') == '') { |
223
|
|
|
$this->log['EmptyPKField'] = 'Email, username or password is empty <pre>' . print_r($this->toArray(), |
224
|
|
|
true) . '</pre>'; |
225
|
|
|
|
226
|
|
|
return false; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
if (!$this->checkUnique('web_users', 'username')) { |
230
|
|
|
$this->log['UniqueUsername'] = 'username not unique <pre>' . print_r($this->get('username'), |
231
|
|
|
true) . '</pre>'; |
232
|
|
|
|
233
|
|
|
return false; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
if (!$this->checkUnique('web_user_attributes', 'email', 'internalKey')) { |
237
|
|
|
$this->log['UniqueEmail'] = 'Email not unique <pre>' . print_r($this->get('email'), true) . '</pre>'; |
238
|
|
|
|
239
|
|
|
return false; |
240
|
|
|
} |
241
|
|
|
$this->set('sessionid', ''); |
242
|
|
|
$fld = $this->toArray(); |
243
|
|
|
foreach ($this->default_field['user'] as $key => $value) { |
244
|
|
|
$tmp = $this->get($key); |
245
|
|
|
if ($this->newDoc && (!is_int($tmp) && $tmp == '')) { |
246
|
|
|
$this->field[$key] = $value; |
247
|
|
|
} |
248
|
|
|
$this->Uset($key, 'user'); |
249
|
|
|
unset($fld[$key]); |
250
|
|
|
} |
251
|
|
|
if (!empty($this->set['user'])) { |
252
|
|
|
if ($this->newDoc) { |
253
|
|
|
$SQL = "INSERT into {$this->makeTable('web_users')} SET " . implode(', ', $this->set['user']); |
254
|
|
|
} else { |
255
|
|
|
$SQL = "UPDATE {$this->makeTable('web_users')} SET " . implode(', ', |
256
|
|
|
$this->set['user']) . " WHERE id = " . $this->id; |
257
|
|
|
} |
258
|
|
|
$this->query($SQL); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
if ($this->newDoc) { |
262
|
|
|
$this->id = $this->modx->db->getInsertId(); |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
$this->saveQuery($fld); |
266
|
|
|
unset($fld['id']); |
267
|
|
|
|
268
|
|
|
foreach ($fld as $key => $value) { |
269
|
|
|
if ($value == '' || !$this->isChanged($key)) { |
270
|
|
|
continue; |
271
|
|
|
} |
272
|
|
|
$result = $this->query("SELECT `setting_value` FROM {$this->makeTable('web_user_settings')} WHERE `webuser` = '{$this->id}' AND `setting_name` = '{$key}'"); |
273
|
|
|
if ($this->modx->db->getRecordCount($result) > 0) { |
274
|
|
|
$this->query("UPDATE {$this->makeTable('web_user_settings')} SET `setting_value` = '{$value}' WHERE `webuser` = '{$this->id}' AND `setting_name` = '{$key}';"); |
275
|
|
|
} else { |
276
|
|
|
$this->query("INSERT into {$this->makeTable('web_user_settings')} SET `webuser` = {$this->id},`setting_name` = '{$key}',`setting_value` = '{$value}';"); |
277
|
|
|
} |
278
|
|
|
} |
279
|
|
|
if (!$this->newDoc && $this->givenPassword) { |
280
|
|
|
$this->invokeEvent('OnWebChangePassword', array( |
281
|
|
|
'userObj' => $this, |
282
|
|
|
'userid' => $this->id, |
283
|
|
|
'user' => $this->toArray(), |
284
|
|
|
'userpassword' => $this->givenPassword, |
285
|
|
|
'internalKey' => $this->id, |
286
|
|
|
'username' => $this->get('username') |
287
|
|
|
), $fire_events); |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
if (!empty($this->groupIds)) $this->setUserGroups($this->id, $this->groupIds); |
291
|
|
|
|
292
|
|
|
$this->invokeEvent('OnWebSaveUser', array( |
293
|
|
|
'userObj' => $this, |
294
|
|
|
'mode' => $this->newDoc ? "new" : "upd", |
295
|
|
|
'id' => $this->id, |
296
|
|
|
'user' => $this->toArray() |
297
|
|
|
), $fire_events); |
298
|
|
|
|
299
|
|
|
if ($clearCache) { |
300
|
|
|
$this->clearCache($fire_events); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
return $this->id; |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
/** |
307
|
|
|
* @param array $fld |
308
|
|
|
*/ |
309
|
|
|
protected function saveQuery(array &$fld) { |
310
|
|
|
foreach ($this->default_field['attribute'] as $key => $value) { |
311
|
|
|
$tmp = $this->get($key); |
312
|
|
|
if ($this->newDoc && (!is_int($tmp) && $tmp == '')) { |
313
|
|
|
$this->field[$key] = $value; |
314
|
|
|
} |
315
|
|
|
$this->Uset($key, 'attribute'); |
316
|
|
|
unset($fld[$key]); |
317
|
|
|
} |
318
|
|
|
if (!empty($this->set['attribute'])) { |
319
|
|
|
if ($this->newDoc) { |
320
|
|
|
$this->set('internalKey', $this->id)->Uset('internalKey', 'attribute'); |
321
|
|
|
$SQL = "INSERT into {$this->makeTable('web_user_attributes')} SET " . implode(', ', |
322
|
|
|
$this->set['attribute']); |
323
|
|
|
} else { |
324
|
|
|
$SQL = "UPDATE {$this->makeTable('web_user_attributes')} SET " . implode(', ', |
325
|
|
|
$this->set['attribute']) . " WHERE internalKey = " . $this->getID(); |
326
|
|
|
} |
327
|
|
|
$this->query($SQL); |
328
|
|
|
} |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
/** |
332
|
|
|
* @param $ids |
333
|
|
|
* @param bool $fire_events |
334
|
|
|
* @return bool|null|void |
335
|
|
|
*/ |
336
|
|
|
public function delete($ids, $fire_events = false) |
337
|
|
|
{ |
338
|
|
|
if ($this->edit($ids)) { |
339
|
|
|
$flag = $this->deleteQuery(); |
340
|
|
|
$this->query("DELETE FROM {$this->makeTable('web_user_settings')} WHERE webuser='{$this->getID()}'"); |
341
|
|
|
$this->query("DELETE FROM {$this->makeTable('web_groups')} WHERE webuser='{$this->getID()}'"); |
342
|
|
|
$this->invokeEvent('OnWebDeleteUser', array( |
343
|
|
|
'userObj' => $this, |
344
|
|
|
'userid' => $this->getID(), |
345
|
|
|
'internalKey' => $this->getID(), |
346
|
|
|
'username' => $this->get('username'), |
347
|
|
|
'timestamp' => time() |
348
|
|
|
), $fire_events); |
349
|
|
|
} else { |
350
|
|
|
$flag = false; |
351
|
|
|
} |
352
|
|
|
$this->close(); |
353
|
|
|
|
354
|
|
|
return $flag; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
protected function deleteQuery() { |
358
|
|
|
return $this->query(" |
359
|
|
|
DELETE user,attribute FROM {$this->makeTable('web_user_attributes')} as attribute |
360
|
|
|
LEFT JOIN {$this->makeTable('web_users')} as user ON user.id=attribute.internalKey |
361
|
|
|
WHERE attribute.internalKey='{$this->escape($this->getID())}'"); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* @param int $id |
366
|
|
|
* @param bool|integer $fulltime |
367
|
|
|
* @param string $cookieName |
368
|
|
|
* @param bool $fire_events |
369
|
|
|
* @return bool |
370
|
|
|
*/ |
371
|
|
|
public function authUser($id = 0, $fulltime = true, $cookieName = 'WebLoginPE', $fire_events = false) |
372
|
|
|
{ |
373
|
|
|
$flag = false; |
374
|
|
|
if (null === $this->getID() && $id) { |
375
|
|
|
$this->edit($id); |
376
|
|
|
} |
377
|
|
|
if (null !== $this->getID()) { |
378
|
|
|
$flag = true; |
379
|
|
|
$this->save(false); |
380
|
|
|
$this->SessionHandler('start', $cookieName, $fulltime); |
381
|
|
|
$this->invokeEvent("OnWebLogin", array( |
382
|
|
|
'userObj' => $this, |
383
|
|
|
'userid' => $this->getID(), |
384
|
|
|
'username' => $this->get('username'), |
385
|
|
|
'userpassword' => $this->givenPassword, |
386
|
|
|
'rememberme' => $fulltime |
387
|
|
|
), $fire_events); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
return $flag; |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
/** |
394
|
|
|
* @param int $id |
395
|
|
|
* @return bool |
396
|
|
|
*/ |
397
|
|
|
public function checkBlock($id = 0) |
398
|
|
|
{ |
399
|
|
|
$tmp = clone $this; |
400
|
|
|
if ($id && $tmp->getID() != $id) { |
401
|
|
|
$tmp->edit($id); |
402
|
|
|
} |
403
|
|
|
$now = time(); |
404
|
|
|
|
405
|
|
|
$b = $tmp->get('blocked'); |
406
|
|
|
$bu = $tmp->get('blockeduntil'); |
407
|
|
|
$ba = $tmp->get('blockedafter'); |
408
|
|
|
$flag = (($b && !$bu && !$ba) || ($bu && $now < $bu) || ($ba && $now > $ba)); |
409
|
|
|
unset($tmp); |
410
|
|
|
|
411
|
|
|
return $flag; |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* @param $id |
416
|
|
|
* @param $password |
417
|
|
|
* @param $blocker |
418
|
|
|
* @param bool $fire_events |
419
|
|
|
* @return bool |
420
|
|
|
*/ |
421
|
|
|
public function testAuth($id, $password, $blocker, $fire_events = false) |
422
|
|
|
{ |
423
|
|
|
$tmp = clone $this; |
424
|
|
|
if ($id && $tmp->getID() != $id) { |
425
|
|
|
$tmp->edit($id); |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
$flag = $pluginFlag = false; |
429
|
|
|
if ( |
430
|
|
|
(null !== $tmp->getID()) && (!$blocker || ($blocker && !$tmp->checkBlock($id))) |
431
|
|
|
) { |
432
|
|
|
$eventResult = $this->getInvokeEventResult('OnWebAuthentication', array( |
433
|
|
|
'userObj' => $this, |
434
|
|
|
'userid' => $tmp->getID(), |
435
|
|
|
'username' => $tmp->get('username'), |
436
|
|
|
'userpassword' => $password, |
437
|
|
|
'savedpassword' => $tmp->get('password') |
438
|
|
|
), $fire_events); |
439
|
|
|
if (is_array($eventResult)) { |
440
|
|
|
foreach ($eventResult as $result) { |
441
|
|
|
$pluginFlag = (bool)$result; |
442
|
|
|
} |
443
|
|
|
} else { |
444
|
|
|
$pluginFlag = (bool)$eventResult; |
445
|
|
|
} |
446
|
|
|
if (!$pluginFlag) { |
447
|
|
|
$flag = ($tmp->get('password') == $tmp->getPassword($password)); |
448
|
|
|
} |
449
|
|
|
} |
450
|
|
|
unset($tmp); |
451
|
|
|
|
452
|
|
|
return $flag || $pluginFlag; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* @param bool|integer $fulltime |
457
|
|
|
* @param string $cookieName |
458
|
|
|
* @return bool |
459
|
|
|
*/ |
460
|
|
|
public function AutoLogin($fulltime = true, $cookieName = 'WebLoginPE', $fire_events = null) |
|
|
|
|
461
|
|
|
{ |
462
|
|
|
$flag = false; |
463
|
|
|
if (isset($_COOKIE[$cookieName])) { |
464
|
|
|
$cookie = explode('|', $_COOKIE[$cookieName], 4); |
465
|
|
|
if (isset($cookie[0], $cookie[1], $cookie[2]) && strlen($cookie[0]) == 32 && strlen($cookie[1]) == 32) { |
466
|
|
|
if (!$fulltime && isset($cookie[4])) { |
467
|
|
|
$fulltime = (int)$cookie[4]; |
468
|
|
|
} |
469
|
|
|
$this->close(); |
470
|
|
|
$q = $this->modx->db->query("SELECT id FROM " . $this->makeTable('web_users') . " WHERE md5(username)='{$this->escape($cookie[0])}'"); |
471
|
|
|
$id = $this->modx->db->getValue($q); |
472
|
|
|
if ( |
473
|
|
|
$this->edit($id) |
474
|
|
|
&& null !== $this->getID() |
475
|
|
|
&& $this->get('password') == $cookie[1] |
476
|
|
|
&& $this->get('sessionid') == $cookie[2] |
477
|
|
|
&& !$this->checkBlock($this->getID()) |
478
|
|
|
) { |
479
|
|
|
$flag = $this->authUser($this->getID(), $fulltime, $cookieName, $fire_events); |
480
|
|
|
|
481
|
|
|
} |
482
|
|
|
} |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
return $flag; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* @param string $cookieName |
490
|
|
|
* @param bool $fire_events |
491
|
|
|
*/ |
492
|
|
|
public function logOut($cookieName = 'WebLoginPE', $fire_events = false) |
|
|
|
|
493
|
|
|
{ |
494
|
|
|
if (!$uid = $this->modx->getLoginUserID('web')) { |
495
|
|
|
return; |
496
|
|
|
} |
497
|
|
|
$params = array( |
498
|
|
|
'username' => $_SESSION['webShortname'], |
499
|
|
|
'internalKey' => $uid, |
500
|
|
|
'userid' => $uid // Bugfix by TS |
501
|
|
|
); |
502
|
|
|
$this->invokeEvent('OnBeforeWebLogout', $params, $fire_events); |
503
|
|
|
$this->SessionHandler('destroy', $cookieName ? $cookieName : 'WebLoginPE'); |
504
|
|
|
$this->invokeEvent('OnWebLogout', $params, $fire_events); |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* SessionHandler |
509
|
|
|
* Starts the user session on login success. Destroys session on error or logout. |
510
|
|
|
* |
511
|
|
|
* @param string $directive ('start' or 'destroy') |
512
|
|
|
* @param string $cookieName |
513
|
|
|
* @param bool|integer $remember |
514
|
|
|
* @return modUsers |
515
|
|
|
* @author Raymond Irving |
516
|
|
|
* @author Scotty Delicious |
517
|
|
|
* |
518
|
|
|
* remeber может быть числом в секундах |
519
|
|
|
*/ |
520
|
|
|
protected function SessionHandler($directive, $cookieName, $remember = true) |
|
|
|
|
521
|
|
|
{ |
522
|
|
|
switch ($directive) { |
523
|
|
|
case 'start': |
524
|
|
|
if ($this->getID() !== null) { |
525
|
|
|
$_SESSION['webShortname'] = $this->get('username'); |
526
|
|
|
$_SESSION['webFullname'] = $this->get('fullname'); |
527
|
|
|
$_SESSION['webEmail'] = $this->get('email'); |
528
|
|
|
$_SESSION['webValidated'] = 1; |
529
|
|
|
$_SESSION['webInternalKey'] = $this->getID(); |
530
|
|
|
$_SESSION['webValid'] = base64_encode($this->get('password')); |
531
|
|
|
$_SESSION['webUser'] = base64_encode($this->get('username')); |
532
|
|
|
$_SESSION['webFailedlogins'] = $this->get('failedlogincount'); |
533
|
|
|
$_SESSION['webLastlogin'] = $this->get('lastlogin'); |
534
|
|
|
$_SESSION['webnrlogins'] = $this->get('logincount'); |
535
|
|
|
$_SESSION['webUsrConfigSet'] = array(); |
536
|
|
|
$_SESSION['webUserGroupNames'] = $this->getUserGroups(); |
537
|
|
|
$_SESSION['webDocgroups'] = $this->getDocumentGroups(); |
538
|
|
|
if (!empty($remember)) { |
539
|
|
|
$this->setAutoLoginCookie($cookieName, $remember); |
540
|
|
|
} |
541
|
|
|
} |
542
|
|
|
break; |
543
|
|
|
case 'destroy': |
544
|
|
|
if (isset($_SESSION['mgrValidated'])) { |
545
|
|
|
unset($_SESSION['webShortname']); |
546
|
|
|
unset($_SESSION['webFullname']); |
547
|
|
|
unset($_SESSION['webEmail']); |
548
|
|
|
unset($_SESSION['webValidated']); |
549
|
|
|
unset($_SESSION['webInternalKey']); |
550
|
|
|
unset($_SESSION['webValid']); |
551
|
|
|
unset($_SESSION['webUser']); |
552
|
|
|
unset($_SESSION['webFailedlogins']); |
553
|
|
|
unset($_SESSION['webLastlogin']); |
554
|
|
|
unset($_SESSION['webnrlogins']); |
555
|
|
|
unset($_SESSION['webUsrConfigSet']); |
556
|
|
|
unset($_SESSION['webUserGroupNames']); |
557
|
|
|
unset($_SESSION['webDocgroups']); |
558
|
|
|
|
559
|
|
|
setcookie($cookieName, '', time() - 60, MODX_BASE_URL); |
560
|
|
|
} else { |
561
|
|
|
if (isset($_COOKIE[session_name()])) { |
562
|
|
|
setcookie(session_name(), '', time() - 60, MODX_BASE_URL); |
563
|
|
|
} |
564
|
|
|
setcookie($cookieName, '', time() - 60, MODX_BASE_URL); |
565
|
|
|
session_destroy(); |
566
|
|
|
} |
567
|
|
|
break; |
568
|
|
|
} |
569
|
|
|
|
570
|
|
|
return $this; |
571
|
|
|
} |
572
|
|
|
|
573
|
|
|
/** |
574
|
|
|
* @return bool |
575
|
|
|
*/ |
576
|
|
|
public function isSecure() |
577
|
|
|
{ |
578
|
|
|
$out = $this->modxConfig('server_protocol') == 'http' ? false : true; |
579
|
|
|
|
580
|
|
|
return $out; |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
/** |
584
|
|
|
* @param $cookieName |
585
|
|
|
* @param bool|integer $remember |
586
|
|
|
* @return $this |
587
|
|
|
*/ |
588
|
|
|
public function setAutoLoginCookie($cookieName, $remember = true) |
589
|
|
|
{ |
590
|
|
|
if (!empty($cookieName) && $this->getID() !== null) { |
591
|
|
|
$secure = $this->isSecure(); |
592
|
|
|
$remember = is_bool($remember) ? $this->getRememberTime() : (int)$remember; |
593
|
|
|
$cookieValue = array(md5($this->get('username')), $this->get('password'), $this->get('sessionid'), $remember); |
594
|
|
|
$cookieValue = implode('|', $cookieValue); |
595
|
|
|
$cookieExpires = time() + $remember; |
596
|
|
|
setcookie($cookieName, $cookieValue, $cookieExpires, MODX_BASE_URL, '', $secure, true); |
597
|
|
|
} |
598
|
|
|
|
599
|
|
|
return $this; |
600
|
|
|
} |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* @param int $userID |
604
|
|
|
* @return array |
605
|
|
|
*/ |
606
|
|
|
public function getDocumentGroups($userID = 0) |
607
|
|
|
{ |
608
|
|
|
$out = array(); |
609
|
|
|
$user = $this->switchObject($userID); |
610
|
|
|
if (null !== $user->getID()) { |
611
|
|
|
$web_groups = $this->modx->getFullTableName('web_groups'); |
612
|
|
|
$webgroup_access = $this->modx->getFullTableName('webgroup_access'); |
613
|
|
|
|
614
|
|
|
$sql = "SELECT `uga`.`documentgroup` FROM {$web_groups} as `ug` |
615
|
|
|
INNER JOIN {$webgroup_access} as `uga` ON `uga`.`webgroup`=`ug`.`webgroup` |
616
|
|
|
WHERE `ug`.`webuser` = " . $user->getID(); |
617
|
|
|
$out = $this->modx->db->getColumn('documentgroup', $this->query($sql)); |
618
|
|
|
|
619
|
|
|
} |
620
|
|
|
unset($user); |
621
|
|
|
|
622
|
|
|
return $out; |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* @param int $userID |
627
|
|
|
* @return array |
628
|
|
|
*/ |
629
|
|
|
public function getUserGroups($userID = 0) |
630
|
|
|
{ |
631
|
|
|
$out = array(); |
632
|
|
|
$user = $this->switchObject($userID); |
633
|
|
|
if (null !== $user->getID()) { |
634
|
|
|
$web_groups = $this->makeTable('web_groups'); |
635
|
|
|
$webgroup_names = $this->makeTable('webgroup_names'); |
636
|
|
|
|
637
|
|
|
$rs = $this->query("SELECT `ug`.`webgroup`, `ugn`.`name` FROM {$web_groups} as `ug` |
638
|
|
|
INNER JOIN {$webgroup_names} as `ugn` ON `ugn`.`id`=`ug`.`webgroup` |
639
|
|
|
WHERE `ug`.`webuser` = " . $user->getID()); |
640
|
|
|
while ($row = $this->modx->db->getRow($rs)) { |
641
|
|
|
$out[$row['webgroup']] = $row['name']; |
642
|
|
|
} |
643
|
|
|
} |
644
|
|
|
unset($user); |
645
|
|
|
|
646
|
|
|
return $out; |
647
|
|
|
} |
648
|
|
|
|
649
|
|
|
/** |
650
|
|
|
* @param int $userID |
651
|
|
|
* @param array $groupIds |
652
|
|
|
* @return $this |
653
|
|
|
*/ |
654
|
|
|
public function setUserGroups($userID = 0, $groupIds = array()) |
655
|
|
|
{ |
656
|
|
|
if (!is_array($groupIds)) return $this; |
657
|
|
|
if ($this->newDoc && $userID == 0) { |
658
|
|
|
$this->groupIds = $groupIds; |
659
|
|
|
} else { |
660
|
|
|
$user = $this->switchObject($userID); |
661
|
|
|
if ($uid = $user->getID()) { |
662
|
|
|
foreach ($groupIds as $gid) { |
663
|
|
|
$this->query("REPLACE INTO {$this->makeTable('web_groups')} (`webgroup`, `webuser`) VALUES ('{$gid}', '{$uid}')"); |
664
|
|
|
} |
665
|
|
|
if (!$this->newDoc) { |
666
|
|
|
$groupIds = empty($groupIds) ? '0' : implode(',', $groupIds); |
667
|
|
|
$this->query("DELETE FROM {$this->makeTable('web_groups')} WHERE `webuser`={$uid} AND `webgroup` NOT IN ({$groupIds})"); |
668
|
|
|
} |
669
|
|
|
} |
670
|
|
|
unset($user); |
671
|
|
|
$this->groupIds = array(); |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
return $this; |
675
|
|
|
} |
676
|
|
|
} |
677
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.