PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.0
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / app / Services / Tickets / AgentTicketAccess.php

AgentTicketAccess.php in Fluent Support – Helpdesk & Customer Support Ticket System 2.4.0, at app/Services/Tickets/AgentTicketAccess.php

167 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Services\Tickets;
4
5 use FluentSupport\App\Modules\PermissionManager;
6 use FluentSupport\App\Services\Helper;
7
8 class AgentTicketAccess
9 {
10 // Keyed by user id so wp_set_current_user() switches land on their own entry.
11 private static $restrictedByUser = [];
12
13 public function currentAgentCanAccess($ticket)
14 {
15 return $this->canAccess(Helper::getAgentByUserId(), $ticket);
16 }
17
18 public function canAccess($agent, $ticket, $restrictions = null)
19 {
20 if (!$agent || empty($agent->user_id) || !$ticket || empty($ticket->id)) {
21 return false;
22 }
23
24 if ($this->isMailboxRestricted($agent, $ticket, $restrictions)) {
25 return false;
26 }
27
28 $visibility = PermissionManager::getAgentTicketVisibility($agent->user_id);
29
30 if ($visibility === PermissionManager::VISIBILITY_ALL) {
31 return true;
32 }
33
34 if ((int) $ticket->agent_id === (int) $agent->id) {
35 return true;
36 }
37
38 return !$ticket->agent_id && $visibility === PermissionManager::VISIBILITY_ASSIGNED_AND_UNASSIGNED;
39 }
40
41 public function applyAccessScope($query, $agent = null, $restrictions = null)
42 {
43 $agent = $agent ?: Helper::getAgentByUserId();
44
45 if (!$agent || empty($agent->user_id)) {
46 $query->where('id', 0);
47 return $query;
48 }
49
50 $this->applyVisibilityScope($query, $agent);
51 $this->applyMailboxRestrictionScope($query, $agent, $restrictions);
52
53 return $query;
54 }
55
56 public function applyVisibilityScope($query, $agent = null)
57 {
58 $agent = $agent ?: Helper::getAgentByUserId();
59
60 if (!$agent || empty($agent->user_id)) {
61 $query->where('id', 0);
62 return $query;
63 }
64
65 $visibility = PermissionManager::getAgentTicketVisibility($agent->user_id);
66
67 if ($visibility === PermissionManager::VISIBILITY_ALL) {
68 return $query;
69 }
70
71 if ($visibility === PermissionManager::VISIBILITY_ASSIGNED_ONLY) {
72 $query->where('agent_id', $agent->id);
73 return $query;
74 }
75
76 $query->where(function ($q) use ($agent) {
77 $q->where('agent_id', $agent->id);
78 $q->orWhereNull('agent_id');
79 });
80
81 return $query;
82 }
83
84 public function applyMailboxRestrictionScope($query, $agent = null, $restrictions = null)
85 {
86 $restrictedBoxes = $this->getRestrictedMailboxIds($agent, $restrictions);
87
88 if ($restrictedBoxes) {
89 $this->applyRestrictedMailboxFilter($query, $restrictedBoxes);
90 }
91
92 return $query;
93 }
94
95 // NOT IN is NULL, not TRUE, for a NULL mailbox — hence the explicit OR.
96 protected function applyRestrictedMailboxFilter($query, $restrictedBoxes)
97 {
98 return $query->where(function ($q) use ($restrictedBoxes) {
99 $q->whereNotIn('mailbox_id', $restrictedBoxes);
100 $q->orWhereNull('mailbox_id');
101 });
102 }
103
104 // Costs an agent + meta read, so the current-user answer is memoised for the
105 // request; a request constructs many instances and they all share it.
106 public function getRestrictedMailboxIds($agent = null, $restrictions = null)
107 {
108 if ($agent !== null || $restrictions !== null) {
109 return $this->resolveRestrictedMailboxIds($agent, $restrictions);
110 }
111
112 $userId = (int) get_current_user_id();
113
114 if (!array_key_exists($userId, self::$restrictedByUser)) {
115 self::$restrictedByUser[$userId] = $this->resolveRestrictedMailboxIds(null, null);
116 }
117
118 return self::$restrictedByUser[$userId];
119 }
120
121 // Call after writing agent_restrictions so the same request sees the new value.
122 public static function resetCache()
123 {
124 self::$restrictedByUser = [];
125 }
126
127 private function resolveRestrictedMailboxIds($agent, $restrictions)
128 {
129 $agent = $agent ?: Helper::getAgentByUserId();
130
131 if (!$agent) {
132 return [];
133 }
134
135 if ($restrictions === null) {
136 $restrictions = $agent->getMeta('agent_restrictions', []);
137 }
138
139 if (!empty($restrictions['businessBoxRestrictions']) && !empty($restrictions['restrictedBusinessBoxes'])) {
140 return array_values(array_unique(array_map('intval', $restrictions['restrictedBusinessBoxes'])));
141 }
142
143 return [];
144 }
145
146 // Same boundary, for rows that reach their mailbox through a `ticket` relation.
147 public function applyMailboxRestrictionScopeViaTicket($query)
148 {
149 $restrictedBoxes = $this->getRestrictedMailboxIds();
150
151 if (!$restrictedBoxes) {
152 return $query;
153 }
154
155 return $query->whereHas('ticket', function ($q) use ($restrictedBoxes) {
156 $this->applyRestrictedMailboxFilter($q, $restrictedBoxes);
157 });
158 }
159
160 protected function isMailboxRestricted($agent, $ticket, $restrictions = null)
161 {
162 $restrictedBoxes = $this->getRestrictedMailboxIds($agent, $restrictions);
163
164 return !empty($ticket->mailbox_id) && in_array((int) $ticket->mailbox_id, $restrictedBoxes, true);
165 }
166 }
167