|
1 | 1 | <?php |
2 | | -header('Content-type: application/json'); |
3 | 2 |
|
4 | | -$currentUser = erLhcoreClassUser::instance(); |
5 | | -$userData = $currentUser->getUserData(true); |
| 3 | +header('Content-Type: application/json'); |
| 4 | +$db = ezcDbInstance::get(); |
6 | 5 |
|
7 | | -if (!isset($_SERVER['HTTP_X_CSRFTOKEN']) || !$currentUser->validateCSFRToken($_SERVER['HTTP_X_CSRFTOKEN'])) { |
8 | | - echo json_encode(array('error' => true, 'active' => true)); |
9 | | - exit; |
10 | | -} |
| 6 | +try { |
| 7 | + $db->beginTransaction(); |
| 8 | + |
| 9 | + $currentUser = erLhcoreClassUser::instance(); |
| 10 | + $userData = $currentUser->getUserData(true); |
11 | 11 |
|
12 | | -// We have to check is operator really inactive or it's just a tab trying to set inactive mode |
13 | | -if ($Params['user_parameters']['status'] == 'true') { |
14 | | - $activityTimeout = erLhcoreClassModelUserSetting::getSetting('trackactivitytimeout',-1); |
| 12 | + // Lock the user record to prevent race conditions when updating inactive_mode |
| 13 | + $userData->syncAndLock(); |
15 | 14 |
|
16 | | - // If there is no individual setting user global one |
17 | | - if ($activityTimeout == -1) { |
18 | | - $activityTimeout = (int)erLhcoreClassModelChatConfig::fetchCache('activity_timeout')->current_value*60; |
| 15 | + if (!isset($_SERVER['HTTP_X_CSRFTOKEN']) || !$currentUser->validateCSFRToken($_SERVER['HTTP_X_CSRFTOKEN'])) { |
| 16 | + throw new Exception('Invalid CSFR Token'); |
19 | 17 | } |
20 | 18 |
|
21 | | - // Operator was still active in another tab, do nothing |
22 | | - if ($activityTimeout > (time() - $userData->lastd_activity)) { |
23 | | - echo json_encode(array('error' => false, 'active' => true)); |
24 | | - exit; |
| 19 | + // We have to check is operator really inactive or it's just a tab trying to set inactive mode |
| 20 | + if ($Params['user_parameters']['status'] == 'true') { |
| 21 | + $activityTimeout = erLhcoreClassModelUserSetting::getSetting('trackactivitytimeout',-1); |
| 22 | + |
| 23 | + // If there is no individual setting user global one |
| 24 | + if ($activityTimeout == -1) { |
| 25 | + $activityTimeout = (int)erLhcoreClassModelChatConfig::fetchCache('activity_timeout')->current_value*60; |
| 26 | + } |
| 27 | + |
| 28 | + // Operator was still active in another tab, do nothing |
| 29 | + if ($activityTimeout > (time() - $userData->lastd_activity)) { |
| 30 | + $db->commit(); |
| 31 | + echo json_encode(array('error' => false, 'active' => true)); |
| 32 | + exit; |
| 33 | + } |
25 | 34 | } |
26 | | -} |
27 | 35 |
|
28 | | -$originalInactiveMode = $userData->inactive_mode; |
| 36 | + $originalInactiveMode = $userData->inactive_mode; |
29 | 37 |
|
30 | | -if ($Params['user_parameters']['status'] == 'true') { |
31 | | - $userData->inactive_mode = 1; |
32 | | -} else { |
33 | | - $userData->inactive_mode = 0; |
34 | | -} |
| 38 | + if ($Params['user_parameters']['status'] == 'true') { |
| 39 | + $userData->inactive_mode = 1; |
| 40 | + } else { |
| 41 | + $userData->inactive_mode = 0; |
| 42 | + } |
35 | 43 |
|
36 | | -erLhcoreClassUser::getSession()->update($userData); |
| 44 | + erLhcoreClassUser::getSession()->update($userData); |
37 | 45 |
|
38 | | -// Construct temporary object to change inactive modes |
39 | | -$userDataTemp = new stdClass(); |
40 | | -$userDataTemp->id = $userData->id; |
| 46 | + // Construct temporary object to change inactive modes |
| 47 | + $userDataTemp = new stdClass(); |
| 48 | + $userDataTemp->id = $userData->id; |
41 | 49 |
|
42 | | -if ($userData->hide_online == 0) { // change status only if he's not offline manually |
43 | | - $userDataTemp->hide_online = $userData->inactive_mode; |
44 | | - $userDataTemp->always_on = $userData->always_on; |
| 50 | + if ($userData->hide_online == 0) { // change status only if he's not offline manually |
| 51 | + $userDataTemp->hide_online = $userData->inactive_mode; |
| 52 | + $userDataTemp->always_on = $userData->always_on; |
45 | 53 |
|
46 | | - erLhcoreClassUserDep::setHideOnlineStatus($userDataTemp); |
| 54 | + erLhcoreClassUserDep::setHideOnlineStatus($userDataTemp); |
47 | 55 |
|
48 | | - if ($originalInactiveMode != $userData->inactive_mode){ |
49 | | - $currentUser->updateLastVisit(time(), $userDataTemp->hide_online == 1 ? 2 : 1); // Went offline OR went online |
| 56 | + if ($originalInactiveMode != $userData->inactive_mode){ |
| 57 | + $currentUser->updateLastVisit(time(), $userDataTemp->hide_online == 1 ? 2 : 1); // Went offline OR went online |
| 58 | + } |
50 | 59 | } |
51 | | -} |
52 | 60 |
|
53 | | -erLhcoreClassChatEventDispatcher::getInstance()->dispatch('chat.operator_inactivemode_changed',array('user' => & $userData, 'reason' => 'user_action')); |
| 61 | + erLhcoreClassChatEventDispatcher::getInstance()->dispatch('chat.operator_inactivemode_changed',array('user' => & $userData, 'reason' => 'user_action')); |
54 | 62 |
|
| 63 | + echo json_encode(array('error' => false, 'active' => false)); |
55 | 64 |
|
56 | | -echo json_encode(array('error' => false, 'active' => false)); |
| 65 | + $db->commit(); |
| 66 | + |
| 67 | +} catch (Exception $e) { |
| 68 | + echo json_encode(array('error' => true, 'msg' => $e->getMessage())); |
| 69 | + $db->rollback(); |
| 70 | +} |
57 | 71 |
|
58 | 72 | exit; |
59 | 73 |
|
|
0 commit comments