nas commited on 2010-12-04 01:57:02
Showing 100 changed files, with 13861 additions and 0 deletions.
... | ... |
@@ -0,0 +1,317 @@ |
1 |
+/* Half rounded headers */ |
|
2 |
+div.grid_header |
|
3 |
+{ |
|
4 |
+ height: 28px; |
|
5 |
+ margin-bottom: -1px; |
|
6 |
+} |
|
7 |
+/* You no left float, Core! */ |
|
8 |
+h3.grid_header img |
|
9 |
+{ |
|
10 |
+ float: none; |
|
11 |
+} |
|
12 |
+ |
|
13 |
+/* This is done to position icons perfectly in the ticket header (i.e the navigation)*/ |
|
14 |
+h3.ticketheader img |
|
15 |
+{ |
|
16 |
+ top: 2px; |
|
17 |
+ position: relative; |
|
18 |
+ margin-right: 2px; |
|
19 |
+} |
|
20 |
+ |
|
21 |
+.shd_hide_replybox |
|
22 |
+{ |
|
23 |
+ position: relative; |
|
24 |
+ top: 8px; |
|
25 |
+} |
|
26 |
+ |
|
27 |
+/* The Respond, Edit, Delete etc links */ |
|
28 |
+.shd_ticketlinks a |
|
29 |
+{ |
|
30 |
+ margin-right: 10px; |
|
31 |
+} |
|
32 |
+.shd_ticketlinks a#last |
|
33 |
+{ |
|
34 |
+ margin-right: 0px; |
|
35 |
+} |
|
36 |
+ |
|
37 |
+/* Ticket details (Left-floated box) */ |
|
38 |
+.shd_ticketdetails |
|
39 |
+{ |
|
40 |
+ float: left; |
|
41 |
+ width: 215px; |
|
42 |
+ min-height: 280px; |
|
43 |
+ overflow: auto; |
|
44 |
+ margin-right: 20px; |
|
45 |
+} |
|
46 |
+.shd_ticketdetails ul |
|
47 |
+{ |
|
48 |
+ list-style-type: none; |
|
49 |
+ padding-left: 0; |
|
50 |
+ margin: 0; |
|
51 |
+} |
|
52 |
+.shd_smallicon |
|
53 |
+{ |
|
54 |
+ width: 13px; |
|
55 |
+ height: 13px; |
|
56 |
+ margin-right: 4px; |
|
57 |
+} |
|
58 |
+.shd_icon_minihead |
|
59 |
+{ |
|
60 |
+ position: relative; |
|
61 |
+ top: 3px; |
|
62 |
+} |
|
63 |
+.shd_tinyicon |
|
64 |
+{ |
|
65 |
+ width: 9px; |
|
66 |
+ height: 9px; |
|
67 |
+} |
|
68 |
+ |
|
69 |
+.shd_ticket_avatar |
|
70 |
+{ |
|
71 |
+ margin: 1em auto; |
|
72 |
+ text-align: center; |
|
73 |
+} |
|
74 |
+ |
|
75 |
+/* The ticket container */ |
|
76 |
+.shd_ticket |
|
77 |
+{ |
|
78 |
+ min-height: 340px; |
|
79 |
+} |
|
80 |
+.shd_ticket_description |
|
81 |
+{ |
|
82 |
+ padding-top: 9px; |
|
83 |
+ padding-bottom: 45px; |
|
84 |
+ margin-left: 260px; |
|
85 |
+ min-height: 200px; |
|
86 |
+} |
|
87 |
+ |
|
88 |
+#shd_ticket_text |
|
89 |
+{ |
|
90 |
+ min-height: 100px; |
|
91 |
+} |
|
92 |
+ |
|
93 |
+/* The big reply button */ |
|
94 |
+.shd_replybutton |
|
95 |
+{ |
|
96 |
+ margin-top: 10px; |
|
97 |
+ height: 15px; |
|
98 |
+ background: url(../images/simpledesk/respond.png) no-repeat left; |
|
99 |
+ background-position: 10px; |
|
100 |
+ padding: 10px; |
|
101 |
+ padding-left: 40px; |
|
102 |
+ padding-top: 8px; |
|
103 |
+ font-weight: bold; |
|
104 |
+ font-size: 100%; |
|
105 |
+ margin-bottom: 10px; |
|
106 |
+} |
|
107 |
+/* The big quote button */ |
|
108 |
+.shd_quotebutton |
|
109 |
+{ |
|
110 |
+ margin-top: 10px; |
|
111 |
+ height: 15px; |
|
112 |
+ background: url(../images/simpledesk/quote.png) no-repeat left; |
|
113 |
+ background-position: 10px; |
|
114 |
+ padding: 10px; |
|
115 |
+ padding-left: 40px; |
|
116 |
+ padding-top: 8px; |
|
117 |
+ font-weight: bold; |
|
118 |
+ font-size: 100%; |
|
119 |
+ margin-right: 10px; |
|
120 |
+} |
|
121 |
+/* Go advanced! */ |
|
122 |
+.shd_advancedbutton |
|
123 |
+{ |
|
124 |
+ margin-top: 10px; |
|
125 |
+ height: 15px; |
|
126 |
+ background: url(../images/simpledesk/advanced.png) no-repeat left; |
|
127 |
+ background-position: 10px; |
|
128 |
+ padding: 10px; |
|
129 |
+ padding-left: 40px; |
|
130 |
+ padding-top: 8px; |
|
131 |
+ font-weight: bold; |
|
132 |
+ font-size: 100%; |
|
133 |
+ margin-right: 10px; |
|
134 |
+} |
|
135 |
+/* Replies */ |
|
136 |
+.shd_reply |
|
137 |
+{ |
|
138 |
+ padding-bottom: 32px; |
|
139 |
+ padding-top: 12px; |
|
140 |
+} |
|
141 |
+.shd_posterinfo |
|
142 |
+{ |
|
143 |
+ width: 14em; |
|
144 |
+ text-align: center; |
|
145 |
+ margin-left: 3px; |
|
146 |
+ overflow: hidden; |
|
147 |
+} |
|
148 |
+.shd_postername |
|
149 |
+{ |
|
150 |
+ font-size: 120%; |
|
151 |
+} |
|
152 |
+.shd_groupmargin |
|
153 |
+{ |
|
154 |
+ margin-bottom: 10px; |
|
155 |
+} |
|
156 |
+.shd_posteravatar |
|
157 |
+{ |
|
158 |
+ padding: 0px; |
|
159 |
+ max-width: 50px; |
|
160 |
+ max-height: 50px; |
|
161 |
+} |
|
162 |
+.shd_replyarea |
|
163 |
+{ |
|
164 |
+ padding-left: 14em; |
|
165 |
+ margin-left: 10px; |
|
166 |
+} |
|
167 |
+ |
|
168 |
+/* Attachments */ |
|
169 |
+.shd_replyattachments ul, .shd_replyattachments li |
|
170 |
+{ |
|
171 |
+ display: inline; |
|
172 |
+ list-style-type: none; |
|
173 |
+} |
|
174 |
+ |
|
175 |
+.shd_attachment |
|
176 |
+{ |
|
177 |
+ padding-bottom: 5px; |
|
178 |
+ font-size: 85%; |
|
179 |
+} |
|
180 |
+.shd_attachmentpreview |
|
181 |
+{ |
|
182 |
+ text-align: center; |
|
183 |
+} |
|
184 |
+.shd_attachmentpreview img |
|
185 |
+{ |
|
186 |
+ max-width: 75px; |
|
187 |
+ margin: 3px; |
|
188 |
+ margin-top: 6px; |
|
189 |
+} |
|
190 |
+.shd_attachmentpreview .description |
|
191 |
+{ |
|
192 |
+ padding: 0; |
|
193 |
+} |
|
194 |
+.shd_removeattachment |
|
195 |
+{ |
|
196 |
+ margin-left: -8px; |
|
197 |
+ margin-right: 3px; |
|
198 |
+} |
|
199 |
+.shd_attachmentbox |
|
200 |
+{ |
|
201 |
+ padding: 10px; |
|
202 |
+} |
|
203 |
+.shd_attachmentcolumn |
|
204 |
+{ |
|
205 |
+ margin-right: 20px; |
|
206 |
+} |
|
207 |
+ |
|
208 |
+/* Ticket listing */ |
|
209 |
+.shd_ticketlist |
|
210 |
+{ |
|
211 |
+ width: 100%; |
|
212 |
+ border: solid #BBBBBB; |
|
213 |
+ border-width: 1px 1px 0; |
|
214 |
+} |
|
215 |
+.shd_ticketlist td |
|
216 |
+{ |
|
217 |
+ padding: 5px; |
|
218 |
+ border-bottom: 1px solid #AFAFAF; |
|
219 |
+} |
|
220 |
+.shd_noticket |
|
221 |
+{ |
|
222 |
+ text-align: center; |
|
223 |
+} |
|
224 |
+.shd_staffresources ul |
|
225 |
+{ |
|
226 |
+ list-style-type: none; |
|
227 |
+ padding: 0; |
|
228 |
+ margin: 0; |
|
229 |
+} |
|
230 |
+.shd_staffresources li |
|
231 |
+{ |
|
232 |
+ margin-bottom: 3px; |
|
233 |
+} |
|
234 |
+ |
|
235 |
+.shd_reply_attachments |
|
236 |
+{ |
|
237 |
+ width: 68%; |
|
238 |
+ margin-bottom: 0; |
|
239 |
+ float: left; |
|
240 |
+ margin-top: 5px; |
|
241 |
+} |
|
242 |
+ |
|
243 |
+.shd_modified |
|
244 |
+{ |
|
245 |
+ margin-top: 20px; |
|
246 |
+} |
|
247 |
+ |
|
248 |
+.postreply |
|
249 |
+{ |
|
250 |
+ margin: 0; |
|
251 |
+} |
|
252 |
+ |
|
253 |
+.postmodify |
|
254 |
+{ |
|
255 |
+ margin: 0; |
|
256 |
+} |
|
257 |
+ |
|
258 |
+.shd_main_hd |
|
259 |
+{ |
|
260 |
+ margin-top: -3px; |
|
261 |
+} |
|
262 |
+ |
|
263 |
+.shd_nowrap |
|
264 |
+{ |
|
265 |
+ white-space: nowrap; |
|
266 |
+} |
|
267 |
+ |
|
268 |
+.pm_message |
|
269 |
+{ |
|
270 |
+ margin-top: 1ex; |
|
271 |
+} |
|
272 |
+ |
|
273 |
+.shd_reply .avatar |
|
274 |
+{ |
|
275 |
+ margin-bottom: 10px; |
|
276 |
+} |
|
277 |
+ |
|
278 |
+#quickReplyExpand |
|
279 |
+{ |
|
280 |
+ margin-top: 8px; |
|
281 |
+} |
|
282 |
+ |
|
283 |
+/* The left column in the ticket display */ |
|
284 |
+.shd_ticket_leftcolumn |
|
285 |
+{ |
|
286 |
+ width: 25%; |
|
287 |
+} |
|
288 |
+/* The right column in the ticket display */ |
|
289 |
+.shd_ticket_rightcolumn |
|
290 |
+{ |
|
291 |
+ width: 75%; |
|
292 |
+} |
|
293 |
+ |
|
294 |
+/* The 'Empty log' link in the action log */ |
|
295 |
+.shd_empty_log |
|
296 |
+{ |
|
297 |
+ font-size: 80%; |
|
298 |
+} |
|
299 |
+.shd_empty_log img |
|
300 |
+{ |
|
301 |
+ position: relative; |
|
302 |
+ top: 3px; |
|
303 |
+ margin-right: 2px; |
|
304 |
+} |
|
305 |
+/* Override editor margins */ |
|
306 |
+#quickReplyOptions form textarea |
|
307 |
+{ |
|
308 |
+ margin-bottom: 0!important; |
|
309 |
+} |
|
310 |
+ |
|
311 |
+.shd_gototicket |
|
312 |
+{ |
|
313 |
+ display: block; |
|
314 |
+ float: right; |
|
315 |
+ margin-left: 1em; |
|
316 |
+ white-space: nowrap; |
|
317 |
+} |
|
0 | 318 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,89 @@ |
1 |
+#sd_live_news |
|
2 |
+{ |
|
3 |
+ width: 64%; |
|
4 |
+ font-size: 0.85em; |
|
5 |
+} |
|
6 |
+#sd_live_news div.content |
|
7 |
+{ |
|
8 |
+ padding: 0; |
|
9 |
+} |
|
10 |
+#sd_live_news div.content dl |
|
11 |
+{ |
|
12 |
+ padding: 0.5em 0 0 0.5em; |
|
13 |
+} |
|
14 |
+ |
|
15 |
+#sd_supportVersionsTable |
|
16 |
+{ |
|
17 |
+ width: 34%; |
|
18 |
+} |
|
19 |
+#sd_version_details |
|
20 |
+{ |
|
21 |
+ overflow: auto; |
|
22 |
+ height: 16.4em; |
|
23 |
+} |
|
24 |
+#sdAnnouncements |
|
25 |
+{ |
|
26 |
+ height: 21.6em; |
|
27 |
+ overflow: auto; |
|
28 |
+} |
|
29 |
+#sdAnnouncements dt |
|
30 |
+{ |
|
31 |
+ border-bottom: 1px dashed #000; |
|
32 |
+} |
|
33 |
+#sdAnnouncements dd |
|
34 |
+{ |
|
35 |
+ padding: 0; |
|
36 |
+ margin: 0 0 1em 1.5em; |
|
37 |
+} |
|
38 |
+#sd_update_section |
|
39 |
+{ |
|
40 |
+ margin-top: 10px; |
|
41 |
+ margin-bottom: 10px; |
|
42 |
+} |
|
43 |
+#sd_credits |
|
44 |
+{ |
|
45 |
+} |
|
46 |
+.sd_group_name |
|
47 |
+{ |
|
48 |
+} |
|
49 |
+.sd_group_name hr |
|
50 |
+{ |
|
51 |
+ margin-top: 2px; |
|
52 |
+} |
|
53 |
+.shd_help |
|
54 |
+{ |
|
55 |
+ float: right; |
|
56 |
+ margin-top: 8px; |
|
57 |
+} |
|
58 |
+.shd_actionloginfo |
|
59 |
+{ |
|
60 |
+ margin-bottom: 0; |
|
61 |
+ border-bottom: 0; |
|
62 |
+} |
|
63 |
+.shd_admin_leftcolumn |
|
64 |
+{ |
|
65 |
+ width: 74%; |
|
66 |
+ margin-right: 10px; |
|
67 |
+} |
|
68 |
+.shd_admin_rightcolumn |
|
69 |
+{ |
|
70 |
+ width: 24%; |
|
71 |
+} |
|
72 |
+.shd_credits_break |
|
73 |
+{ |
|
74 |
+ margin-bottom: 0; |
|
75 |
+ |
|
76 |
+} |
|
77 |
+.shd_bbc_list |
|
78 |
+{ |
|
79 |
+ width: 33%; |
|
80 |
+} |
|
81 |
+.shd_info_box |
|
82 |
+{ |
|
83 |
+ margin-bottom: 0; |
|
84 |
+} |
|
85 |
+h3.sd_no_margin |
|
86 |
+{ |
|
87 |
+ margin-bottom: 0px; |
|
88 |
+ padding-bottom: 3px; |
|
89 |
+} |
|
0 | 90 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,31 @@ |
1 |
+/* IE6, IE6, how do I hate thee, let me count the ways. */ |
|
2 |
+ |
|
3 |
+/* IE6 needs a height fix here */ |
|
4 |
+.shd_ticketdetails |
|
5 |
+{ |
|
6 |
+ min-height: 280px; |
|
7 |
+ height: auto !important; |
|
8 |
+ height: 280px; |
|
9 |
+} |
|
10 |
+.shd_ticket |
|
11 |
+{ |
|
12 |
+ min-height: 340px; |
|
13 |
+ height: auto !important; |
|
14 |
+ height: 340px; |
|
15 |
+} |
|
16 |
+ |
|
17 |
+/* For whatever odd reason this have to 0.8% or so smaller in IE6 to look good. */ |
|
18 |
+h3.grid_header |
|
19 |
+{ |
|
20 |
+ width: 99.2%; |
|
21 |
+} |
|
22 |
+ |
|
23 |
+.shd_reply .shd_ticketlinks |
|
24 |
+{ |
|
25 |
+ margin-top: -15px; |
|
26 |
+} |
|
27 |
+ |
|
28 |
+h3.ticketheader .shd_ticketlinks |
|
29 |
+{ |
|
30 |
+ margin-top: 3px; |
|
31 |
+} |
|
0 | 32 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,324 @@ |
1 |
+<?xml version="1.0"?> |
|
2 |
+<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification"> |
|
3 |
+<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/"> |
|
4 |
+ <id>SimpleDeskTeam:SimpleDesk</id> |
|
5 |
+ <version>1.0 Felidae</version> |
|
6 |
+ |
|
7 |
+ <file name="$sourcedir/Display.php"> |
|
8 |
+ <operation><!-- add the option to the download system to ensure it handles SD attachments --> |
|
9 |
+ <search position="after"><![CDATA[ |
|
10 |
+ // This is just a regular attachment... |
|
11 |
+ else]]></search> |
|
12 |
+ <add><![CDATA[ |
|
13 |
+ elseif (!empty($_REQUEST['ticket'])) |
|
14 |
+ { |
|
15 |
+ // Make sure the attachment is on this ticket, note right now we're forcing it to be "approved" |
|
16 |
+ $request = shd_db_query('', ' |
|
17 |
+ SELECT a.id_folder, a.filename, a.file_hash, a.fileext, a.id_attach, a.attachment_type, a.mime_type, 1 AS approved |
|
18 |
+ FROM {db_prefix}attachments AS a |
|
19 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
20 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hda.id_msg = hdtr.id_msg) |
|
21 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
22 |
+ WHERE {query_see_ticket} |
|
23 |
+ AND a.id_attach = {int:attach} |
|
24 |
+ AND hdt.id_ticket = {int:ticket} |
|
25 |
+ LIMIT 1', |
|
26 |
+ array( |
|
27 |
+ 'attach' => $_REQUEST['attach'], |
|
28 |
+ 'ticket' => (int) $_REQUEST['ticket'], |
|
29 |
+ ) |
|
30 |
+ ); |
|
31 |
+ }]]></add> |
|
32 |
+ </operation> |
|
33 |
+ </file> |
|
34 |
+ |
|
35 |
+ <file name="$sourcedir/ManageAttachments.php"> |
|
36 |
+ <operation><!-- extend removeAttachments to cover SD's table items since it's doing the rest of the work anyway --> |
|
37 |
+ <search position="after"><![CDATA[ if ($return_affected_messages)]]></search> |
|
38 |
+ <add><![CDATA[ // And now lastly to remove SimpleDesk attachments |
|
39 |
+ if (!empty($attach)) |
|
40 |
+ $smcFunc['db_query']('', ' |
|
41 |
+ DELETE FROM {db_prefix}helpdesk_attachments |
|
42 |
+ WHERE id_attach IN ({array_int:attachment_list})', |
|
43 |
+ array( |
|
44 |
+ 'attachment_list' => $attach, |
|
45 |
+ ) |
|
46 |
+ ); |
|
47 |
+ |
|
48 |
+]]></add> |
|
49 |
+ </operation> |
|
50 |
+ <operation><!-- prevent attachment maintenance killing our attachments! unconventionally, this is an atomic query for good reason, it MUST be put in place fully --> |
|
51 |
+ <search position="replace"><![CDATA[SELECT a.id_attach, a.id_folder, a.filename, a.file_hash |
|
52 |
+ FROM {db_prefix}attachments AS a |
|
53 |
+ LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) |
|
54 |
+ WHERE a.id_attach BETWEEN {int:substep} AND {int:substep} + 499 |
|
55 |
+ AND a.id_member = {int:no_member} |
|
56 |
+ AND a.id_msg != {int:no_msg} |
|
57 |
+ AND m.id_msg IS NULL]]></search> |
|
58 |
+ <add><![CDATA[SELECT a.id_attach, a.id_folder, a.filename, a.file_hash |
|
59 |
+ FROM {db_prefix}attachments AS a |
|
60 |
+ LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) |
|
61 |
+ LEFT JOIN {db_prefix}helpdesk_attachments AS hda ON (hda.id_attach = a.id_attach) |
|
62 |
+ LEFT JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdtr.id_msg = hda.id_msg) |
|
63 |
+ WHERE a.id_attach BETWEEN {int:substep} AND {int:substep} + 499 |
|
64 |
+ AND a.id_member = {int:no_member} |
|
65 |
+ AND a.id_msg != {int:no_msg} |
|
66 |
+ AND m.id_msg IS NULL |
|
67 |
+ AND hdtr.id_msg IS NULL]]></add> |
|
68 |
+ </operation> |
|
69 |
+ <operation><!-- override the master attachments code if it's HD only stuff requested --> |
|
70 |
+ <search position="before"><![CDATA[$context['browse_type'] = isset($_REQUEST['avatars']) ? 'avatars' : (isset($_REQUEST['thumbs']) ? 'thumbs' : 'attachments');]]></search> |
|
71 |
+ <add><![CDATA[ |
|
72 |
+ |
|
73 |
+ if (!empty($modSettings['helpdesk_active']) && (isset($_REQUEST['shd_attach']) || isset($_REQUEST['shd_thumb']))) |
|
74 |
+ { |
|
75 |
+ // We're actually wanting helpdesk only stuff, so do it and bail |
|
76 |
+ return shd_admin_browse_attachments(); |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+]]></add> |
|
80 |
+ </operation> |
|
81 |
+ <operation><!-- add the code to deal with deleting our attachments from ACP --> |
|
82 |
+ <search position="after"><![CDATA[if ($_REQUEST['type'] == 'avatars' && !empty($attachments))]]></search> |
|
83 |
+ <add><![CDATA[if (in_array($_REQUEST['type'], array('shd_attach', 'shd_thumb')) && !empty($attachments)) |
|
84 |
+ $messages = removeAttachments(array('id_attach' => $attachments), '', true); |
|
85 |
+ else]]></add> |
|
86 |
+ </operation> |
|
87 |
+ <operation><!-- add our handling for attachments --> |
|
88 |
+ <search position="end" /> |
|
89 |
+ <add><![CDATA[ |
|
90 |
+ |
|
91 |
+function shd_admin_browse_attachments() |
|
92 |
+{ |
|
93 |
+ global $context, $txt, $scripturl, $options, $modSettings; |
|
94 |
+ global $smcFunc, $sourcedir; |
|
95 |
+ |
|
96 |
+ $context['browse_type'] = isset($_REQUEST['shd_attach']) ? 'shd_attach' : 'shd_thumb'; |
|
97 |
+ |
|
98 |
+ // Set the options for the list component. |
|
99 |
+ $listOptions = array( |
|
100 |
+ 'id' => 'file_list', |
|
101 |
+ 'title' => $txt['attachment_manager_' . $context['browse_type']], |
|
102 |
+ 'items_per_page' => $modSettings['defaultMaxMessages'], |
|
103 |
+ 'base_href' => $scripturl . '?action=admin;area=manageattachments;sa=browse;' . $context['browse_type'], |
|
104 |
+ 'default_sort_col' => 'name', |
|
105 |
+ 'no_items_label' => $txt['attachment_manager_' . $context['browse_type'] . '_no_entries'], |
|
106 |
+ 'get_items' => array( |
|
107 |
+ 'function' => 'shd_list_get_files', |
|
108 |
+ 'params' => array( |
|
109 |
+ $context['browse_type'], |
|
110 |
+ ), |
|
111 |
+ ), |
|
112 |
+ 'get_count' => array( |
|
113 |
+ 'function' => 'shd_list_get_num_files', |
|
114 |
+ 'params' => array( |
|
115 |
+ $context['browse_type'], |
|
116 |
+ ), |
|
117 |
+ ), |
|
118 |
+ 'columns' => array( |
|
119 |
+ 'name' => array( |
|
120 |
+ 'header' => array( |
|
121 |
+ 'value' => $txt['attachment_name'], |
|
122 |
+ ), |
|
123 |
+ 'data' => array( |
|
124 |
+ 'function' => create_function('$rowData', ' |
|
125 |
+ global $modSettings, $context, $scripturl; |
|
126 |
+ |
|
127 |
+ $link = \'<a href="\'; |
|
128 |
+ |
|
129 |
+ $link .= sprintf(\'%1$s?action=dlattach;ticket=%2$d.0;id=%3$d\', $scripturl, $rowData[\'id_ticket\'], $rowData[\'id_attach\']); |
|
130 |
+ |
|
131 |
+ $link .= \'"\'; |
|
132 |
+ |
|
133 |
+ // Show a popup on click if it\'s a picture and we know its dimensions. |
|
134 |
+ if (!empty($rowData[\'width\']) && !empty($rowData[\'height\'])) |
|
135 |
+ $link .= sprintf(\' onclick="return reqWin(this.href + \\\';image\\\', %1$d, %2$d, true);"\', $rowData[\'width\'] + 20, $rowData[\'height\'] + 20); |
|
136 |
+ |
|
137 |
+ $link .= sprintf(\'>%1$s</a>\', preg_replace(\'~&#(\\\\d{1,7}|x[0-9a-fA-F]{1,6});~\', \'&#\\\\1;\', htmlspecialchars($rowData[\'filename\']))); |
|
138 |
+ |
|
139 |
+ // Show the dimensions. |
|
140 |
+ if (!empty($rowData[\'width\']) && !empty($rowData[\'height\'])) |
|
141 |
+ $link .= sprintf(\' <span class="smalltext">%1$dx%2$d</span>\', $rowData[\'width\'], $rowData[\'height\']); |
|
142 |
+ |
|
143 |
+ return $link; |
|
144 |
+ '), |
|
145 |
+ ), |
|
146 |
+ 'sort' => array( |
|
147 |
+ 'default' => 'a.filename', |
|
148 |
+ 'reverse' => 'a.filename DESC', |
|
149 |
+ ), |
|
150 |
+ ), |
|
151 |
+ 'filesize' => array( |
|
152 |
+ 'header' => array( |
|
153 |
+ 'value' => $txt['attachment_file_size'], |
|
154 |
+ ), |
|
155 |
+ 'data' => array( |
|
156 |
+ 'function' => create_function('$rowData',' |
|
157 |
+ global $txt; |
|
158 |
+ |
|
159 |
+ return sprintf(\'%1$s%2$s\', round($rowData[\'size\'] / 1024, 2), $txt[\'kilobyte\']); |
|
160 |
+ '), |
|
161 |
+ 'class' => 'windowbg', |
|
162 |
+ ), |
|
163 |
+ 'sort' => array( |
|
164 |
+ 'default' => 'a.size', |
|
165 |
+ 'reverse' => 'a.size DESC', |
|
166 |
+ ), |
|
167 |
+ ), |
|
168 |
+ 'member' => array( |
|
169 |
+ 'header' => array( |
|
170 |
+ 'value' => $txt['posted_by'], |
|
171 |
+ ), |
|
172 |
+ 'data' => array( |
|
173 |
+ 'function' => create_function('$rowData', ' |
|
174 |
+ global $scripturl; |
|
175 |
+ |
|
176 |
+ return htmlspecialchars($rowData[\'poster_name\']); |
|
177 |
+ '), |
|
178 |
+ ), |
|
179 |
+ 'sort' => array( |
|
180 |
+ 'default' => 'mem.real_name', |
|
181 |
+ 'reverse' => 'mem.real_name DESC', |
|
182 |
+ ), |
|
183 |
+ ), |
|
184 |
+ 'date' => array( |
|
185 |
+ 'header' => array( |
|
186 |
+ 'value' => $txt['date'], |
|
187 |
+ ), |
|
188 |
+ 'data' => array( |
|
189 |
+ 'function' => create_function('$rowData', ' |
|
190 |
+ global $txt, $context, $scripturl; |
|
191 |
+ |
|
192 |
+ return empty($rowData[\'poster_time\']) ? $txt[\'never\'] : timeformat($rowData[\'poster_time\']); |
|
193 |
+ '), |
|
194 |
+ 'class' => 'windowbg', |
|
195 |
+ ), |
|
196 |
+ 'sort' => array( |
|
197 |
+ 'default' => 'hdtr.id_msg', |
|
198 |
+ 'reverse' => 'hdtr.id_msg DESC', |
|
199 |
+ ), |
|
200 |
+ ), |
|
201 |
+ 'downloads' => array( |
|
202 |
+ 'header' => array( |
|
203 |
+ 'value' => $txt['downloads'], |
|
204 |
+ ), |
|
205 |
+ 'data' => array( |
|
206 |
+ 'function' => create_function('$rowData',' |
|
207 |
+ global $txt; |
|
208 |
+ |
|
209 |
+ return comma_format($rowData[\'downloads\']); |
|
210 |
+ '), |
|
211 |
+ 'class' => 'windowbg', |
|
212 |
+ ), |
|
213 |
+ 'sort' => array( |
|
214 |
+ 'default' => 'a.downloads', |
|
215 |
+ 'reverse' => 'a.downloads DESC', |
|
216 |
+ ), |
|
217 |
+ ), |
|
218 |
+ 'check' => array( |
|
219 |
+ 'header' => array( |
|
220 |
+ 'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />', |
|
221 |
+ ), |
|
222 |
+ 'data' => array( |
|
223 |
+ 'sprintf' => array( |
|
224 |
+ 'format' => '<input type="checkbox" name="remove[%1$d]" class="input_check" />', |
|
225 |
+ 'params' => array( |
|
226 |
+ 'id_attach' => false, |
|
227 |
+ ), |
|
228 |
+ ), |
|
229 |
+ 'style' => 'text-align: center', |
|
230 |
+ ), |
|
231 |
+ ), |
|
232 |
+ ), |
|
233 |
+ 'form' => array( |
|
234 |
+ 'href' => $scripturl . '?action=admin;area=manageattachments;sa=remove;' . $context['browse_type'], |
|
235 |
+ 'include_sort' => true, |
|
236 |
+ 'include_start' => true, |
|
237 |
+ 'hidden_fields' => array( |
|
238 |
+ 'type' => $context['browse_type'], |
|
239 |
+ ), |
|
240 |
+ ), |
|
241 |
+ 'additional_rows' => array( |
|
242 |
+ array( |
|
243 |
+ 'position' => 'below_table_data', |
|
244 |
+ 'value' => '<input type="submit" name="remove_submit" class="button_submit" value="' . $txt['quickmod_delete_selected'] . '" onclick="return confirm(\'' . $txt['confirm_delete_attachments'] . '\');" />', |
|
245 |
+ 'class' => 'titlebg', |
|
246 |
+ 'style' => 'text-align: right;', |
|
247 |
+ ), |
|
248 |
+ ), |
|
249 |
+ ); |
|
250 |
+ |
|
251 |
+ // Create the list. |
|
252 |
+ require_once($sourcedir . '/Subs-List.php'); |
|
253 |
+ createList($listOptions); |
|
254 |
+} |
|
255 |
+ |
|
256 |
+function shd_list_get_files($start, $items_per_page, $sort, $browse_type) |
|
257 |
+{ |
|
258 |
+ global $smcFunc, $txt; |
|
259 |
+ |
|
260 |
+ $request = $smcFunc['db_query']('', ' |
|
261 |
+ SELECT |
|
262 |
+ hdtr.id_msg, IFNULL(mem.real_name, hdtr.poster_name) AS poster_name, hdtr.poster_time, hdt.id_ticket, hdtr.id_member, |
|
263 |
+ a.id_attach, a.filename, a.file_hash, a.attachment_type, a.size, a.width, a.height, a.downloads, hdt.subject |
|
264 |
+ FROM {db_prefix}attachments AS a |
|
265 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
266 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hda.id_ticket = hdt.id_ticket) |
|
267 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hda.id_msg = hdtr.id_msg) |
|
268 |
+ LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = hdtr.id_member) |
|
269 |
+ WHERE a.attachment_type = {int:attachment_type} |
|
270 |
+ ORDER BY {raw:sort} |
|
271 |
+ LIMIT {int:start}, {int:per_page}', |
|
272 |
+ array( |
|
273 |
+ 'attachment_type' => $browse_type === 'shd_thumb' ? '3' : '0', |
|
274 |
+ 'sort' => $sort, |
|
275 |
+ 'start' => $start, |
|
276 |
+ 'per_page' => $items_per_page, |
|
277 |
+ ) |
|
278 |
+ ); |
|
279 |
+ $files = array(); |
|
280 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
281 |
+ $files[] = $row; |
|
282 |
+ $smcFunc['db_free_result']($request); |
|
283 |
+ |
|
284 |
+ return $files; |
|
285 |
+} |
|
286 |
+ |
|
287 |
+function shd_list_get_num_files($browse_type) |
|
288 |
+{ |
|
289 |
+ global $smcFunc; |
|
290 |
+ |
|
291 |
+ $request = $smcFunc['db_query']('', ' |
|
292 |
+ SELECT COUNT(*) AS num_attach |
|
293 |
+ FROM {db_prefix}attachments AS a |
|
294 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
295 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hda.id_ticket = hdt.id_ticket) |
|
296 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hda.id_msg = hdtr.id_msg) |
|
297 |
+ WHERE a.attachment_type = {int:attachment_type} |
|
298 |
+ AND a.id_member = {int:guest_id_member}', |
|
299 |
+ array( |
|
300 |
+ 'attachment_type' => $browse_type === 'shd_thumb' ? '3' : '0', |
|
301 |
+ 'guest_id_member' => 0, |
|
302 |
+ ) |
|
303 |
+ ); |
|
304 |
+ |
|
305 |
+ list ($num_files) = $smcFunc['db_fetch_row']($request); |
|
306 |
+ $smcFunc['db_free_result']($request); |
|
307 |
+ |
|
308 |
+ return $num_files; |
|
309 |
+} |
|
310 |
+ |
|
311 |
+]]></add> |
|
312 |
+ </operation> |
|
313 |
+ </file> |
|
314 |
+ |
|
315 |
+ <file name="$themedir/ManageAttachments.template.php"> |
|
316 |
+ <operation> |
|
317 |
+ <search position="before"><![CDATA[$txt['attachment_manager_thumbs'], ']]></search> |
|
318 |
+ <add><![CDATA[', (empty($GLOBALS['modSettings']['helpdesk_active']) ? '' : '</a> | |
|
319 |
+ <a href="' . $scripturl . '?action=admin;area=manageattachments;sa=browse;shd_attach">' . ($context['browse_type'] == 'shd_attach' ? '<img src="' . $settings['images_url'] . '/selected.gif" alt=">" border="0" /> ' : '') . $txt['attachment_manager_shd_attach'] . '</a> | |
|
320 |
+ <a href="' . $scripturl . '?action=admin;area=manageattachments;sa=browse;shd_thumb">' . ($context['browse_type'] == 'shd_thumb' ? '<img src="' . $settings['images_url'] . '/selected.gif" alt=">" border="0" /> ' : '') . $txt['attachment_manager_shd_thumb']), ']]></add> |
|
321 |
+ </operation> |
|
322 |
+ </file> |
|
323 |
+ |
|
324 |
+</modification> |
|
0 | 325 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,177 @@ |
1 |
+<?xml version="1.0"?> |
|
2 |
+<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification"> |
|
3 |
+<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/"> |
|
4 |
+ <id>SimpleDeskTeam:SimpleDesk</id> |
|
5 |
+ <version>1.0 Felidae</version> |
|
6 |
+ |
|
7 |
+ <file name="$sourcedir/Profile-View.php"> |
|
8 |
+ <operation><!-- add the code to call for IP tracking --> |
|
9 |
+ <search position="after"><![CDATA[ $context['single_ip'] = strpos($context['ip'], '*') === false;]]></search> |
|
10 |
+ <add><![CDATA[ // Set the options for the helpdesk replies list. |
|
11 |
+ if (!empty($modSettings['helpdesk_active'])) |
|
12 |
+ { |
|
13 |
+ $listOptions = array( |
|
14 |
+ 'id' => 'track_helpdesk_list', |
|
15 |
+ 'title' => $txt['shd_replies_from_ip'] . ' ' . $context['ip'], |
|
16 |
+ 'start_var_name' => 'helpdeskStart', |
|
17 |
+ 'items_per_page' => $modSettings['defaultMaxMessages'], |
|
18 |
+ 'no_items_label' => $txt['shd_replies_from_ip'], |
|
19 |
+ 'base_href' => $context['base_url'] . ';searchip=' . $context['ip'], |
|
20 |
+ 'default_sort_col' => 'date2', |
|
21 |
+ 'get_items' => array( |
|
22 |
+ 'function' => 'shd_list_get_ip_messages', |
|
23 |
+ 'params' => array( |
|
24 |
+ 'hdtr.poster_ip ' . $ip_string, |
|
25 |
+ array('ip_address' => $ip_var), |
|
26 |
+ ), |
|
27 |
+ ), |
|
28 |
+ 'get_count' => array( |
|
29 |
+ 'function' => 'shd_list_get_ip_message_count', |
|
30 |
+ 'params' => array( |
|
31 |
+ 'hdtr.poster_ip ' . $ip_string, |
|
32 |
+ array('ip_address' => $ip_var), |
|
33 |
+ ), |
|
34 |
+ ), |
|
35 |
+ 'columns' => array( |
|
36 |
+ 'ip_address2' => array( |
|
37 |
+ 'header' => array( |
|
38 |
+ 'value' => $txt['ip_address'], |
|
39 |
+ ), |
|
40 |
+ 'data' => array( |
|
41 |
+ 'sprintf' => array( |
|
42 |
+ 'format' => '<a href="' . $context['base_url'] . ';searchip=%1$s">%1$s</a>', |
|
43 |
+ 'params' => array( |
|
44 |
+ 'ip' => false, |
|
45 |
+ ), |
|
46 |
+ ), |
|
47 |
+ ), |
|
48 |
+ 'sort' => array( |
|
49 |
+ 'default' => 'INET_ATON(hdtr.poster_ip)', |
|
50 |
+ 'reverse' => 'INET_ATON(hdtr.poster_ip) DESC', |
|
51 |
+ ), |
|
52 |
+ ), |
|
53 |
+ 'display_name' => array( |
|
54 |
+ 'header' => array( |
|
55 |
+ 'value' => $txt['display_name'], |
|
56 |
+ ), |
|
57 |
+ 'data' => array( |
|
58 |
+ 'db' => 'member_link', |
|
59 |
+ ), |
|
60 |
+ ), |
|
61 |
+ 'subject' => array( |
|
62 |
+ 'header' => array( |
|
63 |
+ 'value' => $txt['subject'], |
|
64 |
+ ), |
|
65 |
+ 'data' => array( |
|
66 |
+ 'sprintf' => array( |
|
67 |
+ 'format' => '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=%1$s.msg%2$s#msg%2$s" rel="nofollow">%3$s</a>%4$s', |
|
68 |
+ 'params' => array( |
|
69 |
+ 'ticket' => false, |
|
70 |
+ 'id' => false, |
|
71 |
+ 'subject' => false, |
|
72 |
+ 'additional' => false, |
|
73 |
+ ), |
|
74 |
+ ), |
|
75 |
+ ), |
|
76 |
+ ), |
|
77 |
+ 'date2' => array( |
|
78 |
+ 'header' => array( |
|
79 |
+ 'value' => $txt['date'], |
|
80 |
+ ), |
|
81 |
+ 'data' => array( |
|
82 |
+ 'db' => 'time', |
|
83 |
+ ), |
|
84 |
+ 'sort' => array( |
|
85 |
+ 'default' => 'hdtr.id_msg DESC', |
|
86 |
+ 'reverse' => 'hdtr.id_msg', |
|
87 |
+ ), |
|
88 |
+ ), |
|
89 |
+ ), |
|
90 |
+ 'additional_rows' => array( |
|
91 |
+ array( |
|
92 |
+ 'position' => 'after_title', |
|
93 |
+ 'value' => '<span class="smalltext">' . $txt['shd_replies_from_ip_desc'] . '</span>', |
|
94 |
+ 'class' => 'windowbg', |
|
95 |
+ 'style' => 'padding: 2ex;', |
|
96 |
+ ), |
|
97 |
+ ), |
|
98 |
+ ); |
|
99 |
+ |
|
100 |
+ // Create the helpdesk replies list. |
|
101 |
+ createList($listOptions); |
|
102 |
+ } |
|
103 |
+ |
|
104 |
+]]></add> |
|
105 |
+ </operation> |
|
106 |
+ <operation><!-- add the code to get IP tracking data --> |
|
107 |
+ <search position="end" /> |
|
108 |
+ <add><![CDATA[ |
|
109 |
+ |
|
110 |
+function shd_list_get_ip_messages($start, $items_per_page, $sort, $where, $where_vars = array()) |
|
111 |
+{ |
|
112 |
+ global $smcFunc, $txt, $scripturl; |
|
113 |
+ $query = shd_db_query('', ' |
|
114 |
+ SELECT |
|
115 |
+ hdtr.id_msg, hdtr.poster_ip, IFNULL(mem.real_name, hdtr.poster_name) AS display_name, mem.id_member, |
|
116 |
+ hdt.subject, hdtr.poster_time, hdt.id_ticket, hdt.id_first_msg |
|
117 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
118 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
119 |
+ LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = hdtr.id_member) |
|
120 |
+ WHERE {query_see_ticket} AND ' . $where . ' |
|
121 |
+ ORDER BY ' . $sort . ' |
|
122 |
+ LIMIT ' . $start . ', ' . $items_per_page, |
|
123 |
+ array_merge($where_vars, array( |
|
124 |
+ )) |
|
125 |
+ ); |
|
126 |
+ $messages = array(); |
|
127 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
128 |
+ $messages[] = array( |
|
129 |
+ 'ip' => $row['poster_ip'], |
|
130 |
+ 'member_link' => shd_profile_link($row['display_name'], $row['id_member']), |
|
131 |
+ 'ticket' => $row['id_ticket'], |
|
132 |
+ 'id' => $row['id_msg'], |
|
133 |
+ 'subject' => $row['subject'], |
|
134 |
+ 'time' => timeformat($row['poster_time']), |
|
135 |
+ 'timestamp' => forum_time(true, $row['poster_time']), |
|
136 |
+ 'additional' => $row['id_first_msg'] == $row['id_msg'] ? $txt['shd_is_ticket_opener'] : '', |
|
137 |
+ ); |
|
138 |
+ $smcFunc['db_free_result']($query); |
|
139 |
+ |
|
140 |
+ return $messages; |
|
141 |
+} |
|
142 |
+ |
|
143 |
+function shd_list_get_ip_message_count($where, $where_vars = array()) |
|
144 |
+{ |
|
145 |
+ global $smcFunc; |
|
146 |
+ |
|
147 |
+ $request = shd_db_query('', ' |
|
148 |
+ SELECT COUNT(id_msg) AS message_count |
|
149 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
150 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
151 |
+ WHERE {query_see_ticket} AND ' . $where, |
|
152 |
+ $where_vars |
|
153 |
+ ); |
|
154 |
+ list ($count) = $smcFunc['db_fetch_row']($request); |
|
155 |
+ $smcFunc['db_free_result']($request); |
|
156 |
+ |
|
157 |
+ return $count; |
|
158 |
+} |
|
159 |
+ |
|
160 |
+]]></add> |
|
161 |
+ </operation> |
|
162 |
+ </file> |
|
163 |
+ |
|
164 |
+ <file name="$themedir/Profile.template.php"><!-- add the display of tracked IPs to the profile view --> |
|
165 |
+ <operation> |
|
166 |
+ <search position="before"><![CDATA[template_show_list('track_message_list');]]></search> |
|
167 |
+ <add><![CDATA[ |
|
168 |
+ global $modSettings; |
|
169 |
+ if (!empty($modSettings['helpdesk_active'])) |
|
170 |
+ { |
|
171 |
+ echo '<br />'; |
|
172 |
+ |
|
173 |
+ template_show_list('track_helpdesk_list'); |
|
174 |
+ }]]></add> |
|
175 |
+ </operation> |
|
176 |
+ </file> |
|
177 |
+</modification> |
|
0 | 178 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,505 @@ |
1 |
+<?xml version="1.0"?> |
|
2 |
+<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification"> |
|
3 |
+<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/"> |
|
4 |
+ <id>SimpleDeskTeam:SimpleDesk</id> |
|
5 |
+ <version>1.0 Felidae</version> |
|
6 |
+ |
|
7 |
+ <file name="$sourcedir/Admin.php"><!-- adds the navbar links to the admin panel --> |
|
8 |
+ <operation><!-- main SHD menu --> |
|
9 |
+ <search position="after"><![CDATA[ // Make sure the administrator has a valid session...]]></search> |
|
10 |
+ <add><![CDATA[ // Add the SHD item to the menu |
|
11 |
+ $admin_areas['helpdesk_info'] = array( |
|
12 |
+ 'title' => $txt['shd_helpdesk'], |
|
13 |
+ 'permission' => array('admin_forum', 'admin_helpdesk'), |
|
14 |
+ 'enabled' => !empty($modSettings['helpdesk_active']), |
|
15 |
+ 'areas' => array( |
|
16 |
+ 'helpdesk_info' => array( |
|
17 |
+ 'label' => $txt['shd_admin_info'], |
|
18 |
+ 'file' => 'SimpleDesk-Admin.php', |
|
19 |
+ 'icon' => 'simpledesk.png', |
|
20 |
+ 'function' => 'shd_admin_main', |
|
21 |
+ 'subsections' => array( |
|
22 |
+ ), |
|
23 |
+ ), |
|
24 |
+ 'helpdesk_options' => array( |
|
25 |
+ 'label' => $txt['shd_admin_options'], |
|
26 |
+ 'file' => 'SimpleDesk-Admin.php', |
|
27 |
+ 'icon' => 'shd_status.png', |
|
28 |
+ 'function' => 'shd_admin_main', |
|
29 |
+ 'subsections' => array( |
|
30 |
+ 'display' => array($txt['shd_admin_options_display'], array('admin_forum', 'admin_helpdesk')), |
|
31 |
+ 'posting' => array($txt['shd_admin_options_posting'], array('admin_forum', 'admin_helpdesk')), |
|
32 |
+ 'admin' => array($txt['shd_admin_options_admin'], array('admin_forum', 'admin_helpdesk')), |
|
33 |
+ 'standalone' => array($txt['shd_admin_options_standalone'], array('admin_forum', 'admin_helpdesk')), |
|
34 |
+ ), |
|
35 |
+ ), |
|
36 |
+ 'helpdesk_actionlog' => array( |
|
37 |
+ 'label' => $txt['shd_admin_actionlog'], |
|
38 |
+ 'file' => 'SimpleDesk-Admin.php', |
|
39 |
+ 'icon' => 'shd_log.png', |
|
40 |
+ 'function' => 'shd_admin_main', |
|
41 |
+ 'subsections' => array( |
|
42 |
+ ), |
|
43 |
+ ), |
|
44 |
+ 'helpdesk_support' => array( |
|
45 |
+ 'label' => $txt['shd_admin_support'], |
|
46 |
+ 'file' => 'SimpleDesk-Admin.php', |
|
47 |
+ 'icon' => 'shd_support.png', |
|
48 |
+ 'function' => 'shd_admin_main', |
|
49 |
+ 'subsections' => array( |
|
50 |
+ ), |
|
51 |
+ ), |
|
52 |
+ ), |
|
53 |
+ ); |
|
54 |
+ |
|
55 |
+]]></add> |
|
56 |
+ </operation> |
|
57 |
+ <operation><!-- add the item to the logs menu --> |
|
58 |
+ <search position="before"><![CDATA['pruning' => array($txt['pruning_title'], 'admin_forum'),]]></search> |
|
59 |
+ <add><![CDATA[ |
|
60 |
+ 'helpdesklog' => array($txt['shd_admin_helpdesklog'], 'admin_forum', 'enabled' => $modSettings['helpdesk_active'], 'url' => $scripturl . '?action=admin;area=helpdesk_actionlog'),]]></add> |
|
61 |
+ </operation> |
|
62 |
+ <operation><!-- load the SD admin language file --> |
|
63 |
+ <search position="before"><![CDATA[loadLanguage('Admin');]]></search> |
|
64 |
+ <add><![CDATA[ |
|
65 |
+ shd_load_language('SimpleDeskAdmin');]]></add> |
|
66 |
+ </operation> |
|
67 |
+ <operation><!-- add SimpleDesk-Admin to the list of files to load when doing admin search --> |
|
68 |
+ <search position="after"><![CDATA[ foreach ($include_files as $file)]]></search> |
|
69 |
+ <add><![CDATA[ // Add SimpleDesk's file before we start anything |
|
70 |
+ $include_files[] = 'SimpleDesk-Admin'; |
|
71 |
+ |
|
72 |
+]]></add> |
|
73 |
+ </operation> |
|
74 |
+ <operation><!-- prepend SimpleDesk's ACP helper functions to the list of places to search --> |
|
75 |
+ <search position="replace"><![CDATA[// This is a special array of functions that contain setting data - we query all these to simply pull all setting bits! |
|
76 |
+ $settings_search = array(]]></search> |
|
77 |
+ <add><![CDATA[// Add SimpleDesk functions |
|
78 |
+ $settings_search = array(); |
|
79 |
+ $settings_search[] = array('shd_modify_display_options', 'area=helpdesk_options;sa=display'); |
|
80 |
+ $settings_search[] = array('shd_modify_posting_options', 'area=helpdesk_options;sa=posting'); |
|
81 |
+ $settings_search[] = array('shd_modify_admin_options', 'area=helpdesk_options;sa=admin'); |
|
82 |
+ $settings_search[] = array('shd_modify_standalone_options', 'area=helpdesk_options;sa=standalone'); |
|
83 |
+ |
|
84 |
+ // This is a special array of functions that contain setting data - we query all these to simply pull all setting bits! |
|
85 |
+ $settings_search += array( |
|
86 |
+ 4 =>]]></add> |
|
87 |
+ </operation> |
|
88 |
+ </file> |
|
89 |
+ |
|
90 |
+ <file name="$sourcedir/Load.php"><!-- load the main SimpleDesk language strings --> |
|
91 |
+ <operation> |
|
92 |
+ <search position="before"><![CDATA[loadSubTemplate('init', 'ignore');]]></search> |
|
93 |
+ <add><![CDATA[ |
|
94 |
+ // Load the language strings |
|
95 |
+ shd_load_language('SimpleDesk');]]></add> |
|
96 |
+ </operation> |
|
97 |
+ <operation><!-- globally figure out if Helpdesk is enabled; note this doesn't get pushed into settings table :) --> |
|
98 |
+ <search position="after"><![CDATA[ // Is post moderation alive and well?]]></search> |
|
99 |
+ <add><![CDATA[ // Are we helping people today? |
|
100 |
+ $modSettings['helpdesk_active'] = isset($modSettings['admin_features']) ? in_array('shd', explode(',', $modSettings['admin_features'])) : false; |
|
101 |
+ |
|
102 |
+]]></add> |
|
103 |
+ </operation> |
|
104 |
+ </file> |
|
105 |
+ |
|
106 |
+ <file name="$sourcedir/Subs.php"><!-- reconfigure the main menu somewhat --> |
|
107 |
+ <operation><!-- add a generic menu item --> |
|
108 |
+ <search position="replace"><![CDATA[ ), |
|
109 |
+ 'profile' => array(]]></search> |
|
110 |
+ <add><![CDATA[ ), |
|
111 |
+ 'helpdesk' => array( |
|
112 |
+ 'title' => $modSettings['helpdesk_active'] && SMF != 'SSI' ? shd_get_active_tickets() : $txt['shd_helpdesk'], |
|
113 |
+ 'href' => $scripturl . '?action=helpdesk;sa=main', |
|
114 |
+ 'show' => $modSettings['helpdesk_active'] && (allowedTo('access_helpdesk') || allowedTo('admin_helpdesk')), |
|
115 |
+ 'sub_buttons' => array( |
|
116 |
+ 'newticket' => array( |
|
117 |
+ 'title' => $txt['shd_new_ticket'], |
|
118 |
+ 'href' => $scripturl . '?action=helpdesk;sa=newticket', |
|
119 |
+ 'show' => SMF == 'SSI' ? false : shd_allowed_to('shd_new_ticket'), |
|
120 |
+ ), |
|
121 |
+ 'closedtickets' => array( |
|
122 |
+ 'title' => $txt['shd_tickets_closed'], |
|
123 |
+ 'href' => $scripturl . '?action=helpdesk;sa=closedtickets', |
|
124 |
+ 'show' => SMF == 'SSI' ? false : (shd_allowed_to('shd_resolve_ticket_own') || shd_allowed_to('shd_resolve_ticket_any')), |
|
125 |
+ ), |
|
126 |
+ 'recyclebin' => array( |
|
127 |
+ 'title' => $txt['shd_recycle_bin'], |
|
128 |
+ 'href' => $scripturl . '?action=helpdesk;sa=recyclebin', |
|
129 |
+ 'show' => SMF == 'SSI' ? false : shd_allowed_to('shd_access_recyclebin'), |
|
130 |
+ ), |
|
131 |
+ ), |
|
132 |
+ ), |
|
133 |
+ 'profile' => array(]]></add> |
|
134 |
+ </operation> |
|
135 |
+ <operation><!-- turn off PMs if they're disabled --> |
|
136 |
+ <search position="replace"><![CDATA[$context['allow_pm'] = allowedTo('pm_read');]]></search> |
|
137 |
+ <add><![CDATA[$context['allow_pm'] = allowedTo('pm_read') && (empty($modSettings['helpdesk_active']) || empty($modSettings['shd_helpdesk_only']) || empty($modSettings['shd_disable_pm']));]]></add> |
|
138 |
+ </operation> |
|
139 |
+ <operation><!-- expand the quote link= parameter --> |
|
140 |
+ <search position="before"><![CDATA[(?:topic|threadid)=[\dmsg#\./]{1,40}(?:;start=[\dmsg#\./]{1,40})?]]></search> |
|
141 |
+ <add><![CDATA[|action=helpdesk;sa=ticket;ticket=[\dmsg#\./]{1,40}(?:;start=[\dmsg#\./]{1,40})?]]></add> |
|
142 |
+ </operation> |
|
143 |
+ <operation><!-- mess with the main menu --> |
|
144 |
+ <search position="after"><![CDATA[ $context['menu_buttons'] = $menu_buttons;]]></search> |
|
145 |
+ <add><![CDATA[ // SD specific options |
|
146 |
+ if (!empty($modSettings['helpdesk_active'])) |
|
147 |
+ { |
|
148 |
+ // Stuff we'll always do in SD if active |
|
149 |
+ if (allowedTo(array('admin_forum', 'admin_helpdesk'))) |
|
150 |
+ { |
|
151 |
+ $menu_buttons['admin']['sub_buttons']['helpdesk_admin'] = array( |
|
152 |
+ 'title' => $txt['shd_helpdesk'], |
|
153 |
+ 'href' => $scripturl . '?action=admin;area=helpdesk_info', |
|
154 |
+ 'show' => allowedTo(array('admin_forum', 'admin_helpdesk')), |
|
155 |
+ ); |
|
156 |
+ } |
|
157 |
+ |
|
158 |
+ |
|
159 |
+ // Stuff we'll only do if in standalone mode |
|
160 |
+ if (!empty($modSettings['shd_helpdesk_only'])) |
|
161 |
+ { |
|
162 |
+ $menu_buttons['home'] = array( |
|
163 |
+ 'title' => $modSettings['helpdesk_active'] && SMF != 'SSI' ? shd_get_active_tickets() : $txt['shd_helpdesk'], |
|
164 |
+ 'href' => $scripturl . '?action=helpdesk;sa=main', |
|
165 |
+ 'show' => $modSettings['helpdesk_active'] && (allowedTo('access_helpdesk') || allowedTo('admin_helpdesk')), |
|
166 |
+ 'sub_buttons' => array( |
|
167 |
+ ), |
|
168 |
+ 'active_button' => false, |
|
169 |
+ ); |
|
170 |
+ unset($menu_buttons['helpdesk']); |
|
171 |
+ |
|
172 |
+ // Disable help, search, calendar, moderation center |
|
173 |
+ unset($menu_buttons['help']); |
|
174 |
+ |
|
175 |
+ unset($menu_buttons['search']); |
|
176 |
+ $context['allow_search'] = false; |
|
177 |
+ |
|
178 |
+ unset($menu_buttons['calendar']); |
|
179 |
+ $context['allow_calendar'] = false; |
|
180 |
+ |
|
181 |
+ unset($menu_buttons['moderate']); |
|
182 |
+ $context['allow_moderation_center'] = false; |
|
183 |
+ |
|
184 |
+ // Disable PMs |
|
185 |
+ if (!empty($modSettings['shd_disable_pm'])) |
|
186 |
+ { |
|
187 |
+ $context['allow_pm'] = false; |
|
188 |
+ unset($menu_buttons['pm']); |
|
189 |
+ $context['user']['unread_messages'] = 0; // to disable it trying to add to the menu item |
|
190 |
+ } |
|
191 |
+ |
|
192 |
+ // Disable memberlist |
|
193 |
+ if (!empty($modSettings['shd_disable_mlist'])) |
|
194 |
+ { |
|
195 |
+ $context['allow_memberlist'] = false; |
|
196 |
+ unset($menu_buttons['mlist']); |
|
197 |
+ } |
|
198 |
+ } |
|
199 |
+ } |
|
200 |
+ |
|
201 |
+]]></add> |
|
202 |
+ </operation> |
|
203 |
+ </file> |
|
204 |
+ |
|
205 |
+ <file name="$sourcedir/ManageSettings.php"><!-- add the helpdesk to Core Features in admin --> |
|
206 |
+ <operation> |
|
207 |
+ <search position="after"><![CDATA[ // k = karma.]]></search> |
|
208 |
+ <add><![CDATA[ // shd = Helpdesk - Simple(Help)Desk |
|
209 |
+ 'shd' => array( |
|
210 |
+ 'url' => 'action=admin;area=helpdesk_info', |
|
211 |
+ ), |
|
212 |
+]]></add> |
|
213 |
+ </operation> |
|
214 |
+ </file> |
|
215 |
+ |
|
216 |
+ <file name="$sourcedir/Display.php"><!-- add topic to ticket menu button --> |
|
217 |
+ <operation> |
|
218 |
+ <search position="after"><![CDATA[// We don't want to show the poll icon in the topic class here, so pretend it's not one.]]></search> |
|
219 |
+ <add><![CDATA[// Simpledesk: Figure out if they can move this topic to the Helpdesk. |
|
220 |
+ $context['can_move_to_helpdesk'] = allowedTo('shd_topic_to_ticket') && empty($modSettings['shd_helpdesk_only']); |
|
221 |
+]]></add> |
|
222 |
+ </operation> |
|
223 |
+ </file> |
|
224 |
+ |
|
225 |
+ <file name="$sourcedir/ManagePermissions.php"><!-- add all the glorious permissions in an uber extensible way without screwing with Modifications.{language}.php (it's on EVERY page load, and every little helps) --> |
|
226 |
+ <operation> |
|
227 |
+ <search position="after"><![CDATA[ // We need to know what permissions we can't give to guests.]]></search> |
|
228 |
+ <add><![CDATA[ // Load the helpdesk permissions; in a painless manner that doesn't interfere with anything else :) |
|
229 |
+ if ($modSettings['helpdesk_active']) |
|
230 |
+ { |
|
231 |
+ shd_load_language('SimpleDeskPermissions'); |
|
232 |
+ $permissionList['membergroup'] += array( |
|
233 |
+ 'access_helpdesk' => array(false, 'helpdesk', 'use_helpdesk'), |
|
234 |
+ 'shd_view_ticket' => array(true, 'helpdesk', 'use_helpdesk'), |
|
235 |
+ 'shd_view_ticket_private' => array(true, 'helpdesk', 'use_helpdesk'), |
|
236 |
+ 'shd_alter_urgency' => array(true, 'helpdesk', 'use_helpdesk'), |
|
237 |
+ 'shd_alter_urgency_higher' => array(true, 'helpdesk', 'use_helpdesk'), |
|
238 |
+ 'shd_new_ticket' => array(false, 'helpdesk', 'use_helpdesk'), |
|
239 |
+ 'shd_edit_ticket' => array(true, 'helpdesk', 'use_helpdesk'), |
|
240 |
+ 'shd_reply_ticket' => array(true, 'helpdesk', 'use_helpdesk'), |
|
241 |
+ 'shd_edit_reply' => array(true, 'helpdesk', 'use_helpdesk'), |
|
242 |
+ 'shd_post_attachment' => array(false, 'helpdesk', 'use_helpdesk'), |
|
243 |
+ 'shd_resolve_ticket' => array(true, 'helpdesk', 'use_helpdesk'), |
|
244 |
+ |
|
245 |
+ 'shd_staff' => array(false, 'shd_staff', 'shd_staff'), |
|
246 |
+ 'shd_alter_privacy' => array(true, 'shd_staff', 'shd_staff'), |
|
247 |
+ 'shd_assign_ticket' => array(true, 'shd_staff', 'shd_staff'), |
|
248 |
+ 'shd_delete_ticket' => array(true, 'shd_staff', 'shd_staff'), |
|
249 |
+ 'shd_delete_reply' => array(true, 'shd_staff', 'shd_staff'), |
|
250 |
+ 'shd_restore_ticket' => array(true, 'shd_staff', 'shd_staff'), |
|
251 |
+ 'shd_restore_reply' => array(true, 'shd_staff', 'shd_staff'), |
|
252 |
+ 'shd_ticket_to_topic' => array(false, 'shd_staff', 'shd_staff'), |
|
253 |
+ 'shd_topic_to_ticket' => array(false, 'shd_staff', 'shd_staff'), |
|
254 |
+ |
|
255 |
+ 'admin_helpdesk' => array(false, 'shd_admin', 'shd_admin'), |
|
256 |
+ 'shd_delete_recycling' => array(false, 'shd_admin', 'shd_admin'), |
|
257 |
+ 'shd_access_recyclebin' => array(false, 'shd_admin', 'shd_admin'), |
|
258 |
+ ); |
|
259 |
+ |
|
260 |
+ $leftPermissionGroups[] = 'helpdesk'; |
|
261 |
+ |
|
262 |
+ // Also, are we in SHD only mode? If so... hoo boy, we gots some purging to do. |
|
263 |
+ if (!empty($modSettings['shd_helpdesk_only'])) |
|
264 |
+ { |
|
265 |
+ $perms_disable = array( |
|
266 |
+ 'membergroup' => array( |
|
267 |
+ 'view_stats', |
|
268 |
+ 'who_view', |
|
269 |
+ 'search_posts', |
|
270 |
+ 'karma_edit', |
|
271 |
+ 'calendar_view', |
|
272 |
+ 'calendar_post', |
|
273 |
+ 'calendar_edit', |
|
274 |
+ 'manage_boards', |
|
275 |
+ 'manage_attachments', |
|
276 |
+ 'manage_smileys', |
|
277 |
+ 'edit_news', |
|
278 |
+ 'access_mod_center', |
|
279 |
+ 'moderate_forum', |
|
280 |
+ 'send_mail', |
|
281 |
+ 'issue_warning', |
|
282 |
+ 'shd_ticket_to_topic', // yes, even our own, makes sense to reuse what we have here |
|
283 |
+ 'shd_topic_to_ticket', |
|
284 |
+ ), |
|
285 |
+ 'board' => array( |
|
286 |
+ 'moderate_board', |
|
287 |
+ 'approve_posts', |
|
288 |
+ 'post_new', |
|
289 |
+ 'post_unapproved_topics', |
|
290 |
+ 'post_unapproved_replies', |
|
291 |
+ 'post_reply', |
|
292 |
+ 'merge_any', |
|
293 |
+ 'split_any', |
|
294 |
+ 'send_topic', |
|
295 |
+ 'make_sticky', |
|
296 |
+ 'move', |
|
297 |
+ 'lock', |
|
298 |
+ 'remove', |
|
299 |
+ 'modify_replies', |
|
300 |
+ 'delete_replies', |
|
301 |
+ 'announce_topic', |
|
302 |
+ 'delete', |
|
303 |
+ 'modify', |
|
304 |
+ 'report_any', |
|
305 |
+ 'poll_view', |
|
306 |
+ 'poll_vote', |
|
307 |
+ 'poll_post', |
|
308 |
+ 'poll_add', |
|
309 |
+ 'poll_edit', |
|
310 |
+ 'poll_lock', |
|
311 |
+ 'poll_remove', |
|
312 |
+ 'mark_any_notify', |
|
313 |
+ 'mark_notify', |
|
314 |
+ 'view_attachments', |
|
315 |
+ 'post_unapproved_attachments', |
|
316 |
+ 'post_attachment', |
|
317 |
+ ), |
|
318 |
+ ); |
|
319 |
+ // that's the generic stuff, now for specific options |
|
320 |
+ if (!empty($modSettings['shd_disable_pm'])) |
|
321 |
+ { |
|
322 |
+ $perms_disable['membergroup'][] = 'pm_read'; |
|
323 |
+ $perms_disable['membergroup'][] = 'pm_send'; |
|
324 |
+ } |
|
325 |
+ |
|
326 |
+ foreach ($perms_disable as $group => $perm_list) |
|
327 |
+ foreach ($perm_list as $perm) |
|
328 |
+ if (isset($permissionList[$group][$perm])) |
|
329 |
+ unset($permissionList[$group][$perm]); |
|
330 |
+ } |
|
331 |
+ } |
|
332 |
+ |
|
333 |
+]]></add> |
|
334 |
+ </operation> |
|
335 |
+ </file> |
|
336 |
+ |
|
337 |
+ <file name="$sourcedir/Help.php"> |
|
338 |
+ <operation><!-- load the permissions help strings --> |
|
339 |
+ <search position="replace"><![CDATA[ loadLanguage('ManagePermissions');]]></search> |
|
340 |
+ <add><![CDATA[ { |
|
341 |
+ loadLanguage('ManagePermissions'); |
|
342 |
+ shd_load_language('SimpleDeskPermissions'); |
|
343 |
+ }]]></add> |
|
344 |
+ </operation> |
|
345 |
+ <operation><!-- load the admin help strings --> |
|
346 |
+ <search position="replace"><![CDATA[ loadLanguage('Help');]]></search> |
|
347 |
+ <add><![CDATA[ loadLanguage('Help'); |
|
348 |
+ shd_load_language('SimpleDeskAdmin');]]></add> |
|
349 |
+ </operation> |
|
350 |
+ </file> |
|
351 |
+ |
|
352 |
+ <file name="$sourcedir/ManageBoards.php"><!-- load the permissions language file if we're managing boards --> |
|
353 |
+ <operation> |
|
354 |
+ <search position="before"><![CDATA[loadLanguage('ManagePermissions');]]></search> |
|
355 |
+ <add><![CDATA[ |
|
356 |
+ shd_load_language('SimpleDeskPermissions');]]></add> |
|
357 |
+ </operation> |
|
358 |
+ </file> |
|
359 |
+ |
|
360 |
+ <file name="$sourcedir/ManagePosts.php"><!-- at the same time we modify the post settings, make sure we check and update SD's if necessary --> |
|
361 |
+ <operation> |
|
362 |
+ <search position="before"><![CDATA[$smcFunc['db_change_column']('{db_prefix}messages', 'body', array('type' => 'mediumtext'));]]></search> |
|
363 |
+ <add><![CDATA[ |
|
364 |
+ $smcFunc['db_change_column']('{db_prefix}helpdesk_ticket_replies', 'body', array('type' => 'mediumtext'));]]></add> |
|
365 |
+ </operation> |
|
366 |
+ <operation> |
|
367 |
+ <search position="before"><![CDATA[$smcFunc['db_change_column']('{db_prefix}messages', 'body', array('type' => 'text'));]]></search> |
|
368 |
+ <add><![CDATA[ |
|
369 |
+ $smcFunc['db_change_column']('{db_prefix}helpdesk_ticket_replies', 'body', array('type' => 'text'));]]></add> |
|
370 |
+ </operation> |
|
371 |
+ </file> |
|
372 |
+ |
|
373 |
+ <file name="$sourcedir/Profile-View.php"><!-- load the permissions language file if we're looking at profile/permissions --> |
|
374 |
+ <operation> |
|
375 |
+ <search position="after"><![CDATA[ loadLanguage('ManagePermissions');]]></search> |
|
376 |
+ <add><![CDATA[ shd_load_language('SimpleDeskPermissions'); |
|
377 |
+]]></add> |
|
378 |
+ </operation> |
|
379 |
+ </file> |
|
380 |
+ |
|
381 |
+ <file name="$sourcedir/Reports.php"><!-- load the permissions language file if we're getting a report --> |
|
382 |
+ <operation> |
|
383 |
+ <search position="before"><![CDATA[loadLanguage('ManagePermissions');]]></search> |
|
384 |
+ <add><![CDATA[ |
|
385 |
+ shd_load_language('SimpleDeskPermissions');]]></add> |
|
386 |
+ </operation> |
|
387 |
+ </file> |
|
388 |
+ |
|
389 |
+ <file name="$sourcedir/Who.php"><!-- load the who's online strings... we don't use it much now, but maybe later... --> |
|
390 |
+ <operation> |
|
391 |
+ <search position="before"><![CDATA[loadLanguage('Who');]]></search> |
|
392 |
+ <add><![CDATA[ |
|
393 |
+ shd_load_language('SimpleDeskWho');]]></add> |
|
394 |
+ </operation> |
|
395 |
+ </file> |
|
396 |
+ |
|
397 |
+ <file name="$sourcedir/Errors.php"><!-- if an error occurs in an SD file, log it appropriately with the SD errortype --> |
|
398 |
+ <operation> |
|
399 |
+ <search position="after"><![CDATA[ // Make sure the category that was specified is a valid one]]></search> |
|
400 |
+ <add><![CDATA[ // Is this a SimpleDesk error? |
|
401 |
+ $known_error_types[] = 'simpledesk'; |
|
402 |
+ if (strpos($file, 'SimpleDesk') !== false || strpos($error_message, 'shd_') !== false) |
|
403 |
+ $error_type = 'simpledesk'; |
|
404 |
+ |
|
405 |
+]]></add> |
|
406 |
+ </operation> |
|
407 |
+ </file> |
|
408 |
+ |
|
409 |
+ <file name="$boarddir/index.php"><!-- set up the relevant action stuff --> |
|
410 |
+ <operation><!-- add/remove action without having to touch the master array - cleaner! --> |
|
411 |
+ <search position="after"><![CDATA[ // Get the function and file to include - if it's not there, do the board index.]]></search> |
|
412 |
+ <add><![CDATA[ // Deal with SimpleDesk. If we're enabling HD only mode, rebuild everything, otherwise just add it to the array. |
|
413 |
+ $actionArray['helpdesk'] = array('SimpleDesk.php', 'shd_main'); |
|
414 |
+ if (!empty($modSettings['shd_helpdesk_only']) && $modSettings['helpdesk_active']) |
|
415 |
+ { |
|
416 |
+ // Firstly, remove all the standard actions we neither want nor need. |
|
417 |
+ // Note we did this to prevent breakage of other mods that may be installed, e.g. gallery or portal or something. |
|
418 |
+ $unwanted_actions = array('announce', 'attachapprove', 'buddy', 'calendar', 'clock', 'collapse', 'deletemsg', 'display', 'editpoll', 'editpoll2', |
|
419 |
+ 'emailuser', 'groups', 'lock', 'lockvoting', 'markasread', 'mergetopics', 'moderate', 'modifycat', 'modifykarma', 'movetopic', 'movetopic2', |
|
420 |
+ 'notify', 'notifyboard', 'post', 'post2', 'printpage', 'quotefast', 'quickmod', 'quickmod2', 'recent', 'reminder', 'removepoll', 'removetopic2', |
|
421 |
+ 'reporttm', 'restoretopic', 'search', 'search2', 'sendtopic', 'smstats', 'splittopics', 'stats', 'sticky', 'trackip', 'about:mozilla', 'about:unknown', |
|
422 |
+ 'unread', 'unreadreplies', 'vote', 'viewquery', 'who', '.xml', 'xmlhttp'); |
|
423 |
+ |
|
424 |
+ // that's the generic stuff, now for specific options |
|
425 |
+ if (!empty($modSettings['shd_disable_pm'])) |
|
426 |
+ $unwanted_actions[] = 'pm'; |
|
427 |
+ |
|
428 |
+ if (!empty($modSettings['shd_disable_mlist'])) |
|
429 |
+ $unwanted_actions[] = 'mlist'; |
|
430 |
+ |
|
431 |
+ foreach ($unwanted_actions as $unwanted) |
|
432 |
+ if (isset($actionArray[$unwanted])) |
|
433 |
+ unset($actionArray[$unwanted]); |
|
434 |
+ |
|
435 |
+ // Secondly, rewrite the defaults to point to helpdesk, for unknown actions. I'm doing this rather than munging the main code - easier to unbreak stuff |
|
436 |
+ if (empty($actionArray[$_GET['action']])) |
|
437 |
+ $_GET['action'] = 'helpdesk'; |
|
438 |
+ } |
|
439 |
+]]></add> |
|
440 |
+ </operation> |
|
441 |
+ <operation><!-- add a master override if we haven't declared an action --> |
|
442 |
+ <search position="after"><![CDATA[ // Action and board are both empty... BoardIndex!]]></search> |
|
443 |
+ <add><![CDATA[ // If we're in HD-only mode, let's run with that! |
|
444 |
+ if (!empty($modSettings['shd_helpdesk_only']) && $modSettings['helpdesk_active']) |
|
445 |
+ { |
|
446 |
+ require_once($sourcedir . '/SimpleDesk.php'); |
|
447 |
+ return 'shd_main'; |
|
448 |
+ } |
|
449 |
+]]></add> |
|
450 |
+ </operation> |
|
451 |
+ <operation><!-- add a catcher in case it's a function we don't have --> |
|
452 |
+ <search position="after"><![CDATA[ // Fall through to the board index then... |
|
453 |
+ require_once($sourcedir . '/BoardIndex.php'); |
|
454 |
+ return 'BoardIndex';]]></search> |
|
455 |
+ <add><![CDATA[ // If we're in HD-only mode, we can't let them go anywhere useless |
|
456 |
+ if (!empty($modSettings['shd_helpdesk_only']) && $modSettings['helpdesk_active']) |
|
457 |
+ { |
|
458 |
+ require_once($sourcedir . '/SimpleDesk.php'); |
|
459 |
+ return 'shd_main'; |
|
460 |
+ } |
|
461 |
+ |
|
462 |
+]]></add> |
|
463 |
+ </operation> |
|
464 |
+ <operation><!-- bootstrap the SimpleDesk functions a little --> |
|
465 |
+ <search position="before"><![CDATA[require_once($sourcedir . '/Security.php');]]></search> |
|
466 |
+ <add><![CDATA[ |
|
467 |
+require_once($sourcedir . '/Subs-SimpleDesk.php');]]></add> |
|
468 |
+ </operation> |
|
469 |
+ </file> |
|
470 |
+ |
|
471 |
+ <!-- theme edits boohoo --> |
|
472 |
+ <file name="$themedir/Display.template.php"><!-- add topic to ticket menu button --> |
|
473 |
+ <operation> |
|
474 |
+ <search position="after"><![CDATA[// Show the page index... "Pages: [1]".]]></search> |
|
475 |
+ <add><![CDATA[ // SimpleDesk: Add topic -> ticket button |
|
476 |
+ $normal_buttons = array_merge($normal_buttons,array('topictoticket' => array('test' => 'can_move_to_helpdesk', 'text' => 'shd_move_topic_to_ticket', 'lang' => true, 'url' => $scripturl . '?action=helpdesk;sa=topictoticket;topic='.$context['current_topic'].';' . $context['session_var'] . '=' . $context['session_id']))); |
|
477 |
+]]></add> |
|
478 |
+ </operation> |
|
479 |
+ </file> |
|
480 |
+ |
|
481 |
+ <!-- remove the unread/unreadreplies links in SD only mode --> |
|
482 |
+ <!-- unfortunately, these pretty much have to be atomic edits :( --> |
|
483 |
+ <file name="$themedir/index.template.php"> |
|
484 |
+ <operation error="ignore"> |
|
485 |
+ <search position="replace"><![CDATA[ |
|
486 |
+ <li><a href="', $scripturl, '?action=unread">', $txt['unread_since_visit'], '</a></li> |
|
487 |
+ <li><a href="', $scripturl, '?action=unreadreplies">', $txt['show_unread_replies'], '</a></li>';]]></search> |
|
488 |
+ <add><![CDATA[ |
|
489 |
+ ', (!empty($modSettings['helpdesk_active']) && !empty($modSettings['shd_helpdesk_only'])) ? '' : ('<li><a href="' . $scripturl . '?action=unread">' . $txt['unread_since_visit'] . '</a></li> |
|
490 |
+ <li><a href="' . $scripturl . '?action=unreadreplies">' . $txt['show_unread_replies'] . '</a></li>');]]></add> |
|
491 |
+ </operation> |
|
492 |
+ </file> |
|
493 |
+ |
|
494 |
+ <file name="$themes_dir/core/index.template.php" error="skip"> |
|
495 |
+ <operation error="ignore"> |
|
496 |
+ <search position="replace"><![CDATA[ |
|
497 |
+ <li><a href="', $scripturl, '?action=unread">', $txt['unread_since_visit'], '</a></li> |
|
498 |
+ <li><a href="', $scripturl, '?action=unreadreplies">', $txt['show_unread_replies'], '</a></li>';]]></search> |
|
499 |
+ <add><![CDATA[ |
|
500 |
+ ', (!empty($modSettings['helpdesk_active']) && !empty($modSettings['shd_helpdesk_only'])) ? '' : ('<li><a href="' . $scripturl . '?action=unread">' . $txt['unread_since_visit'] . '</a></li> |
|
501 |
+ <li><a href="' . $scripturl . '?action=unreadreplies">' . $txt['show_unread_replies'] . '</a></li>');]]></add> |
|
502 |
+ </operation> |
|
503 |
+ </file> |
|
504 |
+ |
|
505 |
+</modification> |
|
0 | 506 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,508 @@ |
1 |
+<?php |
|
2 |
+########################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+########################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+########################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+########################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: install.php / 1.0 Felidae # |
|
18 |
+########################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This script prepares the database for all the tables and other database changes that SimpleDesk requires. |
|
22 |
+ * |
|
23 |
+ * NOTE: This script is meant to run using the <samp><database></database></samp> elements of the package-info.xml file. This is so |
|
24 |
+ * that admins have the choice to uninstall any database data installed with the mod. Also, since using the <samp><database></samp> |
|
25 |
+ * elements automatically calls on db_extend('packages'), we will only be calling that if we are running this script standalone. |
|
26 |
+ * |
|
27 |
+ * @package installer |
|
28 |
+ * @since 1.0 |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Before attempting to execute, this file attempts to load SSI.php to enable access to the database functions. |
|
33 |
+*/ |
|
34 |
+ |
|
35 |
+// If we have found SSI.php and we are outside of SMF, then we are running standalone. |
|
36 |
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF')) |
|
37 |
+ require_once(dirname(__FILE__) . '/SSI.php'); |
|
38 |
+elseif (!defined('SMF')) // If we are outside SMF and can't find SSI.php, then throw an error |
|
39 |
+ die('<b>Error:</b> Cannot install - please verify you put this file in the same place as SMF\'s SSI.php.'); |
|
40 |
+ |
|
41 |
+if (SMF == 'SSI') |
|
42 |
+ db_extend('packages'); |
|
43 |
+ |
|
44 |
+global $modSettings, $smcFunc; |
|
45 |
+ |
|
46 |
+// For our BBC settings, we first fetch a list off all BBC tags there are. |
|
47 |
+$bbc_tags = array(); |
|
48 |
+foreach (parse_bbc(false) AS $tag) |
|
49 |
+ $bbc_tags[] = $tag['tag']; |
|
50 |
+ |
|
51 |
+// Here we will update the $modSettings variables. |
|
52 |
+$mod_settings = array( |
|
53 |
+ 'shd_attachments_mode' => 'ticket', |
|
54 |
+ 'shd_staff_badge' => 'nobadge', |
|
55 |
+ 'shd_ticketnav_style' => 'sd', |
|
56 |
+ 'shd_enabled_bbc' => implode(',', $bbc_tags), // By default, all available tags are enabled. |
|
57 |
+ 'shd_privacy_display' => 'smart', |
|
58 |
+); |
|
59 |
+ |
|
60 |
+// Now, we move on to adding new tables to the database. |
|
61 |
+$tables = array(); |
|
62 |
+$tables[] = array( |
|
63 |
+ 'table_name' => '{db_prefix}helpdesk_tickets', |
|
64 |
+ 'columns' => array( |
|
65 |
+ array( |
|
66 |
+ 'name' => 'id_ticket', |
|
67 |
+ 'auto' => true, |
|
68 |
+ 'type' => 'mediumint', |
|
69 |
+ 'size' => 8, |
|
70 |
+ 'null' => false, |
|
71 |
+ 'unsigned' => true, |
|
72 |
+ ), |
|
73 |
+ array( |
|
74 |
+ 'name' => 'id_first_msg', |
|
75 |
+ 'auto' => false, |
|
76 |
+ 'type' => 'int', |
|
77 |
+ 'size' => 10, |
|
78 |
+ 'null' => false, |
|
79 |
+ 'unsigned' => true, |
|
80 |
+ 'default' => 0, |
|
81 |
+ ), |
|
82 |
+ array( |
|
83 |
+ 'name' => 'id_member_started', |
|
84 |
+ 'auto' => false, |
|
85 |
+ 'type' => 'mediumint', |
|
86 |
+ 'size' => 8, |
|
87 |
+ 'null' => false, |
|
88 |
+ 'unsigned' => true, |
|
89 |
+ 'default' => 0, |
|
90 |
+ ), |
|
91 |
+ array( |
|
92 |
+ 'name' => 'id_last_msg', |
|
93 |
+ 'auto' => false, |
|
94 |
+ 'type' => 'int', |
|
95 |
+ 'size' => 10, |
|
96 |
+ 'null' => false, |
|
97 |
+ 'unsigned' => true, |
|
98 |
+ 'default' => 0, |
|
99 |
+ ), |
|
100 |
+ array( |
|
101 |
+ 'name' => 'id_member_updated', |
|
102 |
+ 'auto' => false, |
|
103 |
+ 'type' => 'mediumint', |
|
104 |
+ 'size' => 8, |
|
105 |
+ 'null' => false, |
|
106 |
+ 'unsigned' => true, |
|
107 |
+ 'default' => 0, |
|
108 |
+ ), |
|
109 |
+ array( |
|
110 |
+ 'name' => 'id_member_assigned', |
|
111 |
+ 'auto' => false, |
|
112 |
+ 'type' => 'mediumint', |
|
113 |
+ 'size' => 8, |
|
114 |
+ 'null' => false, |
|
115 |
+ 'unsigned' => true, |
|
116 |
+ 'default' => 0, |
|
117 |
+ ), |
|
118 |
+ array( |
|
119 |
+ 'name' => 'num_replies', |
|
120 |
+ 'auto' => false, |
|
121 |
+ 'type' => 'int', |
|
122 |
+ 'size' => 10, |
|
123 |
+ 'null' => false, |
|
124 |
+ 'unsigned' => true, |
|
125 |
+ 'default' => 0, |
|
126 |
+ ), |
|
127 |
+ array( |
|
128 |
+ 'name' => 'deleted_replies', |
|
129 |
+ 'auto' => false, |
|
130 |
+ 'type' => 'int', |
|
131 |
+ 'size' => 10, |
|
132 |
+ 'null' => false, |
|
133 |
+ 'unsigned' => true, |
|
134 |
+ 'default' => 0, |
|
135 |
+ ), |
|
136 |
+ array( |
|
137 |
+ 'name' => 'subject', |
|
138 |
+ 'auto' => false, |
|
139 |
+ 'type' => 'varchar', |
|
140 |
+ 'size' => 100, |
|
141 |
+ 'null' => false, |
|
142 |
+ ), |
|
143 |
+ array( |
|
144 |
+ 'name' => 'urgency', |
|
145 |
+ 'auto' => false, |
|
146 |
+ 'type' => 'tinyint', |
|
147 |
+ 'size' => 3, |
|
148 |
+ 'null' => false, |
|
149 |
+ 'unsigned' => true, |
|
150 |
+ 'default' => 0, |
|
151 |
+ ), |
|
152 |
+ array( |
|
153 |
+ 'name' => 'status', |
|
154 |
+ 'auto' => false, |
|
155 |
+ 'type' => 'tinyint', |
|
156 |
+ 'size' => 3, |
|
157 |
+ 'null' => false, |
|
158 |
+ 'unsigned' => true, |
|
159 |
+ 'default' => 0, |
|
160 |
+ ), |
|
161 |
+ array( |
|
162 |
+ 'name' => 'private', |
|
163 |
+ 'auto' => false, |
|
164 |
+ 'type' => 'tinyint', |
|
165 |
+ 'size' => 3, |
|
166 |
+ 'null' => false, |
|
167 |
+ 'unsigned' => true, |
|
168 |
+ 'default' => 0, |
|
169 |
+ ), |
|
170 |
+ array( |
|
171 |
+ 'name' => 'withdeleted', |
|
172 |
+ 'auto' => false, |
|
173 |
+ 'type' => 'tinyint', |
|
174 |
+ 'size' => 3, |
|
175 |
+ 'null' => false, |
|
176 |
+ 'unsigned' => true, |
|
177 |
+ 'default' => 0, |
|
178 |
+ ), |
|
179 |
+ ), |
|
180 |
+ 'indexes' => array( |
|
181 |
+ array( |
|
182 |
+ 'columns' => array('id_ticket'), |
|
183 |
+ 'type' => 'primary', |
|
184 |
+ ), |
|
185 |
+ array( |
|
186 |
+ 'columns' => array('status', 'id_member_assigned'), |
|
187 |
+ 'type' => 'index', |
|
188 |
+ ), |
|
189 |
+ array( |
|
190 |
+ 'columns' => array('id_member_started', 'private'), |
|
191 |
+ 'type' => 'index', |
|
192 |
+ ), |
|
193 |
+ array( |
|
194 |
+ 'columns' => array('status', 'withdeleted', 'deleted_replies'), |
|
195 |
+ ), |
|
196 |
+ ), |
|
197 |
+ 'if_exists' => 'update', |
|
198 |
+ 'error' => 'fatal', |
|
199 |
+ 'parameters' => array(), |
|
200 |
+); |
|
201 |
+$tables[] = array( |
|
202 |
+ 'table_name' => '{db_prefix}helpdesk_ticket_replies', |
|
203 |
+ 'columns' => array( |
|
204 |
+ array( |
|
205 |
+ 'name' => 'id_msg', |
|
206 |
+ 'auto' => true, |
|
207 |
+ 'type' => 'int', |
|
208 |
+ 'size' => 10, |
|
209 |
+ 'null' => false, |
|
210 |
+ 'unsigned' => true, |
|
211 |
+ ), |
|
212 |
+ array( |
|
213 |
+ 'name' => 'id_ticket', |
|
214 |
+ 'auto' => false, |
|
215 |
+ 'type' => 'mediumint', |
|
216 |
+ 'size' => 8, |
|
217 |
+ 'null' => false, |
|
218 |
+ 'unsigned' => true, |
|
219 |
+ ), |
|
220 |
+ array( |
|
221 |
+ 'name' => 'body', |
|
222 |
+ 'auto' => false, |
|
223 |
+ 'type' => $modSettings['max_messageLength'] > 65535 ? 'text' : 'mediumtext', |
|
224 |
+ 'null' => false, |
|
225 |
+ ), |
|
226 |
+ array( |
|
227 |
+ 'name' => 'id_member', |
|
228 |
+ 'auto' => false, |
|
229 |
+ 'type' => 'mediumint', |
|
230 |
+ 'size' => 8, |
|
231 |
+ 'default' => 0, |
|
232 |
+ 'null' => false, |
|
233 |
+ 'unsigned' => true, |
|
234 |
+ ), |
|
235 |
+ array( |
|
236 |
+ 'name' => 'poster_time', |
|
237 |
+ 'auto' => false, |
|
238 |
+ 'type' => 'int', |
|
239 |
+ 'size' => 10, |
|
240 |
+ 'default' => 0, |
|
241 |
+ 'null' => false, |
|
242 |
+ 'unsigned' => true, |
|
243 |
+ ), |
|
244 |
+ array( |
|
245 |
+ 'name' => 'poster_name', |
|
246 |
+ 'auto' => false, |
|
247 |
+ 'type' => 'varchar', |
|
248 |
+ 'size' => 255, |
|
249 |
+ 'null' => false, |
|
250 |
+ ), |
|
251 |
+ array( |
|
252 |
+ 'name' => 'poster_email', |
|
253 |
+ 'auto' => false, |
|
254 |
+ 'type' => 'varchar', |
|
255 |
+ 'size' => 255, |
|
256 |
+ 'null' => false, |
|
257 |
+ ), |
|
258 |
+ array( |
|
259 |
+ 'name' => 'poster_ip', |
|
260 |
+ 'auto' => false, |
|
261 |
+ 'type' => 'varchar', |
|
262 |
+ 'size' => 255, |
|
263 |
+ 'null' => false, |
|
264 |
+ ), |
|
265 |
+ array( |
|
266 |
+ 'name' => 'modified_time', |
|
267 |
+ 'auto' => false, |
|
268 |
+ 'type' => 'int', |
|
269 |
+ 'size' => 10, |
|
270 |
+ 'default' => 0, |
|
271 |
+ 'null' => false, |
|
272 |
+ 'unsigned' => true, |
|
273 |
+ ), |
|
274 |
+ array( |
|
275 |
+ 'name' => 'modified_member', |
|
276 |
+ 'auto' => false, |
|
277 |
+ 'type' => 'mediumint', |
|
278 |
+ 'size' => 8, |
|
279 |
+ 'default' => 0, |
|
280 |
+ 'null' => false, |
|
281 |
+ 'unsigned' => true, |
|
282 |
+ ), |
|
283 |
+ array( |
|
284 |
+ 'name' => 'modified_name', |
|
285 |
+ 'auto' => false, |
|
286 |
+ 'type' => 'varchar', |
|
287 |
+ 'size' => 255, |
|
288 |
+ 'null' => false, |
|
289 |
+ ), |
|
290 |
+ array( |
|
291 |
+ 'name' => 'smileys_enabled', |
|
292 |
+ 'auto' => false, |
|
293 |
+ 'type' => 'tinyint', |
|
294 |
+ 'size' => 3, |
|
295 |
+ 'default' => 0, |
|
296 |
+ 'null' => false, |
|
297 |
+ ), |
|
298 |
+ array( |
|
299 |
+ 'name' => 'message_status', |
|
300 |
+ 'auto' => false, |
|
301 |
+ 'type' => 'tinyint', |
|
302 |
+ 'size' => 3, |
|
303 |
+ 'default' => 0, |
|
304 |
+ 'null' => false, |
|
305 |
+ ), |
|
306 |
+ ), |
|
307 |
+ 'indexes' => array( |
|
308 |
+ array( |
|
309 |
+ 'columns' => array('id_msg'), |
|
310 |
+ 'type' => 'primary', |
|
311 |
+ ), |
|
312 |
+ array( |
|
313 |
+ 'columns' => array('id_ticket', 'id_msg', 'message_status'), |
|
314 |
+ 'type' => 'index', |
|
315 |
+ ), |
|
316 |
+ ), |
|
317 |
+ 'if_exists' => 'update', |
|
318 |
+ 'error' => 'fatal', |
|
319 |
+ 'parameters' => array(), |
|
320 |
+); |
|
321 |
+$tables[] = array( |
|
322 |
+ 'table_name' => '{db_prefix}helpdesk_log_action', |
|
323 |
+ 'columns' => array( |
|
324 |
+ array( |
|
325 |
+ 'name' => 'id_action', |
|
326 |
+ 'auto' => true, |
|
327 |
+ 'type' => 'int', |
|
328 |
+ 'size' => 10, |
|
329 |
+ 'null' => false, |
|
330 |
+ 'unsigned' => true, |
|
331 |
+ ), |
|
332 |
+ array( |
|
333 |
+ 'name' => 'log_time', // when this happened |
|
334 |
+ 'auto' => false, |
|
335 |
+ 'type' => 'int', |
|
336 |
+ 'size' => 10, |
|
337 |
+ 'default' => 0, |
|
338 |
+ 'null' => false, |
|
339 |
+ 'unsigned' => true, |
|
340 |
+ ), |
|
341 |
+ array( |
|
342 |
+ 'name' => 'id_member', // person making the event |
|
343 |
+ 'auto' => false, |
|
344 |
+ 'type' => 'mediumint', |
|
345 |
+ 'size' => 8, |
|
346 |
+ 'default' => 0, |
|
347 |
+ 'null' => false, |
|
348 |
+ 'unsigned' => true, |
|
349 |
+ ), |
|
350 |
+ array( |
|
351 |
+ 'name' => 'ip', // member's IP |
|
352 |
+ 'auto' => false, |
|
353 |
+ 'type' => 'char', |
|
354 |
+ 'size' => 16, |
|
355 |
+ 'null' => false, |
|
356 |
+ ), |
|
357 |
+ array( |
|
358 |
+ 'name' => 'action', // defines the message to use |
|
359 |
+ 'auto' => false, |
|
360 |
+ 'type' => 'varchar', |
|
361 |
+ 'size' => 30, |
|
362 |
+ 'null' => false, |
|
363 |
+ ), |
|
364 |
+ array( |
|
365 |
+ 'name' => 'id_ticket', // ticket it applies to |
|
366 |
+ 'auto' => false, |
|
367 |
+ 'type' => 'mediumint', |
|
368 |
+ 'size' => 8, |
|
369 |
+ 'default' => 0, |
|
370 |
+ 'null' => false, |
|
371 |
+ ), |
|
372 |
+ array( |
|
373 |
+ 'name' => 'id_msg', // msg it applies to |
|
374 |
+ 'auto' => false, |
|
375 |
+ 'type' => 'int', |
|
376 |
+ 'size' => 10, |
|
377 |
+ 'default' => 0, |
|
378 |
+ 'null' => false, |
|
379 |
+ ), |
|
380 |
+ array( |
|
381 |
+ 'name' => 'extra', // serialised array of params for log message |
|
382 |
+ 'auto' => false, |
|
383 |
+ 'type' => 'mediumtext', |
|
384 |
+ 'null' => false, |
|
385 |
+ ), |
|
386 |
+ ), |
|
387 |
+ 'indexes' => array( |
|
388 |
+ array( |
|
389 |
+ 'columns' => array('id_action'), |
|
390 |
+ 'type' => 'primary', |
|
391 |
+ ), |
|
392 |
+ ), |
|
393 |
+ 'if_exists' => 'update', |
|
394 |
+ 'error' => 'fatal', |
|
395 |
+ 'parameters' => array(), |
|
396 |
+); |
|
397 |
+$tables[] = array( |
|
398 |
+ 'table_name' => '{db_prefix}helpdesk_log_read', |
|
399 |
+ 'columns' => array( |
|
400 |
+ array( |
|
401 |
+ 'name' => 'id_ticket', |
|
402 |
+ 'auto' => false, |
|
403 |
+ 'default' => 0, |
|
404 |
+ 'type' => 'mediumint', |
|
405 |
+ 'size' => 8, |
|
406 |
+ 'null' => false, |
|
407 |
+ 'unsigned' => true, |
|
408 |
+ ), |
|
409 |
+ array( |
|
410 |
+ 'name' => 'id_member', |
|
411 |
+ 'auto' => false, |
|
412 |
+ 'default' => 0, |
|
413 |
+ 'type' => 'mediumint', |
|
414 |
+ 'size' => 8, |
|
415 |
+ 'null' => false, |
|
416 |
+ 'unsigned' => true, |
|
417 |
+ ), |
|
418 |
+ array( |
|
419 |
+ 'name' => 'id_msg', |
|
420 |
+ 'auto' => false, |
|
421 |
+ 'default' => 0, |
|
422 |
+ 'type' => 'int', |
|
423 |
+ 'size' => 10, |
|
424 |
+ 'null' => false, |
|
425 |
+ 'unsigned' => true, |
|
426 |
+ ), |
|
427 |
+ ), |
|
428 |
+ 'indexes' => array( |
|
429 |
+ array( |
|
430 |
+ 'columns' => array('id_ticket', 'id_member'), |
|
431 |
+ 'type' => 'primary', |
|
432 |
+ ), |
|
433 |
+ ), |
|
434 |
+ 'if_exists' => 'update', |
|
435 |
+ 'error' => 'fatal', |
|
436 |
+ 'parameters' => array(), |
|
437 |
+); |
|
438 |
+$tables[] = array( |
|
439 |
+ 'table_name' => '{db_prefix}helpdesk_attachments', |
|
440 |
+ 'columns' => array( |
|
441 |
+ array( |
|
442 |
+ 'name' => 'id_attach', |
|
443 |
+ 'auto' => false, |
|
444 |
+ 'default' => 0, |
|
445 |
+ 'type' => 'int', |
|
446 |
+ 'size' => 10, |
|
447 |
+ 'null' => false, |
|
448 |
+ 'unsigned' => true, |
|
449 |
+ ), |
|
450 |
+ array( |
|
451 |
+ 'name' => 'id_ticket', |
|
452 |
+ 'auto' => false, |
|
453 |
+ 'default' => 0, |
|
454 |
+ 'type' => 'mediumint', |
|
455 |
+ 'size' => 8, |
|
456 |
+ 'null' => false, |
|
457 |
+ 'unsigned' => true, |
|
458 |
+ ), |
|
459 |
+ array( |
|
460 |
+ 'name' => 'id_msg', |
|
461 |
+ 'auto' => false, |
|
462 |
+ 'default' => 0, |
|
463 |
+ 'type' => 'int', |
|
464 |
+ 'size' => 10, |
|
465 |
+ 'null' => false, |
|
466 |
+ 'unsigned' => true, |
|
467 |
+ ), |
|
468 |
+ ), |
|
469 |
+ 'indexes' => array( |
|
470 |
+ array( |
|
471 |
+ 'columns' => array('id_attach'), |
|
472 |
+ 'type' => 'primary', |
|
473 |
+ ), |
|
474 |
+ ), |
|
475 |
+ 'if_exists' => 'update', |
|
476 |
+ 'error' => 'fatal', |
|
477 |
+ 'parameters' => array(), |
|
478 |
+); |
|
479 |
+ |
|
480 |
+// Oh joy, we've now made it to extra rows... (testing data) |
|
481 |
+$rows = array(); |
|
482 |
+ |
|
483 |
+// Now we can add a new column to an existing table |
|
484 |
+$columns = array(); |
|
485 |
+ |
|
486 |
+// Update mod settings if applicable |
|
487 |
+foreach ($mod_settings as $new_setting => $new_value) |
|
488 |
+{ |
|
489 |
+ if (empty($modSettings[$new_setting])) |
|
490 |
+ updateSettings(array($new_setting => $new_value)); |
|
491 |
+} |
|
492 |
+ |
|
493 |
+// Create new tables, if any |
|
494 |
+foreach ($tables as $table) |
|
495 |
+ $smcFunc['db_create_table']($table['table_name'], $table['columns'], $table['indexes'], $table['parameters'], $table['if_exists'], $table['error']); |
|
496 |
+ |
|
497 |
+// Create new rows, if any |
|
498 |
+foreach ($rows as $row) |
|
499 |
+ $smcFunc['db_insert']($row['method'], $row['table_name'], $row['columns'], $row['data'], $row['keys']); |
|
500 |
+ |
|
501 |
+// Create new columns, if any |
|
502 |
+foreach ($columns as $column) |
|
503 |
+ $smcFunc['db_add_column']($column['table_name'], $column['column_info'], $column['parameters'], $column['if_exists'], $column['error']); |
|
504 |
+ |
|
505 |
+// Are we done? |
|
506 |
+if (SMF == 'SSI') |
|
507 |
+ echo 'Database changes are complete!'; |
|
508 |
+?> |
|
0 | 509 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,282 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk.english.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+// Version: 1.0 Felidae; SimpleDesk main language file |
|
20 |
+ |
|
21 |
+// Important! Before editing these language files please read the text at the top of index.english.php. |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * This file contains all of the principle language strings used by SimpleDesk and are loaded on every page. |
|
25 |
+ * |
|
26 |
+ * @package language |
|
27 |
+ * @todo Document the text groups in this file. |
|
28 |
+ * @since 1.0 |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+$txt['shd_helpdesk'] = 'Helpdesk'; |
|
32 |
+ |
|
33 |
+//! @name Admininstration panel strings |
|
34 |
+//@{ |
|
35 |
+$txt['shd_admin_welcome'] = 'Welcome to the main helpdesk administration center!'; |
|
36 |
+$txt['shd_admin_title'] = 'Helpdesk Administration Center'; |
|
37 |
+$txt['shd_staff_list'] = 'Helpdesk staff'; |
|
38 |
+$txt['shd_update_available'] = 'New version available!'; |
|
39 |
+$txt['shd_update_message'] = 'A new version of SimpleDesk has been released. We recommened you to <a href="#" id="update-link">update to the latest version</a> in order to stay secure and enjoy all features our modification have to offer. |
|
40 |
+<span style="display: none;" id="information-link-span"><br />For more information on what is new in this release, please visit <a href="#" id="information-link" target="_blank">our website</a>.</span><br /> |
|
41 |
+<strong>The SimpleDesk Team</strong>'; |
|
42 |
+//@} |
|
43 |
+ |
|
44 |
+//! @name Urgency levels, ties to helpdesk_tickets.urgency |
|
45 |
+//@{ |
|
46 |
+$txt['shd_urgency_0'] = 'Low'; |
|
47 |
+$txt['shd_urgency_1'] = 'Medium'; |
|
48 |
+$txt['shd_urgency_2'] = 'High'; |
|
49 |
+$txt['shd_urgency_3'] = 'Very High'; |
|
50 |
+$txt['shd_urgency_4'] = 'Severe'; |
|
51 |
+$txt['shd_urgency_5'] = 'Critical'; |
|
52 |
+$txt['shd_urgency_increase'] = 'Increase'; |
|
53 |
+$txt['shd_urgency_decrease'] = 'Decrease'; |
|
54 |
+//@} |
|
55 |
+ |
|
56 |
+//! @name Status, ties to helpdesk_tickets.status |
|
57 |
+//@{ |
|
58 |
+$txt['shd_status_0'] = 'New'; |
|
59 |
+$txt['shd_status_1'] = 'Pending Staff Comment'; |
|
60 |
+$txt['shd_status_2'] = 'Pending User Comment'; |
|
61 |
+$txt['shd_status_3'] = 'Resolved/Closed'; |
|
62 |
+$txt['shd_status_4'] = 'Referred to Supervisor'; |
|
63 |
+$txt['shd_status_5'] = 'Escalated - Urgent'; |
|
64 |
+$txt['shd_status_6'] = 'Deleted'; |
|
65 |
+//@} |
|
66 |
+ |
|
67 |
+//! @name Headings, for the helpdesk listing pages |
|
68 |
+//@{ |
|
69 |
+$txt['shd_status_0_heading'] = 'New Tickets'; |
|
70 |
+$txt['shd_status_1_heading'] = 'Tickets Awaiting Staff Response'; |
|
71 |
+$txt['shd_status_2_heading'] = 'Tickets Awaiting User Response'; |
|
72 |
+$txt['shd_status_3_heading'] = 'Closed Tickets'; |
|
73 |
+$txt['shd_status_4_heading'] = 'Tickets Referred to Supervisor'; |
|
74 |
+$txt['shd_status_5_heading'] = 'Urgent Tickets'; |
|
75 |
+$txt['shd_status_6_heading'] = 'Recycled Tickets'; |
|
76 |
+$txt['shd_status_assigned_heading'] = 'Assigned to Me'; |
|
77 |
+$txt['shd_status_withdeleted_heading'] = 'Tickets with Deleted Replies'; |
|
78 |
+//@} |
|
79 |
+ |
|
80 |
+$txt['shd_tickets_open'] = 'Open Tickets'; |
|
81 |
+$txt['shd_tickets_closed'] = 'Closed Tickets'; |
|
82 |
+$txt['shd_tickets_recycled'] = 'Recycled Tickets'; |
|
83 |
+ |
|
84 |
+$txt['shd_assigned'] = 'Assigned'; |
|
85 |
+$txt['shd_unassigned'] = 'Unassigned'; |
|
86 |
+ |
|
87 |
+$txt['shd_read_ticket'] = 'Read Ticket'; |
|
88 |
+$txt['shd_unread_ticket'] = 'Unread Ticket'; |
|
89 |
+ |
|
90 |
+$txt['shd_owned'] = 'Owned Ticket'; // aka Assigned to Me |
|
91 |
+ |
|
92 |
+$txt['shd_count_ticket_1'] = 'ticket'; |
|
93 |
+$txt['shd_count_tickets'] = 'tickets'; |
|
94 |
+ |
|
95 |
+// Errors |
|
96 |
+$txt['cannot_access_helpdesk'] = 'You are not permitted to access the helpdesk.'; |
|
97 |
+$txt['shd_no_ticket'] = 'The ticket you have requested does not appear to exist.'; |
|
98 |
+$txt['shd_no_topic'] = 'The topic you have requested does not appaear to exist.'; |
|
99 |
+$txt['shd_ticket_no_perms'] = 'You do not have permission to view that ticket.'; |
|
100 |
+$txt['shd_error_no_tickets'] = 'No tickets were found.'; |
|
101 |
+$txt['shd_inactive'] = 'The helpdesk is currently deactivated.'; |
|
102 |
+$txt['shd_cannot_assign'] = 'You are not permitted to assign tickets.'; |
|
103 |
+$txt['shd_cannot_assign_other'] = 'This ticket is already assigned to another user. You cannot reassign it to yourself - please contact the administrator.'; |
|
104 |
+$txt['shd_no_staff_assign'] = 'There are no staff configured; it is not possible to assign a ticket. Please contact your administrator.'; |
|
105 |
+$txt['shd_assigned_not_permitted'] = 'The user you have requested to assign this ticket to does not have sufficient permissions to see it.'; |
|
106 |
+$txt['shd_cannot_resolve'] = 'You do not have permission to mark this ticket as resolved.'; |
|
107 |
+$txt['shd_cannot_change_privacy'] = 'You do not have permission to alter the privacy on this ticket.'; |
|
108 |
+$txt['shd_cannot_change_urgency'] = 'You do not have permission to alter the urgency on this ticket.'; |
|
109 |
+$txt['shd_ajax_problem'] = 'There was a problem attempting to load the page. Would you like to try again?'; |
|
110 |
+$txt['shd_cannot_move_ticket'] = 'You do not have permission to move this ticket to a topic.'; |
|
111 |
+$txt['shd_cannot_move_topic'] = 'You do not have permission to move this topic to a ticket.'; |
|
112 |
+$txt['shd_moveticket_noboards'] = 'There are no boards to move this ticket to!'; |
|
113 |
+$txt['shd_move_no_pm'] = 'You must enter a reason for moving the ticket to send to the ticket owner, or uncheck the option to \'send a PM to the ticket owner\'.'; |
|
114 |
+$txt['shd_move_no_pm_topic'] = 'You must enter a reason for moving the topic to send to the topic starter, or uncheck the option to \'send a PM to the topic starter\'.'; |
|
115 |
+$txt['shd_move_topic_not_created'] = 'Failed to move the ticket to the board. Please try again.'; |
|
116 |
+$txt['shd_move_ticket_not_created'] = 'Failed to move the topic to the helpdesk. Please try again.'; |
|
117 |
+$txt['shd_no_replies'] = 'This ticket does not have any replies yet.'; |
|
118 |
+$txt['cannot_shd_new_ticket'] = 'You do not have permission to create a new ticket.'; |
|
119 |
+$txt['cannot_shd_edit_ticket'] = 'You do not have permission to edit this ticket.'; |
|
120 |
+$txt['shd_cannot_reply_any'] = 'You do not have permission to reply to any tickets.'; |
|
121 |
+$txt['shd_cannot_reply_any_but_own'] = 'You do not have permission to reply to any tickets other than your own.'; |
|
122 |
+$txt['shd_cannot_edit_reply_any'] = 'You do not have permission to edit any replies.'; |
|
123 |
+$txt['shd_cannot_edit_reply_any_but_own'] = 'You do not have permission to edit replies to any tickets other than your own replies.'; |
|
124 |
+$txt['shd_cannot_edit_closed'] = 'You cannot edit resolved tickets; you need to mark it unresolved first.'; |
|
125 |
+$txt['shd_cannot_edit_deleted'] = 'You cannot edit tickets in the recycle bin. They will need to be restored first.'; |
|
126 |
+$txt['shd_cannot_reply_closed'] = 'You cannot reply to resolved tickets; you need to mark them unresolved first.'; |
|
127 |
+$txt['shd_cannot_reply_deleted'] = 'You cannot reply to tickets in the recycle bin. They will need to be restored first.'; |
|
128 |
+$txt['shd_cannot_delete_ticket'] = 'You are not permitted to delete this ticket.'; |
|
129 |
+$txt['shd_cannot_delete_reply'] = 'You are not permitted to delete that reply.'; |
|
130 |
+$txt['shd_cannot_restore_ticket'] = 'You are not permitted to restore this ticket from the recycle bin.'; |
|
131 |
+$txt['shd_cannot_restore_reply'] = 'You are not permitted to restore that reply from the recycle bin.'; |
|
132 |
+$txt['shd_cannot_view_resolved'] = 'You are not permitted to access resolved tickets.'; |
|
133 |
+$txt['cannot_shd_access_recyclebin'] = 'You cannot access the recycle bin.'; |
|
134 |
+$txt['shd_cannot_move_ticket_with_deleted'] = 'You cannot move this ticket to the forum; there are one or more deleted replies, which your current permissions do not permit access to.'; |
|
135 |
+$txt['shd_cannot_attach_ext'] = 'The type of file you have tried to attach ({ext}) is not allowed here. The allowed types of file are: {attach_exts}'; |
|
136 |
+ |
|
137 |
+// The main Helpdesk. |
|
138 |
+$txt['shd_home'] = 'Home'; |
|
139 |
+$txt['shd_new_ticket'] = 'Post New Ticket'; |
|
140 |
+$txt['shd_welcome'] = 'Welcome, %s!'; |
|
141 |
+$txt['shd_go'] = 'Go!'; |
|
142 |
+$txt['shd_go_to_ticket'] = 'Go to ticket'; |
|
143 |
+ |
|
144 |
+$txt['shd_user_greeting'] = 'Here you can file new tickets for the site staff to action, and check on current tickets already underway.'; |
|
145 |
+$txt['shd_staff_greeting'] = 'Here are all the tickets that require attention.'; |
|
146 |
+$txt['shd_shd_greeting'] = 'This is the Helpdesk. Here you waste your time to help newbies. Enjoy! ;D'; |
|
147 |
+$txt['shd_closed_user_greeting'] = 'These are all the closed/resolved tickets you have posted to the helpdesk.'; |
|
148 |
+$txt['shd_closed_staff_greeting'] = 'These are all closed/resolved tickets submitted to the helpdesk.'; |
|
149 |
+ |
|
150 |
+// The main ticket view. |
|
151 |
+$txt['shd_ticket_details'] = 'Ticket details'; |
|
152 |
+$txt['shd_ticket_updated'] = 'Updated'; |
|
153 |
+$txt['shd_ticket_id'] = 'Id'; |
|
154 |
+$txt['shd_ticket_name'] = 'Name'; |
|
155 |
+$txt['shd_ticket_user'] = 'User'; |
|
156 |
+$txt['shd_ticket_date'] = 'Posted'; |
|
157 |
+$txt['shd_ticket_urgency'] = 'Urgency'; |
|
158 |
+$txt['shd_ticket_assigned'] = 'Assigned'; |
|
159 |
+$txt['shd_ticket_assignedto'] = 'Assigned to'; |
|
160 |
+$txt['shd_ticket_started_by'] = 'Started by'; |
|
161 |
+$txt['shd_ticket_updated_by'] = 'Updated by'; |
|
162 |
+$txt['shd_ticket_status'] = 'Status'; |
|
163 |
+$txt['shd_ticket_num_replies'] = 'Replies'; |
|
164 |
+$txt['shd_ticket_replies'] = 'Replies'; |
|
165 |
+$txt['shd_ticket_staff'] = 'Staff member'; |
|
166 |
+$txt['shd_ticket_attachments'] = 'Attachments'; |
|
167 |
+$txt['shd_ticket_reply_number'] = 'Reply <strong>#%s</strong>'; // 'Reply #34' |
|
168 |
+$txt['shd_ticket'] = 'Ticket'; |
|
169 |
+$txt['shd_reply_written'] = 'Reply written %s'; // 'Reply written Today at 04:12:29 pm', 'Reply written January 5 2009 04:12:29 pm' |
|
170 |
+$txt['shd_never'] = 'Never'; |
|
171 |
+$txt['shd_linktree_tickets'] = 'Tickets'; |
|
172 |
+$txt['shd_ticket_privacy'] = 'Privacy'; |
|
173 |
+$txt['shd_ticket_notprivate'] = 'Not Private'; |
|
174 |
+$txt['shd_ticket_private'] = 'Private'; |
|
175 |
+$txt['shd_ticket_change'] = 'Change'; |
|
176 |
+$txt['shd_ticket_ip'] = 'IP address'; |
|
177 |
+$txt['shd_back_to_hd'] = 'Back to the helpdesk'; |
|
178 |
+ |
|
179 |
+$txt['shd_ticket_has_been_deleted'] = 'This ticket is currently in the recycle bin and cannot be altered without being returned to the helpdesk.'; |
|
180 |
+$txt['shd_ticket_replies_deleted'] = 'This ticket has had replies deleted from it previously.'; |
|
181 |
+$txt['shd_ticket_replies_deleted_view'] = 'These are displayed with a colored background. <a href="%1$s">View the ticket without deletions</a>.'; |
|
182 |
+$txt['shd_ticket_replies_deleted_link'] = 'Please <a href="%1$s">click here</a> to view them.'; |
|
183 |
+ |
|
184 |
+$txt['shd_ticket_notnew'] = 'You have already seen this'; |
|
185 |
+$txt['shd_ticket_new'] = 'New!'; |
|
186 |
+ |
|
187 |
+$txt['shd_linktree_move_ticket'] = 'Move ticket'; |
|
188 |
+$txt['shd_linktree_move_topic'] = 'Move topic to helpdesk'; |
|
189 |
+ |
|
190 |
+$txt['shd_cancel_ticket'] = 'Cancel and return to the ticket'; |
|
191 |
+$txt['shd_cancel_home'] = 'Cancel and return to the helpdesk home'; |
|
192 |
+$txt['shd_cancel_topic'] = 'Cancel and return to the topic'; |
|
193 |
+ |
|
194 |
+// Actions |
|
195 |
+$txt['shd_ticket_reply'] = 'Reply to ticket'; |
|
196 |
+$txt['shd_ticket_quote'] = 'Reply with quote'; |
|
197 |
+$txt['shd_go_advanced'] = 'Go advanced!'; |
|
198 |
+$txt['shd_ticket_edit_reply'] = 'Edit reply'; |
|
199 |
+$txt['shd_ticket_quote_short'] = 'Quote'; |
|
200 |
+$txt['shd_ticket_markunread'] = 'Mark as unread'; |
|
201 |
+$txt['shd_ticket_reply_short'] = 'Reply'; |
|
202 |
+$txt['shd_ticket_edit'] = 'Edit'; |
|
203 |
+$txt['shd_ticket_resolved'] = 'Mark resolved'; |
|
204 |
+$txt['shd_ticket_unresolved'] = 'Mark unresolved'; |
|
205 |
+$txt['shd_ticket_assign'] = 'Assign'; |
|
206 |
+$txt['shd_ticket_assign_self'] = 'Assign to me'; |
|
207 |
+$txt['shd_ticket_reassign'] = 'Re-Assign'; |
|
208 |
+$txt['shd_ticket_unassign'] = 'Un-Assign'; |
|
209 |
+$txt['shd_ticket_delete'] = 'Delete'; |
|
210 |
+$txt['shd_delete_confirm'] = 'Are you sure you want to delete this ticket? If deleted, this ticket will be moved to recycling bin.'; |
|
211 |
+$txt['shd_delete_reply_confirm'] = 'Are you sure you want to delete this reply? If deleted, this reply will be moved to the recycling bin.'; |
|
212 |
+$txt['shd_ticket_restore'] = 'Restore'; |
|
213 |
+$txt['shd_delete_permanently'] = 'Delete permanently'; |
|
214 |
+$txt['shd_delete_permanently_confirm'] = 'Are you sure you want to permanently delete this ticket? This CAN NOT be undone!'; |
|
215 |
+$txt['shd_ticket_move_to_topic'] = 'Move to topic'; |
|
216 |
+$txt['shd_actions'] = 'Actions'; |
|
217 |
+$txt['shd_back_to_ticket'] = 'Return to this ticket after posting'; |
|
218 |
+$txt['shd_disable_smileys_post'] = 'Turn off smileys in this post'; |
|
219 |
+ |
|
220 |
+$txt['shd_ticket_assign_ticket'] = 'Assign Ticket'; |
|
221 |
+$txt['shd_ticket_assign_to'] = 'Assign ticket to'; |
|
222 |
+ |
|
223 |
+// Ticket to topic and back |
|
224 |
+$txt['shd_move_ticket_to_topic'] = 'Move ticket to topic'; |
|
225 |
+$txt['shd_move_ticket'] = 'Move ticket'; |
|
226 |
+$txt['shd_ticket_board'] = 'Board'; |
|
227 |
+$txt['shd_move_send_pm'] = 'Send a PM to the ticket owner'; |
|
228 |
+$txt['shd_move_why'] = 'Please enter a brief description as to |
|
229 |
+why this ticket is being moved to a forum topic. '; |
|
230 |
+$txt['shd_ticket_moved_subject'] = 'Your ticket has been moved.'; |
|
231 |
+$txt['shd_move_default'] = 'Hello {user}, |
|
232 |
+ |
|
233 |
+Your ticket, {subject}, has been moved from the helpdesk to a topic in the forum. |
|
234 |
+You can find your ticket in the board {board} or via this link: |
|
235 |
+ |
|
236 |
+{link} |
|
237 |
+ |
|
238 |
+Thanks'; |
|
239 |
+ |
|
240 |
+$txt['shd_move_topic_to_ticket'] = 'Move topic to helpdesk'; |
|
241 |
+$txt['shd_move_topic'] = 'Move topic'; |
|
242 |
+$txt['shd_move_send_pm_topic'] = 'Send a PM to the topic starter'; |
|
243 |
+$txt['shd_move_why_topic'] = 'Please enter a brief description as to |
|
244 |
+why this topic is being moved to the helpdesk. '; |
|
245 |
+$txt['shd_ticket_moved_subject_topic'] = 'Your topic has been moved.'; |
|
246 |
+$txt['shd_move_default_topic'] = 'Hello {user}, |
|
247 |
+ |
|
248 |
+Your topic, {subject}, has been moved from the forum to the Helpdesk section. |
|
249 |
+You can find your topic via this link: |
|
250 |
+ |
|
251 |
+{link} |
|
252 |
+ |
|
253 |
+Thanks'; |
|
254 |
+ |
|
255 |
+$txt['shd_ticket_move_deleted'] = 'This ticket has replies that are currently in the recycle bin. What do you wish to do?'; |
|
256 |
+$txt['shd_ticket_move_deleted_abort'] = 'Abort, take me to the recycle bin'; |
|
257 |
+$txt['shd_ticket_move_deleted_delete'] = 'Continue, abandon the deleted replies (do not move them into the new topic)'; |
|
258 |
+$txt['shd_ticket_move_deleted_undelete'] = 'Continue, undelete the replies (move them into the new topic)'; |
|
259 |
+ |
|
260 |
+// Recycling |
|
261 |
+$txt['shd_recycle_bin'] = 'Recycle Bin'; |
|
262 |
+$txt['shd_recycle_greeting'] = 'This is the recycling bin. All deleted tickets go here, but staff members with special permissions can remove tickets permanently from here.'; |
|
263 |
+ |
|
264 |
+// Posting |
|
265 |
+$txt['shd_create_ticket'] = 'Create ticket'; |
|
266 |
+$txt['shd_edit_ticket'] = 'Edit ticket'; |
|
267 |
+$txt['shd_edit_ticket_linktree'] = 'Edit ticket (%s)'; |
|
268 |
+$txt['shd_ticket_subject'] = 'Ticket subject'; |
|
269 |
+$txt['shd_ticket_post_error'] = 'The following issue, or issues, occurred while trying to post this ticket'; |
|
270 |
+$txt['shd_reply_ticket'] = 'Reply to ticket'; |
|
271 |
+$txt['shd_reply_ticket_linktree'] = 'Reply to ticket (%s)'; |
|
272 |
+$txt['shd_edit_reply_linktree'] = 'Edit reply (%s)'; |
|
273 |
+$txt['shd_previewing_ticket'] = 'Previewing ticket'; |
|
274 |
+$txt['shd_previewing_reply'] = 'Previewing reply to'; |
|
275 |
+ |
|
276 |
+// Profile / trackip |
|
277 |
+$txt['shd_replies_from_ip'] = 'Helpdesk replies posted from IP (range)'; |
|
278 |
+$txt['shd_no_replies_from_ip'] = 'No helpdesk replies from the specified IP (range) found'; |
|
279 |
+$txt['shd_replies_from_ip_desc'] = 'Below is a list of all messages posted to the helpdesk from this IP (range).'; |
|
280 |
+$txt['shd_is_ticket_opener'] = ' (ticket starter)'; |
|
281 |
+ |
|
282 |
+?> |
|
0 | 283 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,198 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Admin.english.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+// Version: 1.0 Felidae; SimpleDesk administration options |
|
20 |
+ |
|
21 |
+// Important! Before editing these language files please read the text at the top of index.english.php. |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * This file contains all of the language strings used in SimpleDesk's administration panel which is loaded throughout the SMF admin area. |
|
25 |
+ * |
|
26 |
+ * @package language |
|
27 |
+ * @todo Document the text groups in this file. |
|
28 |
+ * @since 1.0 |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+//! @name The 'Core Features' page item |
|
32 |
+//@{ |
|
33 |
+$txt['core_settings_item_shd'] = 'Helpdesk'; |
|
34 |
+$txt['core_settings_item_shd_desc'] = 'The helpdesk allows you to expand your forum into the service industry by providing a dedicated user-staff helpdesk area.'; |
|
35 |
+//@} |
|
36 |
+ |
|
37 |
+//! @name Items for general SMF/ACP integration |
|
38 |
+//@{ |
|
39 |
+$txt['errortype_simpledesk'] = 'SimpleDesk'; |
|
40 |
+//@} |
|
41 |
+ |
|
42 |
+//! @name Items for the administration menu structure |
|
43 |
+//@{ |
|
44 |
+// Admin menu items |
|
45 |
+$txt['shd_admin_info'] = 'Information'; |
|
46 |
+$txt['shd_admin_options'] = 'Options'; |
|
47 |
+$txt['shd_admin_standalone_options'] = 'Standalone Mode'; |
|
48 |
+$txt['shd_admin_actionlog'] = 'Action Log'; |
|
49 |
+$txt['shd_admin_support'] = 'Support'; |
|
50 |
+$txt['shd_admin_helpdesklog'] = 'Helpdesk Log'; |
|
51 |
+ |
|
52 |
+$txt['shd_admin_options_display'] = 'Display Options'; |
|
53 |
+$txt['shd_admin_options_posting'] = 'Posting Options'; |
|
54 |
+$txt['shd_admin_options_admin'] = 'Administrative Options'; |
|
55 |
+$txt['shd_admin_options_standalone'] = 'Standalone Options'; |
|
56 |
+//@} |
|
57 |
+ |
|
58 |
+//! @name Descriptions for the page items. |
|
59 |
+//@{ |
|
60 |
+$txt['shd_admin_info_desc'] = 'This is the information center for the helpdesk, powered by SimpleDesk. Here you can get the latest news as well as version-specific support.'; |
|
61 |
+$txt['shd_admin_options_desc'] = 'This is the general configuration area for the helpdesk, where some basic options can be configured.'; |
|
62 |
+$txt['shd_admin_options_display_desc'] = 'In this area you can change some settings that will edit the display of your helpdesk.'; |
|
63 |
+$txt['shd_admin_options_posting_desc'] = 'Here you can edit posting settings, such as BBC, smileys, and attachments.'; |
|
64 |
+$txt['shd_admin_options_admin_desc'] = 'Here you can set some general administrative options for the helpdesk.'; |
|
65 |
+$txt['shd_admin_options_standalone_desc'] = 'This area manages the standalone mode for the helpdesk, that effectively disables the forum part of an SMF installation.'; |
|
66 |
+$txt['shd_admin_actionlog_desc'] = 'This is a list of all actions, such as resolved tickets, edited tickets and more, carried out in the helpdesk.'; |
|
67 |
+$txt['shd_admin_support_desc'] = 'This area will help you get through to SimpleDesk.net quickly and effectively - the post will include some information helpful for our Support team, about your installation (like SMF version and SimpleDesk version).'; |
|
68 |
+$txt['shd_admin_help'] = 'This is the administration panel for the helpdesk. Here you can manage settings, get news and updates on this modification, and view helpdesk logs.'; |
|
69 |
+//@} |
|
70 |
+ |
|
71 |
+//! @name SimpleDesk info center |
|
72 |
+//@{ |
|
73 |
+$txt['shd_live_from'] = 'Live from SimpleDesk.net'; |
|
74 |
+$txt['shd_no_connect'] = 'Could not retrieve news file from simpledesk.net'; |
|
75 |
+$txt['shd_current_version'] = 'Current Version'; |
|
76 |
+$txt['shd_your_version'] = 'Your Version'; |
|
77 |
+$txt['shd_mod_information'] = 'Mod Information'; |
|
78 |
+$txt['shd_admin_readmore'] = 'Read more'; |
|
79 |
+$txt['shd_admin_help_live'] = 'This box displays the latest news and updates from www.simpledesk.net. Keep your eyes open for new releases and bug fixes. If a new version of this modification is released, you will also see a notification at the top of the helpdesk administration page.'; |
|
80 |
+$txt['shd_admin_help_modification'] = 'This box contains various information about your installation of SimpleDesk.'; |
|
81 |
+$txt['shd_admin_help_credits'] = 'This box lists all of the people that made SimpleDesk possible, from the developers of the actual code, to the support team and the beta testers.'; |
|
82 |
+$txt['shd_admin_help_update'] = 'If you can see this box, you are most likely using an outdated version of SimpleDesk. Follow the guidelines in the notification in order to upgrade to the new release.'; |
|
83 |
+$txt['shd_ticket_information'] = 'Ticket information'; |
|
84 |
+$txt['shd_total_tickets'] = 'Total number of tickets'; |
|
85 |
+$txt['shd_open_tickets'] = 'Open tickets'; |
|
86 |
+$txt['shd_closed_tickets'] = 'Closed tickets'; |
|
87 |
+$txt['shd_recycled_tickets'] = 'Recycled tickets'; |
|
88 |
+//@} |
|
89 |
+ |
|
90 |
+//! @name Translatable strings for the credits |
|
91 |
+//@{ |
|
92 |
+$txt['shd_credits'] = 'SimpleDesk Credits'; |
|
93 |
+$txt['shd_credits_and'] = 'and'; |
|
94 |
+$txt['shd_credits_pretext'] = 'These are the persons that made SimpleDesk possible. Thank you!'; |
|
95 |
+$txt['shd_credits_devs'] = 'Developers'; |
|
96 |
+$txt['shd_credits_devs_desc'] = 'The developers of the actual SimpleDesk code.'; |
|
97 |
+$txt['shd_credits_projectsupport'] = 'Project Support'; |
|
98 |
+$txt['shd_credits_projectsupport_desc'] = 'Those managing and supporting the project in different ways.'; |
|
99 |
+$txt['shd_credits_marketing'] = 'Marketing'; |
|
100 |
+$txt['shd_credits_marketing_desc'] = 'Those spreading the word of SimpleDesk.'; |
|
101 |
+$txt['shd_credits_globalizer'] = 'Globalization'; |
|
102 |
+$txt['shd_credits_globalizer_desc'] = 'The people who makes SimpleDesk spread across the world.'; |
|
103 |
+$txt['shd_credits_support'] = 'Support'; |
|
104 |
+$txt['shd_credits_support_desc'] = 'The people providing all the helpless souls with the support they require.'; |
|
105 |
+$txt['shd_credits_qualityassurance'] = 'Quality Assurance'; |
|
106 |
+$txt['shd_credits_qualityassurance_desc'] = 'The leaders of the beta testing team.'; |
|
107 |
+$txt['shd_credits_beta'] = 'Beta Testers'; |
|
108 |
+$txt['shd_credits_beta_desc'] = 'These persons make sure SimpleDesk lives up to the expectations.'; |
|
109 |
+$txt['shd_credits_alltherest'] = 'Anyone else we might\'ve missed...'; |
|
110 |
+$txt['shd_credits_ledicons'] = 'Creator of the icons used by SimpleDesk'; |
|
111 |
+$txt['shd_credits_user'] = '<strong>YOU</strong>, the proud users of SimpleDesk. Thank you for choosing our software!'; |
|
112 |
+//@} |
|
113 |
+ |
|
114 |
+//! @name Configuration items on the Display Options page |
|
115 |
+//@{ |
|
116 |
+$txt['shd_staff_badge'] = 'What style of badges to use in ticket view?'; |
|
117 |
+$txt['shd_staff_badge_note'] = 'When looking at different replies, it may be helpful to display badges if you have different teams who may respond in the helpdesk. It may also be useful to display members\' own badges, or not; this option lets you select.'; |
|
118 |
+$txt['shd_staff_badge_nobadge'] = 'Display no badge, just a small icon for staff'; |
|
119 |
+$txt['shd_staff_badge_staffbadge'] = 'Display badges only of staff members'; |
|
120 |
+$txt['shd_staff_badge_userbadge'] = 'Display badges only of non-staff/regular users'; |
|
121 |
+$txt['shd_staff_badge_bothbadge'] = 'Display badges of both users and staff'; |
|
122 |
+$txt['shd_display_avatar'] = 'Display avatars in replies to a ticket?'; |
|
123 |
+$txt['shd_ticketnav_style'] = 'What type of navigation to use in the ticket view?'; |
|
124 |
+$txt['shd_ticketnav_style_note'] = 'When looking at tickets, there may be a number of options available to users, including edit, close, and delete. This option specifies the different ways this can look.'; |
|
125 |
+$txt['shd_ticketnav_style_sd'] = 'SimpleDesk style (icon with small text note)'; |
|
126 |
+$txt['shd_ticketnav_style_sdcompact'] = 'SimpleDesk style (icon only)'; |
|
127 |
+$txt['shd_ticketnav_style_smf'] = 'SMF style (text buttons, above the ticket)'; |
|
128 |
+//@} |
|
129 |
+ |
|
130 |
+//! @name Configuration items on the Posting Options page |
|
131 |
+//@{ |
|
132 |
+$txt['shd_allow_ticket_bbc'] = 'Allow tickets and replies to use bbcode'; |
|
133 |
+$txt['shd_allow_ticket_smileys'] = 'Allow tickets and replies to use smileys'; |
|
134 |
+$txt['shd_attachments_mode'] = 'How should attachments to tickets be treated?'; |
|
135 |
+$txt['shd_attachments_mode_ticket'] = 'As attached to the ticket'; |
|
136 |
+$txt['shd_attachments_mode_reply'] = 'As attached to individual replies'; |
|
137 |
+$txt['shd_attachments_mode_note'] = 'If using "to ticket" mode, there is no limit on the number of attachments, while if using "to replies", the helpdesk will use the same settings as regular attachments, by default 4 to a post only. Both modes check the size per attachment and that it will not fill up your attachments folder based on the settings in your attachments panel.'; |
|
138 |
+$txt['shd_bbc'] = 'Enabled BBC tags in the helpdesk'; |
|
139 |
+$txt['shd_bbc_desc'] = '<strong>If BBC is enabled above.</strong> What tags should be enabled for use in the helpdesk?'; |
|
140 |
+//@} |
|
141 |
+ |
|
142 |
+//! @name Configuration items on the Admin Options page |
|
143 |
+//@{ |
|
144 |
+$txt['shd_disable_action_log'] = 'Disable logging of helpdesk actions?'; |
|
145 |
+$txt['shd_staff_ticket_self'] = 'For tickets opened by staff, should it be possible to assign them the ticket?'; |
|
146 |
+$txt['shd_admins_not_assignable'] = 'Should admins be excluded from having tickets assigned to them?'; |
|
147 |
+$txt['shd_privacy_display'] = 'What method to use for displaying ticket privacy?'; |
|
148 |
+$txt['shd_privacy_display_smart'] = 'Display a ticket\'s privacy setting when appropriate'; |
|
149 |
+$txt['shd_privacy_display_always'] = 'Always display the ticket\'s privacy setting'; |
|
150 |
+$txt['shd_privacy_display_note'] = 'Normally tickets are limited to user seeing their own and staff seeing all users. There are times you might want staff to be able to create tickets only for senior staff to see - this is a "private" ticket. Since "non-private" might be confusing for regular users, this option allows you to hide the display of "non private" or "private" to only when it is appropriate on a ticket.'; |
|
151 |
+//@} |
|
152 |
+ |
|
153 |
+//! @name Configuration items on the Standalone Options page |
|
154 |
+//@{ |
|
155 |
+$txt['shd_helpdesk_only'] = 'Enable helpdesk only mode'; |
|
156 |
+$txt['shd_helpdesk_only_note'] = 'This will disable access to topics and boards, as well as optionally the features below. Note that none of the data is lost, merely rendered inactive. The following options ONLY apply when this mode is active (when the forum is basically disabled outside the helpdesk)'; |
|
157 |
+$txt['shd_disable_pm'] = 'Disable private messages entirely'; |
|
158 |
+$txt['shd_disable_mlist'] = 'Disable the memberlist entirely'; |
|
159 |
+//@} |
|
160 |
+ |
|
161 |
+//! @name General language strings for the action log (entries are contained in SimpleDesk-LogAction.english.php) |
|
162 |
+//@{ |
|
163 |
+$txt['shd_delete_item'] = 'Delete this log item'; |
|
164 |
+$txt['shd_admin_actionlog_title'] = 'Helpdesk action log'; |
|
165 |
+$txt['shd_admin_actionlog_action'] = 'Action'; |
|
166 |
+$txt['shd_admin_actionlog_date'] = 'Date'; |
|
167 |
+$txt['shd_admin_actionlog_member'] = 'Member'; |
|
168 |
+$txt['shd_admin_actionlog_position'] = 'Position'; |
|
169 |
+$txt['shd_admin_actionlog_ip'] = 'IP'; |
|
170 |
+$txt['shd_admin_actionlog_none'] = 'No entries were found.'; |
|
171 |
+$txt['shd_admin_actionlog_unknown'] = 'Unknown'; |
|
172 |
+$txt['shd_admin_actionlog_removeall'] = 'Empty out the entire log'; |
|
173 |
+$txt['shd_admin_actionlog_removeall_confirm'] = 'This will permanently delete all entries in the action log older than %s hours. Are you sure?'; |
|
174 |
+//@} |
|
175 |
+ |
|
176 |
+//! @name Strings for the post-to-SimpleDesk.net support page |
|
177 |
+//@{ |
|
178 |
+$txt['shd_admin_support_form_title'] = 'Support form'; |
|
179 |
+$txt['shd_admin_support_what_is_this'] = 'What is this?'; |
|
180 |
+$txt['shd_admin_support_explanation'] = 'This simple form will allow you to send a support request directly to the SimpleDesk website so that the support team there can help you solve any issue you run in to.<br /><br />Please note that you will need an account on our website in order to post as well as replying to your topic in the future. This form will simply speed up the posting process.'; |
|
181 |
+$txt['shd_admin_support_send'] = 'Send support request'; |
|
182 |
+//@} |
|
183 |
+ |
|
184 |
+//! @name The browse-attachments integration strings |
|
185 |
+//@{ |
|
186 |
+$txt['attachment_manager_shd_attach'] = 'Helpdesk attachments'; |
|
187 |
+$txt['attachment_manager_shd_thumb'] = 'Helpdesk thumbnails'; |
|
188 |
+$txt['attachment_manager_shd_attach_no_entries'] = 'There are currently no helpdesk attachments.'; |
|
189 |
+$txt['attachment_manager_shd_thumb_no_entries'] = 'There are currently no helpdesk thumbnails.'; |
|
190 |
+//@} |
|
191 |
+ |
|
192 |
+/** |
|
193 |
+ * @ignore |
|
194 |
+ * Warning: He may bite. |
|
195 |
+*/ |
|
196 |
+$txt['shd_fluffy'] = 'Guardian of the <span %s>cookies</span>'; |
|
197 |
+ |
|
198 |
+?> |
|
0 | 199 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,78 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-LogAction.english.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+// Version: 1.0 Felidae; SimpleDesk action log |
|
20 |
+ |
|
21 |
+// Important! Before editing these language files please read the text at the top of index.english.php. |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * This file contains all of the base language strings used by the helpdesk action log. |
|
25 |
+ * Unlike other language files, many of the strings here are parameterised, enabling them to be extended in the future. |
|
26 |
+ * @see shd_log_action() |
|
27 |
+ * |
|
28 |
+ * @package language |
|
29 |
+ * @todo Document the text groups in this file. |
|
30 |
+ * @since 1.0 |
|
31 |
+ */ |
|
32 |
+ |
|
33 |
+//! @name General strings |
|
34 |
+//@{ |
|
35 |
+$txt['shd_action_log_disabled'] = '<strong>Note:</strong> Logging of actions is currently <strong>disabled</strong>, so no new log entries will be added.'; |
|
36 |
+//@} |
|
37 |
+ |
|
38 |
+//! @name Ticket resolution |
|
39 |
+//@{ |
|
40 |
+$txt['shd_log_resolve'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> marked as <strong>resolved</strong>.'; |
|
41 |
+$txt['shd_log_unresolve'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> marked as <strong>not yet resolved</strong>.'; |
|
42 |
+//@} |
|
43 |
+ |
|
44 |
+//! @name Ticket assignation |
|
45 |
+//@{ |
|
46 |
+$txt['shd_log_assign'] = 'Assigned <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> to {profile_link}'; |
|
47 |
+$txt['shd_log_unassign'] = 'Assigned <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> to no-one'; |
|
48 |
+//@} |
|
49 |
+ |
|
50 |
+//! @name Ticket privacy |
|
51 |
+//@{ |
|
52 |
+$txt['shd_log_markprivate'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> marked as <strong>private</strong>.'; |
|
53 |
+$txt['shd_log_marknotprivate'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> marked as <strong>not private</strong>.'; |
|
54 |
+//@} |
|
55 |
+ |
|
56 |
+//! @name Ticket urgency |
|
57 |
+//@{ |
|
58 |
+$txt['shd_log_urgency_increase'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> increased to <strong>{urgency}</strong>.'; |
|
59 |
+$txt['shd_log_urgency_decrease'] = '<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a> decreased to <strong>{urgency}</strong>.'; |
|
60 |
+//@} |
|
61 |
+ |
|
62 |
+//! @name Ticket/topic, topic/ticket moves |
|
63 |
+//@{ |
|
64 |
+$txt['shd_log_tickettotopic'] = 'Moved <a href="{scripturl}?topic={ticket}.0">{subject}</a> to <strong><a href="{scripturl}?board={board_id}.0">{board_name}</a></strong> in the forum'; |
|
65 |
+$txt['shd_log_topictoticket'] = 'Moved the topic <strong><a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a></strong> from the forum to the helpdesk.'; |
|
66 |
+//@} |
|
67 |
+ |
|
68 |
+//! @name Ticket deletion, restoration, permadeletion |
|
69 |
+//@{ |
|
70 |
+$txt['shd_log_delete'] = 'Deleted <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}.0">{subject}</a> to recycle bin.'; |
|
71 |
+$txt['shd_log_restore'] = 'Restored <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}.0">{subject}</a> from recycle bin.'; |
|
72 |
+$txt['shd_log_permadelete'] = '<strong>Permanently</strong> deleted "{subject}" (ticket {ticket}).'; |
|
73 |
+$txt['shd_log_delete_reply'] = 'Deleted reply in <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}.msg{msg}#msg{msg};recycle">{subject}</a> to recycle bin.'; |
|
74 |
+$txt['shd_log_restore_reply'] = 'Restored reply in <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}.msg{msg}#msg{msg}">{subject}</a> from recycle bin.'; |
|
75 |
+$txt['shd_log_permadelete_reply'] = '<strong>Permanently</strong> deleted a reply from <a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a>.'; |
|
76 |
+//@} |
|
77 |
+ |
|
78 |
+?> |
|
0 | 79 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,253 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Permissions.english.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+// Version: 1.0 Felidae; SimpleDesk permissions |
|
20 |
+ |
|
21 |
+// Important! Before editing these language files please read the text at the top of index.english.php. |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * This file contains all of the language strings (both main description and help text) for all permissions that SimpleDesk adds to the |
|
25 |
+ * permissions pages. Note that both classic and simple view are accounted for, explaining the large number of strings per permission. |
|
26 |
+ * |
|
27 |
+ * @package language |
|
28 |
+ * @todo Document the text groups in this file. |
|
29 |
+ * @since 1.0 |
|
30 |
+ */ |
|
31 |
+ |
|
32 |
+//! @name Permission groups |
|
33 |
+//@{ |
|
34 |
+$txt['permissiongroup_helpdesk'] = 'Helpdesk permissions'; |
|
35 |
+$txt['permissiongroup_simple_use_helpdesk'] = 'Permissions to use the helpdesk system'; |
|
36 |
+ |
|
37 |
+$txt['permissiongroup_shd_staff'] = 'Helpdesk staff permissions'; |
|
38 |
+$txt['permissiongroup_simple_shd_staff'] = 'Permissions for staff users of the helpdesk'; |
|
39 |
+ |
|
40 |
+$txt['permissiongroup_shd_admin'] = 'Helpdesk administration'; |
|
41 |
+$txt['permissiongroup_simple_shd_admin'] = 'Permissions for administrating the helpdesk'; |
|
42 |
+//@} |
|
43 |
+ |
|
44 |
+//! @name General permissions |
|
45 |
+//@{ |
|
46 |
+$txt['permissionname_access_helpdesk'] = 'Access the helpdesk'; |
|
47 |
+$txt['permissionhelp_access_helpdesk'] = 'This permission allows users to even see the helpdesk, and is required to do anything within the helpdesk; is available in the event of banning someone from the helpdesk.'; |
|
48 |
+$txt['permissionname_admin_helpdesk'] = 'Administrate the helpdesk (allows reconfiguration)'; |
|
49 |
+$txt['permissionhelp_admin_helpdesk'] = 'This permission controls whether administrative functions of the helpdesk can be passed on to users who are not administrators of the forum; typically senior associates/helpdesk agents would have this.'; |
|
50 |
+$txt['permissionname_shd_staff'] = 'Treat this user group as helpdesk staff'; |
|
51 |
+$txt['permissionhelp_shd_staff'] = 'Users with this permission will be treated as staff. Amongst other things, this grants the ability to reply to any ticket that is not owned by the starter.'; |
|
52 |
+//@} |
|
53 |
+ |
|
54 |
+//! @name Ticket visibility: general |
|
55 |
+//@{ |
|
56 |
+$txt['permissionname_shd_view_ticket'] = 'View helpdesk tickets'; |
|
57 |
+$txt['permissionhelp_shd_view_ticket'] = 'This permission controls whether users can see tickets at all, and more importantly whether they have access to the standard user view or the staff level view; users with the ability to view any are generally considered to be staff.'; |
|
58 |
+$txt['permissionname_shd_view_ticket_own'] = 'Own tickets'; |
|
59 |
+$txt['permissionname_shd_view_ticket_any'] = 'Any tickets'; |
|
60 |
+$txt['permissionname_simple_shd_view_ticket_own'] = 'Allow users to view their own public tickets'; |
|
61 |
+$txt['permissionhelp_simple_shd_view_ticket_own'] = 'This permission allows regular users to see their own tickets, but only those not marked private.'; |
|
62 |
+$txt['permissionname_simple_shd_view_ticket_any'] = 'Allow users to view all public helpdesk tickets'; |
|
63 |
+$txt['permissionhelp_simple_shd_view_ticket_any'] = 'This permission allows users to see any normal ticket on the helpdesk.'; |
|
64 |
+//@} |
|
65 |
+ |
|
66 |
+//! @name Ticket visibility: privacy |
|
67 |
+//@{ |
|
68 |
+$txt['permissionname_shd_view_ticket_private'] = 'View private helpdesk tickets'; |
|
69 |
+$txt['permissionhelp_shd_view_ticket_private'] = 'This permission controls whether tickets that are marked private can be seen by users, for example, you could use this permission for staff members who want to post a ticket that concerns them, without it being visible to all staff - only senior staff.'; |
|
70 |
+$txt['permissionname_shd_view_ticket_private_own'] = 'Own private tickets'; |
|
71 |
+$txt['permissionname_shd_view_ticket_private_any'] = 'Any users\' private tickets'; |
|
72 |
+$txt['permissionname_simple_shd_view_ticket_private_own'] = 'Allow users to view their own private tickets'; |
|
73 |
+$txt['permissionhelp_simple_shd_view_ticket_private_own'] = 'This permission allows users to see their own private tickets.'; |
|
74 |
+$txt['permissionname_simple_shd_view_ticket_private_any'] = 'Allow users to view all private tickets'; |
|
75 |
+$txt['permissionhelp_simple_shd_view_ticket_private_any'] = 'This permission allows users to see all of the private tickets, in addition to any other permissions they have. Recommended for senior staff.'; |
|
76 |
+//@} |
|
77 |
+ |
|
78 |
+//! @name Ticket modifications: privacy |
|
79 |
+//@{ |
|
80 |
+$txt['permissionname_shd_alter_privacy'] = 'Allow users to alter the privacy on a ticket'; |
|
81 |
+$txt['permissionhelp_shd_alter_privacy'] = 'This permission allows a user to change the privacy on a ticket, from public to private and back. Actual ticket editing permission is not required to use this.'; |
|
82 |
+$txt['permissionname_shd_alter_privacy_own'] = 'Own tickets'; |
|
83 |
+$txt['permissionname_shd_alter_privacy_any'] = 'Any tickets'; |
|
84 |
+$txt['permissionname_simple_shd_alter_privacy_own'] = 'Allow users to mark their own tickets as private/public'; |
|
85 |
+$txt['permissionhelp_simple_shd_alter_privacy_own'] = 'This allows users to flag their own tickets as private or public, in line with the ability to view private tickets system. (This does not require the ability to edit ticket details.)'; |
|
86 |
+$txt['permissionname_simple_shd_alter_privacy_any'] = 'Allow users to mark their any tickets as private/public'; |
|
87 |
+$txt['permissionhelp_simple_shd_alter_privacy_any'] = 'This allows users to flag any users\' tickets as private or public, in line with the ability to view private tickets system. (This does not require the ability to edit ticket details.)'; |
|
88 |
+//@} |
|
89 |
+ |
|
90 |
+//! @name Ticket modifications: urgency |
|
91 |
+//@{ |
|
92 |
+$txt['permissionname_shd_alter_urgency'] = 'Allow users to alter the urgency of tickets'; |
|
93 |
+$txt['permissionhelp_shd_alter_urgency'] = 'Tickets are available in a range of "urgency" levels: Low, Medium, High, Very High, Severe, Critical. This permission allows users to raise and lower urgency up to the level of High (and lower from Very High back to High only)'; |
|
94 |
+$txt['permissionname_shd_alter_urgency_own'] = 'Own tickets'; |
|
95 |
+$txt['permissionname_shd_alter_urgency_any'] = 'Any tickets'; |
|
96 |
+$txt['permissionname_simple_shd_alter_urgency_own'] = 'Allow users to raise or lower the urgency of their own tickets'; |
|
97 |
+$txt['permissionhelp_simple_shd_alter_urgency_own'] = 'Tickets are available in a range of "urgency" levels: Low, Medium, High, Very High, Severe, Critical. This permission allows users to raise and lower urgency of their own tickets up to the level of High (and lower from Very High back to High only)'; |
|
98 |
+$txt['permissionname_simple_shd_alter_urgency_any'] = 'Allow users to raise or lower the urgency of any tickets'; |
|
99 |
+$txt['permissionhelp_simple_shd_alter_urgency_any'] = 'Tickets are available in a range of "urgency" levels: Low, Medium, High, Very High, Severe, Critical. This permission allows users to raise and lower urgency of any tickets in the helpdesk up to the level of High (and lower from Very High back to High only)'; |
|
100 |
+$txt['permissionname_shd_alter_urgency_higher'] = 'Allow user to set urgency "Very High" or above'; |
|
101 |
+$txt['permissionhelp_shd_alter_urgency_higher'] = 'This permission extends the above permission, and allows users to be able to select the highest levels of urgency for a ticket. Generally this would be assigned by staff only.'; |
|
102 |
+$txt['permissionname_shd_alter_urgency_higher_own'] = 'Own tickets'; |
|
103 |
+$txt['permissionname_shd_alter_urgency_higher_any'] = 'Any tickets'; |
|
104 |
+$txt['permissionname_simple_shd_alter_urgency_higher_own'] = 'Allow users to set the urgency of their own tickets to "Very High" or above'; |
|
105 |
+$txt['permissionhelp_simple_shd_alter_urgency_higher_any'] = 'Urgency of tickets is split into two tiers, Low/Medium/High, and Very High/Severe/Critical. This permission allows users to flag their own tickets higher than High.'; |
|
106 |
+$txt['permissionname_simple_shd_alter_urgency_higher_any'] = 'Allow users to set the urgency of any tickets to "Very High" or above'; |
|
107 |
+$txt['permissionhelp_simple_shd_alter_urgency_higher_any'] = 'Urgency of tickets is split into two tiers, Low/Medium/High, and Very High/Severe/Critical. This permission allows users to flag any tickets more urgent than High urgency.'; |
|
108 |
+//@} |
|
109 |
+ |
|
110 |
+//! @name Ticket modification: assignment |
|
111 |
+//@{ |
|
112 |
+$txt['permissionname_shd_assign_ticket'] = 'Allow users to assign a ticket'; |
|
113 |
+$txt['permissionhelp_shd_assign_ticket'] = 'This permission allows users to assign tickets to staff to be dealt with; normally would be given to staff to assign tickets to themselves, or to managers to assign to other users'; |
|
114 |
+$txt['permissionname_shd_assign_ticket_own'] = 'To themselves'; |
|
115 |
+$txt['permissionname_shd_assign_ticket_any'] = 'Any staff member'; |
|
116 |
+$txt['permissionname_simple_shd_assign_ticket_own'] = 'Allow users to assign tickets to themselves'; |
|
117 |
+$txt['permissionhelp_simple_shd_assign_ticket_own'] = 'This permission allows a user to assign a ticket to themselves for resolution. Would be useful for lower-level staff.'; |
|
118 |
+$txt['permissionname_simple_shd_assign_ticket_any'] = 'Allow users to assign tickets to any staff memmber'; |
|
119 |
+$txt['permissionhelp_simple_shd_assign_ticket_any'] = 'This permission allows a user to assign a ticket to any staff member, including themselves. Certainly higher level staff would normally have access, but for smaller numbers of staff, all may be granted permission to use it.'; |
|
120 |
+//@} |
|
121 |
+ |
|
122 |
+//! @name Ticket modification: resolution |
|
123 |
+//@{ |
|
124 |
+$txt['permissionname_shd_resolve_ticket'] = 'Allow users to mark a ticket as resolved'; |
|
125 |
+$txt['permissionhelp_shd_resolve_ticket'] = 'This permission allows users to mark tickets resolved, and mark completed tickets as unresolved if there is further business to attend to.'; |
|
126 |
+$txt['permissionname_shd_resolve_ticket_own'] = 'Own tickets'; |
|
127 |
+$txt['permissionname_shd_resolve_ticket_any'] = 'Any tickets'; |
|
128 |
+$txt['permissionname_simple_shd_resolve_ticket_own'] = 'Allow users to mark their own tickets as resolved'; |
|
129 |
+$txt['permissionhelp_simple_shd_resolve_ticket_own'] = 'This permission allows a user to mark their own tickets as resolved, and additionally to mark any completed tickets as unresolved if further things need to be attended to.'; |
|
130 |
+$txt['permissionname_simple_shd_resolve_ticket_any'] = 'Allow users to mark any ticket as resolved'; |
|
131 |
+$txt['permissionhelp_simple_shd_resolve_ticket_any'] = 'This permission allows a user to mark any ticket as resolved, and additionally reopen any already-resolved ticket.'; |
|
132 |
+//@} |
|
133 |
+ |
|
134 |
+//! @name Ticket posting: new ticket |
|
135 |
+//@{ |
|
136 |
+$txt['permissionname_shd_new_ticket'] = 'Allow users to post a new ticket'; |
|
137 |
+$txt['permissionhelp_shd_new_ticket'] = 'This permission allows users in this membergroup to file new tickets for themselves.'; |
|
138 |
+//@} |
|
139 |
+ |
|
140 |
+//! @name Ticket posting: replies |
|
141 |
+//@{ |
|
142 |
+$txt['permissionname_shd_reply_ticket'] = 'Allow users to reply to tickets'; |
|
143 |
+$txt['permissionhelp_shd_reply_ticket'] = 'This permission allows users to reply to tickets, either to provide further details, or to provide an answer.'; |
|
144 |
+$txt['permissionname_shd_reply_ticket_own'] = 'Own tickets'; |
|
145 |
+$txt['permissionname_shd_reply_ticket_any'] = 'Any tickets'; |
|
146 |
+$txt['permissionname_simple_shd_reply_ticket_own'] = 'Allow users to reply to their own tickets'; |
|
147 |
+$txt['permissionhelp_simple_shd_reply_ticket_own'] = 'This permission allows a user to reply to tickets that they have started. You would normally grant this to membergroups who can start tickets, as it allows them to reply to staff comments.'; |
|
148 |
+$txt['permissionname_simple_shd_reply_ticket_any'] = 'Allow users to reply to any ticket'; |
|
149 |
+$txt['permissionhelp_simple_shd_reply_ticket_any'] = 'This permission allows a user to reply to any ticket they have access to (see the permissions about being able to view tickets). This would normally be granted to membergroups that are considered staff.'; |
|
150 |
+//@} |
|
151 |
+ |
|
152 |
+//! @name Ticket posting: editing a ticket |
|
153 |
+//@{ |
|
154 |
+$txt['permissionname_shd_edit_ticket'] = 'Allow users to edit the ticket details'; |
|
155 |
+$txt['permissionhelp_shd_edit_ticket'] = 'This permission allows a user to edit the core details of a ticket, such as the ticket\'s name and initial description.'; |
|
156 |
+$txt['permissionname_shd_edit_ticket_own'] = 'Own tickets'; |
|
157 |
+$txt['permissionname_shd_edit_ticket_any'] = 'Any tickets'; |
|
158 |
+$txt['permissionname_simple_shd_edit_ticket_own'] = 'Allow users to edit their own tickets\' details'; |
|
159 |
+$txt['permissionhelp_simple_shd_edit_ticket_own'] = 'This permission allows a user to edit the basic ticket details of their own tickets, the title and body contents.'; |
|
160 |
+$txt['permissionname_simple_shd_edit_ticket_any'] = 'Allow users to edit any ticket\'s details'; |
|
161 |
+$txt['permissionhelp_simple_shd_edit_ticket_any'] = 'This permission allows a user to edit the basic ticket details (title and body contents) of any ticket.'; |
|
162 |
+//@} |
|
163 |
+ |
|
164 |
+//! @name Ticket posting: editing replies |
|
165 |
+//@{ |
|
166 |
+$txt['permissionname_shd_edit_reply'] = 'Allow users to edit replies in tickets'; |
|
167 |
+$txt['permissionhelp_shd_edit_reply'] = 'This permission allows a user to edit replies in tickets, not the main ticket itself.'; |
|
168 |
+$txt['permissionname_shd_edit_reply_own'] = 'Own replies'; |
|
169 |
+$txt['permissionname_shd_edit_reply_any'] = 'Any replies'; |
|
170 |
+$txt['permissionname_simple_shd_edit_reply_own'] = 'Allow users to edit their own replies to tickets'; |
|
171 |
+$txt['permissionhelp_simple_shd_edit_reply_own'] = 'This permission allows users to update the contents of replies they make to tickets.'; |
|
172 |
+$txt['permissionname_simple_shd_edit_reply_any'] = 'Allow users to edit any tickets and posts'; |
|
173 |
+$txt['permissionhelp_simple_shd_edit_reply_any'] = 'This permission allows users to update the contents of any replies to any tickets they have access to.'; |
|
174 |
+//@} |
|
175 |
+ |
|
176 |
+//! @name Ticket deletion: tickets |
|
177 |
+//@{ |
|
178 |
+$txt['permissionname_shd_delete_ticket'] = 'Allow users to delete a ticket'; |
|
179 |
+$txt['permissionhelp_shd_delete_ticket'] = 'This permission allows a user to delete a ticket.'; |
|
180 |
+$txt['permissionname_shd_delete_ticket_own'] = 'Own tickets'; |
|
181 |
+$txt['permissionname_shd_delete_ticket_any'] = 'Any tickets'; |
|
182 |
+$txt['permissionname_simple_shd_delete_ticket_own'] = 'Allow users to delete their own tickets'; |
|
183 |
+$txt['permissionhelp_simple_shd_delete_ticket_own'] = 'This permission allows a user to delete their own tickets. Note that this is not a permanent deletion - all "deleted" tickets are moved to a recycle bin.'; |
|
184 |
+$txt['permissionname_simple_shd_delete_ticket_any'] = 'Allow users to delete any tickets'; |
|
185 |
+$txt['permissionhelp_simple_shd_delete_ticket_any'] = 'This permission allows a user to delete their own tickets. Note that this is not a permanent deletion - all "deleted" tickets are moved to a recycle bin.'; |
|
186 |
+//@} |
|
187 |
+ |
|
188 |
+//! @name Ticket deletion: replies |
|
189 |
+//@{ |
|
190 |
+$txt['permissionname_shd_delete_reply'] = 'Allow users to delete replies in tickets'; |
|
191 |
+$txt['permissionhelp_shd_delete_reply'] = 'This permission allows a user to delete replies in tickets, not the main ticket itself.'; |
|
192 |
+$txt['permissionname_shd_delete_reply_own'] = 'Own replies'; |
|
193 |
+$txt['permissionname_shd_delete_reply_any'] = 'Any replies'; |
|
194 |
+$txt['permissionname_simple_shd_delete_reply_own'] = 'Allow users to delete their own replies to tickets'; |
|
195 |
+$txt['permissionhelp_simple_shd_delete_reply_own'] = 'This permission allows users to remove any replies they have made to a ticket. Note that this is not a permanent deletion - all "deleted" tickets are moved to a recycle bin.'; |
|
196 |
+$txt['permissionname_simple_shd_delete_reply_any'] = 'Allow users to delete any replies to tickets'; |
|
197 |
+$txt['permissionhelp_simple_shd_delete_reply_any'] = 'This permission allows users to the replies of any user to any ticket they can access. Note that this is not a permanent deletion - all "deleted" tickets are moved to a recycle bin.'; |
|
198 |
+//@} |
|
199 |
+ |
|
200 |
+//! @name Ticket deletion: permadelete |
|
201 |
+//@{ |
|
202 |
+$txt['permissionname_shd_delete_recycling'] = 'Delete tickets/posts from recycling'; |
|
203 |
+$txt['permissionhelp_shd_delete_recycling'] = 'This permission allows users to remove tickets and posts from the recycling area. Note that once removed here, they are NOT recoverable, as such it is not recommended to grant this permission to all staff.'; |
|
204 |
+//@} |
|
205 |
+ |
|
206 |
+//! @name Ticket deletion: accessing recycle bin |
|
207 |
+//@{ |
|
208 |
+$txt['permissionname_shd_access_recyclebin'] = 'Access recycling bin'; |
|
209 |
+$txt['permissionhelp_shd_access_recyclebin'] = 'Users with this permission will be able to access the list of recycled tickets and read the tickets.'; |
|
210 |
+//@} |
|
211 |
+ |
|
212 |
+//! @name Ticket deletion: restoration of tickets |
|
213 |
+//@{ |
|
214 |
+$txt['permissionname_shd_restore_ticket'] = 'Allow user to restore tickets from the recycling bin'; |
|
215 |
+$txt['permissionhelp_shd_restore_ticket'] = 'This permission allows a user to restore deleted tickets from the recycling bin.'; |
|
216 |
+$txt['permissionname_shd_restore_ticket_own'] = 'Own tickets'; |
|
217 |
+$txt['permissionname_shd_restore_ticket_any'] = 'Any tickets'; |
|
218 |
+$txt['permissionname_simple_shd_restore_ticket_own'] = 'Allow users to restore their own tickets from recycling'; |
|
219 |
+$txt['permissionhelp_simple_shd_restore_ticket_own'] = 'When tickets are deleted, they are not normally deleted permanently, just saved in a recycling area, from which users can recover them until the administrator or suitably privileged user can delete them (see "permanently delete"). This permission allows users to recover their own tickets out of the recycling area.'; |
|
220 |
+$txt['permissionname_simple_shd_restore_ticket_any'] = 'Allow users to restore any tickets from recycling'; |
|
221 |
+$txt['permissionhelp_simple_shd_restore_ticket_any'] = 'When tickets are deleted, they are not normally deleted permanently, just saved in a recycling area, from which users can recover them until the administrator or suitably privileged user can delete them (see "permanently delete"). This permission allows users to recover any tickets they would have access to out of the recycling area.'; |
|
222 |
+//@} |
|
223 |
+ |
|
224 |
+//! @name Ticket deletion: restoration of replies |
|
225 |
+//@{ |
|
226 |
+$txt['permissionname_shd_restore_reply'] = 'Allow user to restore replies in deleted tickets from the recycling bin'; |
|
227 |
+$txt['permissionhelp_shd_restore_reply'] = 'This permission allows a user to restore deleted replies from the recycling bin.'; |
|
228 |
+$txt['permissionname_shd_restore_reply_own'] = 'Own replies'; |
|
229 |
+$txt['permissionname_shd_restore_reply_any'] = 'Any replies'; |
|
230 |
+$txt['permissionname_simple_shd_restore_reply_own'] = 'Allow users to restore their own replies in tickets from recycling'; |
|
231 |
+$txt['permissionhelp_simple_shd_restore_reply_own'] = 'When tickets are deleted, they are not normally deleted permanently, just saved in a recycling area, from which users can recover them until the administrator or suitably privileged user can delete them (see "permanently delete"). This permission allows users to recover replies to tickets - their own replies, note, from tickets out of the recycling area.'; |
|
232 |
+$txt['permissionname_simple_shd_restore_reply_any'] = 'Allow users to restore any replies from tickets in recycling'; |
|
233 |
+$txt['permissionhelp_simple_shd_restore_reply_any'] = 'When tickets are deleted, they are not normally deleted permanently, just saved in a recycling area, from which users can recover them until the administrator or suitably privileged user can delete them (see "permanently delete"). This permission allows users to recover any replies back to regular tickets, from tickets they would have access to out of the recycling area.'; |
|
234 |
+//@} |
|
235 |
+ |
|
236 |
+//! @name Attachments |
|
237 |
+//@{ |
|
238 |
+$txt['permissionname_shd_post_attachment'] = 'Allow users to post attachments'; |
|
239 |
+$txt['permissionhelp_shd_post_attachment'] = 'This permission allows a user to post attachments to tickets.'; |
|
240 |
+$txt['permissionname_simple_shd_post_attachment'] = 'Allow users to attach their files to tickets'; |
|
241 |
+$txt['permissionhelp_simple_shd_post_attachment'] = 'This permission allows users the ability to add files to tickets that you have, which might be screenshots of problems, or information that relates to their ticket, or other such information.'; |
|
242 |
+//@} |
|
243 |
+ |
|
244 |
+//! @name Ticket to topic, topic to ticket movement |
|
245 |
+//@{ |
|
246 |
+global $modSettings; |
|
247 |
+$txt['permissionname_shd_ticket_to_topic'] = 'Move tickets to topics'; |
|
248 |
+$txt['permissionhelp_shd_ticket_to_topic'] = 'This permission allows a user to transform tickets into topics in the forum. This should only be granted to staff members.'; |
|
249 |
+$txt['permissionname_shd_topic_to_ticket'] = 'Move topics to tickets'; |
|
250 |
+$txt['permissionhelp_shd_topic_to_ticket'] = 'This permission allows a user to transform topics in the forum into helpdesk tickets. This should only be granted to staff members.'; |
|
251 |
+//@} |
|
252 |
+ |
|
253 |
+?> |
|
0 | 254 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,82 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Who.english.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+// Version: 1.0 Felidae; SimpleDesk who's online |
|
20 |
+ |
|
21 |
+// Important! Before editing these language files please read the text at the top of index.english.php. |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * This file contains all of the language strings used by Who's Online for actions carried out within the helpdesk. |
|
25 |
+ * |
|
26 |
+ * @package language |
|
27 |
+ * @todo Document the text groups in this file. |
|
28 |
+ * @since 1.0 |
|
29 |
+ */ |
|
30 |
+ |
|
31 |
+//! @name General strings |
|
32 |
+//@{ |
|
33 |
+$txt['whoall_helpdesk'] = 'Viewing the helpdesk index.'; |
|
34 |
+$txt['whoall_helpdesk_main'] = 'Viewing the helpdesk index.'; |
|
35 |
+$txt['whoall_helpdesk_ticket'] = 'Viewing a helpdesk ticket.'; |
|
36 |
+//@} |
|
37 |
+ |
|
38 |
+//! @name Posting/editing |
|
39 |
+//@{ |
|
40 |
+$txt['whoall_helpdesk_newticket'] = 'Posting a new ticket in the helpdesk.'; |
|
41 |
+$txt['whoall_helpdesk_editticket'] = 'Editing a ticket in the helpdesk.'; |
|
42 |
+$txt['whoall_helpdesk_saveticket'] = 'Posting a ticket in the helpdesk.'; |
|
43 |
+$txt['whoall_helpdesk_reply'] = 'Replying to a helpdesk ticket.'; |
|
44 |
+$txt['whoall_helpdesk_savereply'] = 'Replying to a helpdesk ticket.'; |
|
45 |
+$txt['whoall_helpdesk_editreply'] = 'Editing a reply on a helpdesk ticket.'; |
|
46 |
+$txt['whoall_helpdesk_markunread'] = 'Marking a helpdesk ticket as unread.'; |
|
47 |
+//@} |
|
48 |
+ |
|
49 |
+//! @name Updating ticket details |
|
50 |
+//@{ |
|
51 |
+$txt['whoall_helpdesk_assign'] = 'Assigning a ticket to a user in the helpdesk.'; |
|
52 |
+$txt['whoall_helpdesk_assign2'] = 'Assigning a ticket to a user in the helpdesk.'; |
|
53 |
+$txt['whoall_helpdesk_ajax'] = 'Updating a ticket in the helpdesk.'; |
|
54 |
+$txt['whoall_helpdesk_privacychange'] = 'Updating a ticket\'s details in the helpdesk.'; |
|
55 |
+$txt['whoall_helpdesk_urgencychange'] = 'Updating a ticket\'s details in the helpdesk.'; |
|
56 |
+//@} |
|
57 |
+ |
|
58 |
+//! @name Deletion/recycling, restoration, permadeletion |
|
59 |
+//@{ |
|
60 |
+$txt['whoall_helpdesk_deletereply'] = 'Deleting a reply to a helpdesk ticket.'; |
|
61 |
+$txt['whoall_helpdesk_deleteticket'] = 'Deleting a ticket in the helpdesk.'; |
|
62 |
+$txt['whoall_helpdesk_restorereply'] = 'Restoring a post from the helpdesk recycle bin.'; |
|
63 |
+$txt['whoall_helpdesk_restoretopic'] = 'Restoring a ticket from the helpdesk recycle bin.'; |
|
64 |
+$txt['whoall_helpdesk_recyclebin'] = 'Viewing the deleted tickets in the helpdesk.'; |
|
65 |
+$txt['whoall_helpdesk_permadelete'] = 'Permanently deleting a ticket from the helpdesk.'; |
|
66 |
+//@} |
|
67 |
+ |
|
68 |
+//! @name Ticket resolution |
|
69 |
+//@{ |
|
70 |
+$txt['whoall_helpdesk_resolveticket'] = 'Marking a ticket as resolved, or reopening a resolved, ticket in the helpdesk.'; |
|
71 |
+$txt['whoall_helpdesk_closedtickets'] = 'Viewing the resolved tickets in the helpdesk.'; |
|
72 |
+//@} |
|
73 |
+ |
|
74 |
+//! @name Topic-to-ticket, ticket-to-topic movement |
|
75 |
+//@{ |
|
76 |
+$txt['whoall_helpdesk_tickettotopic'] = 'Moving a helpdesk ticket to a forum topic.'; |
|
77 |
+$txt['whoall_helpdesk_tickettotopic2'] = 'Moving a helpdesk ticket to a forum topic.'; |
|
78 |
+$txt['whoall_helpdesk_topictoticket'] = 'Moving a forum topic to a helpdesk ticket.'; |
|
79 |
+$txt['whoall_helpdesk_topictoticket2'] = 'Moving a forum topic to a helpdesk ticket.'; |
|
80 |
+//@} |
|
81 |
+ |
|
82 |
+?> |
|
0 | 83 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,52 @@ |
1 |
+[url=http://www.simpledesk.net/][img]http://www.simpledesk.net/promo/graphics/signatures/signature1.png[/img][/url] |
|
2 |
+ |
|
3 |
+Thank you for downloading SimpleDesk :) |
|
4 |
+ |
|
5 |
+[b]License[/b] |
|
6 |
+ |
|
7 |
+Yes, we know, you don't want the boring formality of a license, but to protect us - and you - we have a license in the code. Clicking the install button after this constitutes acceptance of the following terms. |
|
8 |
+ |
|
9 |
+[code]Copyright (c) 2010, SimpleDesk Team |
|
10 |
+All rights reserved. |
|
11 |
+ |
|
12 |
+Redistribution and use in source and binary forms, with or without |
|
13 |
+modification, are permitted provided that the following conditions are met: |
|
14 |
+ * Redistributions of source code must retain the above copyright |
|
15 |
+ notice, this list of conditions and the following disclaimer. |
|
16 |
+ * Redistributions in binary form must reproduce the above copyright |
|
17 |
+ notice, this list of conditions and the following disclaimer in the |
|
18 |
+ documentation and/or other materials provided with the distribution. |
|
19 |
+ * Neither the name of SimpleDesk nor the |
|
20 |
+ names of its contributors may be used to endorse or promote products |
|
21 |
+ derived from this software without specific prior written permission. |
|
22 |
+ |
|
23 |
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
24 |
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
25 |
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
26 |
+DISCLAIMED. IN NO EVENT SHALL SIMPLEDESK TEAM BE LIABLE FOR ANY |
|
27 |
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
28 |
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
29 |
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
30 |
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
31 |
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
32 |
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.[/code] |
|
33 |
+ |
|
34 |
+Loosely translated (and this bit isn't the legal wording) |
|
35 |
+* You can pass it on to others but you have to leave the copyright in the files, including derived/modified versions |
|
36 |
+ |
|
37 |
+* You can't use the name of SimpleDesk to promote something without asking us first. |
|
38 |
+ |
|
39 |
+ |
|
40 |
+[b]So, what next?[/b] |
|
41 |
+ |
|
42 |
+Well, once you click the button and install this mod, the installer will take you to the Core Features page of the SMF admin panel, where you can enable SimpleDesk and begin working with it. |
|
43 |
+ |
|
44 |
+[b]What if I need help?[/b] |
|
45 |
+ |
|
46 |
+You can always get help on our forum, http://www.simpledesk.net/community/ |
|
47 |
+ |
|
48 |
+When SimpleDesk is installed, there will be an extra area for support in the SimpleDesk admin area, that will take you to our forum and help you make a post in the best place for your question - and provide us with some necessary information at the same time. |
|
49 |
+ |
|
50 |
+ |
|
51 |
+I think that's everything from us for now! Enjoy using SimpleDesk as much as we enjoyed creating it! |
|
52 |
+-- the SimpleDesk Development team |
|
0 | 53 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+Copyright (c) 2010, SimpleDesk Team |
|
2 |
+All rights reserved. |
|
3 |
+ |
|
4 |
+Redistribution and use in source and binary forms, with or without |
|
5 |
+modification, are permitted provided that the following conditions are met: |
|
6 |
+ * Redistributions of source code must retain the above copyright |
|
7 |
+ notice, this list of conditions and the following disclaimer. |
|
8 |
+ * Redistributions in binary form must reproduce the above copyright |
|
9 |
+ notice, this list of conditions and the following disclaimer in the |
|
10 |
+ documentation and/or other materials provided with the distribution. |
|
11 |
+ * Neither the name of SimpleDesk nor the |
|
12 |
+ names of its contributors may be used to endorse or promote products |
|
13 |
+ derived from this software without specific prior written permission. |
|
14 |
+ |
|
15 |
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
16 |
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
17 |
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
18 |
+DISCLAIMED. IN NO EVENT SHALL SIMPLEDESK TEAM BE LIABLE FOR ANY |
|
19 |
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
20 |
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
21 |
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
22 |
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 |
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
24 |
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
0 | 25 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,126 @@ |
1 |
+<?xml version="1.0"?> |
|
2 |
+<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info"> |
|
3 |
+<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/"> |
|
4 |
+ <id>SimpleDeskTeam:SimpleDesk</id> |
|
5 |
+ <name>SimpleDesk - Integrated Helpdesk for Simple Machines Forum</name> |
|
6 |
+ <version>1.0 Felidae</version> |
|
7 |
+ <type>modification</type> |
|
8 |
+ |
|
9 |
+ <install for="2.0 RC2, 2.0 RC3"> |
|
10 |
+ <!-- readme files --> |
|
11 |
+ <readme lang="english" parsebbc="true" type="file">language-readme/readme.english.txt</readme> |
|
12 |
+ |
|
13 |
+ <!-- general edits --> |
|
14 |
+ <modification format="xml" type="file">install-xml/install.xml</modification> |
|
15 |
+ <modification format="xml" type="file">install-xml/install-attachments.xml</modification> |
|
16 |
+ <modification format="xml" type="file">install-xml/install-trackip.xml</modification> |
|
17 |
+ |
|
18 |
+ <!-- language files --> |
|
19 |
+ <require-file name="language-php/SimpleDesk.english.php" destination="$languagedir" /> |
|
20 |
+ <require-file name="language-php/SimpleDeskPermissions.english.php" destination="$languagedir" /> |
|
21 |
+ <require-file name="language-php/SimpleDeskLogAction.english.php" destination="$languagedir" /> |
|
22 |
+ <require-file name="language-php/SimpleDeskAdmin.english.php" destination="$languagedir" /> |
|
23 |
+ <require-file name="language-php/SimpleDeskWho.english.php" destination="$languagedir" /> |
|
24 |
+ |
|
25 |
+ <!-- sources --> |
|
26 |
+ <require-file name="source/SimpleDesk.php" destination="$sourcedir" /> |
|
27 |
+ <require-file name="source/SimpleDesk-Display.php" destination="$sourcedir" /> |
|
28 |
+ <require-file name="source/SimpleDesk-MiscActions.php" destination="$sourcedir" /> |
|
29 |
+ <require-file name="source/SimpleDesk-Assign.php" destination="$sourcedir" /> |
|
30 |
+ <require-file name="source/SimpleDesk-Post.php" destination="$sourcedir" /> |
|
31 |
+ <require-file name="source/SimpleDesk-AjaxHandler.php" destination="$sourcedir" /> |
|
32 |
+ <require-file name="source/SimpleDesk-TicketTopicMove.php" destination="$sourcedir" /> |
|
33 |
+ <require-file name="source/SimpleDesk-Delete.php" destination="$sourcedir" /> |
|
34 |
+ <require-file name="source/SimpleDesk-Admin.php" destination="$sourcedir" /> |
|
35 |
+ <require-file name="source/Subs-SimpleDesk.php" destination="$sourcedir" /> |
|
36 |
+ <require-file name="source/Subs-SimpleDeskAdmin.php" destination="$sourcedir" /> |
|
37 |
+ <require-file name="source/Subs-SimpleDeskPost.php" destination="$sourcedir" /> |
|
38 |
+ |
|
39 |
+ <!-- templates --> |
|
40 |
+ <require-file name="template/SimpleDesk.template.php" destination="$themedir" /> |
|
41 |
+ <require-file name="template/SimpleDesk-Display.template.php" destination="$themedir" /> |
|
42 |
+ <require-file name="template/SimpleDesk-Admin.template.php" destination="$themedir" /> |
|
43 |
+ <require-file name="template/SimpleDesk-Assign.template.php" destination="$themedir" /> |
|
44 |
+ <require-file name="template/SimpleDesk-Post.template.php" destination="$themedir" /> |
|
45 |
+ <require-file name="template/SimpleDesk-TicketTopicMove.template.php" destination="$themedir" /> |
|
46 |
+ |
|
47 |
+ <!-- images --> |
|
48 |
+ <require-dir name="images/simpledesk" destination="$imagesdir" /> |
|
49 |
+ <require-file name="images/feature_shd.png" destination="$imagesdir/admin" /> |
|
50 |
+ <require-file name="images/simpledesk.png" destination="$imagesdir/admin" /> |
|
51 |
+ <require-file name="images/shd_status.png" destination="$imagesdir/admin" /> |
|
52 |
+ <require-file name="images/shd_log.png" destination="$imagesdir/admin" /> |
|
53 |
+ <require-file name="images/shd_support.png" destination="$imagesdir/admin" /> |
|
54 |
+ |
|
55 |
+ <!-- css --> |
|
56 |
+ <require-file name="css/helpdesk.css" destination="$themedir/css" /> |
|
57 |
+ <require-file name="css/helpdesk_admin.css" destination="$themedir/css" /> |
|
58 |
+ <require-file name="css/helpdesk_ie6.css" destination="$themedir/css" /> |
|
59 |
+ |
|
60 |
+ <!-- scripts --> |
|
61 |
+ <require-file name="scripts/helpdesk_admin.js" destination="$themedir/scripts" /> |
|
62 |
+ <require-file name="scripts/helpdesk.js" destination="$themedir/scripts" /> |
|
63 |
+ |
|
64 |
+ <!-- database changes --> |
|
65 |
+ <database>install.php</database> |
|
66 |
+ |
|
67 |
+ <redirect url="?action=admin;area=corefeatures#js_feature_shd" /> |
|
68 |
+ </install> |
|
69 |
+ |
|
70 |
+ <uninstall for="2.0 RC2, 2.0 RC3"> |
|
71 |
+ <!-- database changes, undone --> |
|
72 |
+ <database>uninstall-optional.php</database> |
|
73 |
+ <code type="file">uninstall-required.php</code> |
|
74 |
+ |
|
75 |
+ <!-- general edits, undone --> |
|
76 |
+ <modification format="xml" type="file" reverse="true">install-xml/install.xml</modification> |
|
77 |
+ <modification format="xml" type="file" reverse="true">install-xml/install-attachments.xml</modification> |
|
78 |
+ <modification format="xml" type="file" reverse="true">install-xml/install-trackip.xml</modification> |
|
79 |
+ |
|
80 |
+ <!-- language files, removed --> |
|
81 |
+ <remove-file name="$languagedir/SimpleDesk.english.php" /> |
|
82 |
+ <remove-file name="$languagedir/SimpleDeskPermissions.english.php" /> |
|
83 |
+ <remove-file name="$languagedir/SimpleDeskLogAction.english.php" /> |
|
84 |
+ <remove-file name="$languagedir/SimpleDeskAdmin.english.php" /> |
|
85 |
+ <remove-file name="$languagedir/SimpleDeskWho.english.php" /> |
|
86 |
+ |
|
87 |
+ <!-- source files, removed --> |
|
88 |
+ <remove-file name="$sourcedir/SimpleDesk.php" /> |
|
89 |
+ <remove-file name="$sourcedir/SimpleDesk-Display.php" /> |
|
90 |
+ <remove-file name="$sourcedir/SimpleDesk-MiscActions.php" /> |
|
91 |
+ <remove-file name="$sourcedir/SimpleDesk-Assign.php" /> |
|
92 |
+ <remove-file name="$sourcedir/SimpleDesk-Post.php" /> |
|
93 |
+ <remove-file name="$sourcedir/SimpleDesk-AjaxHandler.php" /> |
|
94 |
+ <remove-file name="$sourcedir/SimpleDesk-TicketTopicMove.php" /> |
|
95 |
+ <remove-file name="$sourcedir/SimpleDesk-Delete.php" /> |
|
96 |
+ <remove-file name="$sourcedir/SimpleDesk-Admin.php" /> |
|
97 |
+ <remove-file name="$sourcedir/Subs-SimpleDesk.php" /> |
|
98 |
+ <remove-file name="$sourcedir/Subs-SimpleDeskAdmin.php" /> |
|
99 |
+ <remove-file name="$sourcedir/Subs-SimpleDeskPost.php" /> |
|
100 |
+ |
|
101 |
+ <!-- template files, removed --> |
|
102 |
+ <remove-file name="$themedir/SimpleDesk.template.php" /> |
|
103 |
+ <remove-file name="$themedir/SimpleDesk-Display.template.php" /> |
|
104 |
+ <remove-file name="$themedir/SimpleDesk-Admin.template.php" /> |
|
105 |
+ <remove-file name="$themedir/SimpleDesk-Assign.template.php" /> |
|
106 |
+ <remove-file name="$themedir/SimpleDesk-Post.template.php" /> |
|
107 |
+ <remove-file name="$themedir/SimpleDesk-TicketTopicMove.template.php" /> |
|
108 |
+ |
|
109 |
+ <!-- images, removed --> |
|
110 |
+ <remove-dir name="$imagesdir/simpledesk" /> |
|
111 |
+ <remove-file name="$imagesdir/admin/feature_shd.png" /> |
|
112 |
+ <remove-file name="$imagesdir/admin/simpledesk.png" /> |
|
113 |
+ <remove-file name="$imagesdir/admin/shd_status.png" /> |
|
114 |
+ <remove-file name="$imagesdir/admin/shd_log.png" /> |
|
115 |
+ <remove-file name="$imagesdir/admin/shd_support.png" /> |
|
116 |
+ |
|
117 |
+ <!-- css, removed --> |
|
118 |
+ <remove-file name="$themedir/css/helpdesk.css" /> |
|
119 |
+ <remove-file name="$themedir/css/helpdesk-admin.css" /> |
|
120 |
+ <remove-file name="$themedir/css/helpdesk-ie6.css" /> |
|
121 |
+ |
|
122 |
+ <!-- scripts, removed --> |
|
123 |
+ <remove-file name="$themedir/scripts/helpdesk-admin.js" /> |
|
124 |
+ <remove-file name="$themedir/scripts/helpdesk.js" /> |
|
125 |
+ </uninstall> |
|
126 |
+</package-info> |
|
0 | 127 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,341 @@ |
1 |
+/* Javascript for the main Helpdesk */ |
|
2 |
+ |
|
3 |
+/* The privacy toggle in AJAX */ |
|
4 |
+function shd_privacyControl(oOpts) |
|
5 |
+{ |
|
6 |
+ shd_privacyControl.prototype.opts = oOpts; // attaches to the link, but it doesn't exist until after DOM is loaded! |
|
7 |
+ if(window.addEventListener) |
|
8 |
+ window.addEventListener('load', shd_privacyControl.prototype.init, false); |
|
9 |
+ else if(window.attachEvent) |
|
10 |
+ window.attachEvent('onload', shd_privacyControl.prototype.init); |
|
11 |
+} |
|
12 |
+ |
|
13 |
+shd_privacyControl.prototype.init = function () |
|
14 |
+{ |
|
15 |
+ var oDiv = document.getElementById(shd_privacyControl.prototype.opts.sSrcA); |
|
16 |
+ if (oDiv != null) |
|
17 |
+ oDiv.onclick = shd_privacyControl.prototype.action; |
|
18 |
+} |
|
19 |
+ |
|
20 |
+shd_privacyControl.prototype.action = function () |
|
21 |
+{ |
|
22 |
+ ajax_indicator(true); |
|
23 |
+ getXMLDocument(shd_privacyControl.prototype.opts.sUrl + ';' + shd_privacyControl.prototype.opts.sSession, shd_privacyControl.prototype.callback); |
|
24 |
+ return false; |
|
25 |
+} |
|
26 |
+ |
|
27 |
+shd_privacyControl.prototype.callback = function (oRecvd) |
|
28 |
+{ |
|
29 |
+ ajax_indicator(false); |
|
30 |
+ if (oRecvd) |
|
31 |
+ { |
|
32 |
+ var errors = oRecvd.getElementsByTagName('error'); |
|
33 |
+ if (errors.length > 0) |
|
34 |
+ { |
|
35 |
+ var msg = ""; |
|
36 |
+ for (var i = 0; i < errors.length; i++) |
|
37 |
+ msg += errors[i].firstChild.nodeValue + "\n"; |
|
38 |
+ alert(msg); |
|
39 |
+ } |
|
40 |
+ else |
|
41 |
+ { |
|
42 |
+ var msg = oRecvd.getElementsByTagName('message'); |
|
43 |
+ if (msg.length > 0) |
|
44 |
+ { |
|
45 |
+ var oSpan = document.getElementById(shd_privacyControl.prototype.opts.sDestSpan); |
|
46 |
+ oSpan.firstChild.nodeValue = msg[0].firstChild.nodeValue; |
|
47 |
+ } |
|
48 |
+ } |
|
49 |
+ } |
|
50 |
+ else |
|
51 |
+ if (confirm(shd_ajax_problem)) |
|
52 |
+ window.location = smf_scripturl + '?action=helpdesk;sa=privacychange;ticket=' + shd_privacyControl.prototype.opts.ticket + ';' + shd_privacyControl.prototype.opts.sSession; |
|
53 |
+ |
|
54 |
+ return false; |
|
55 |
+} |
|
56 |
+ |
|
57 |
+/* The urgency doodad */ |
|
58 |
+function shd_urgencyControl(oOpts) |
|
59 |
+{ |
|
60 |
+ shd_urgencyControl.prototype.opts = oOpts; // attaches to the link, but it doesn't exist until after DOM is loaded! |
|
61 |
+ if(window.addEventListener) |
|
62 |
+ window.addEventListener('load', shd_urgencyControl.prototype.init, false); |
|
63 |
+ else if(window.attachEvent) |
|
64 |
+ window.attachEvent('onload', shd_urgencyControl.prototype.init); |
|
65 |
+} |
|
66 |
+ |
|
67 |
+shd_urgencyControl.prototype.init = function () |
|
68 |
+{ |
|
69 |
+ for (var i in shd_urgencyControl.prototype.opts.aButtonOps) |
|
70 |
+ { |
|
71 |
+ var oDiv = document.getElementById('urglink_' + shd_urgencyControl.prototype.opts.aButtonOps[i]); |
|
72 |
+ if (oDiv != null && i == 'up') |
|
73 |
+ oDiv.onclick = shd_urgencyControl.prototype.actionUp; |
|
74 |
+ else if(oDiv != null && i == 'down') |
|
75 |
+ oDiv.onclick = shd_urgencyControl.prototype.actionDown; // I *did* try to make this a single parameterised function but it always fired when it wasn't supposed to |
|
76 |
+ } |
|
77 |
+} |
|
78 |
+ |
|
79 |
+shd_urgencyControl.prototype.actionUp = function () |
|
80 |
+{ |
|
81 |
+ return shd_urgencyControl.prototype.action('up'); |
|
82 |
+} |
|
83 |
+ |
|
84 |
+shd_urgencyControl.prototype.actionDown = function () |
|
85 |
+{ |
|
86 |
+ return shd_urgencyControl.prototype.action('down'); |
|
87 |
+} |
|
88 |
+ |
|
89 |
+shd_urgencyControl.prototype.action = function (direction) |
|
90 |
+{ |
|
91 |
+ ajax_indicator(true); |
|
92 |
+ shd_urgencyControl.prototype.opts.direction = direction; |
|
93 |
+ getXMLDocument(shd_urgencyControl.prototype.opts.sUrl + shd_urgencyControl.prototype.opts.aButtonOps[direction] + ';' + shd_urgencyControl.prototype.opts.sSession, shd_urgencyControl.prototype.callback); |
|
94 |
+ return false; |
|
95 |
+} |
|
96 |
+ |
|
97 |
+shd_urgencyControl.prototype.callback = function (oRecvd) |
|
98 |
+{ |
|
99 |
+ ajax_indicator(false); |
|
100 |
+ if (oRecvd) |
|
101 |
+ { |
|
102 |
+ var errors = oRecvd.getElementsByTagName('error'); |
|
103 |
+ if (errors.length > 0) |
|
104 |
+ { |
|
105 |
+ var msg = ""; |
|
106 |
+ for (var i = 0; i < errors.length; i++) |
|
107 |
+ msg += errors[i].firstChild.nodeValue + "\n"; |
|
108 |
+ alert(msg); |
|
109 |
+ } |
|
110 |
+ else |
|
111 |
+ { |
|
112 |
+ var msg = oRecvd.getElementsByTagName('message'); |
|
113 |
+ if (msg.length > 0) |
|
114 |
+ { |
|
115 |
+ var oSpan = document.getElementById(shd_urgencyControl.prototype.opts.sDestSpan); |
|
116 |
+ setInnerHTML(oSpan, msg[0].firstChild.nodeValue); |
|
117 |
+ } |
|
118 |
+ // Now to reset the buttons |
|
119 |
+ var btn_set = [ "increase", "decrease" ]; |
|
120 |
+ |
|
121 |
+ for (var i in btn_set) |
|
122 |
+ { |
|
123 |
+ var oBtn = oRecvd.getElementsByTagName(btn_set[i]); |
|
124 |
+ var oSpan = document.getElementById('urgency_' + btn_set[i]); |
|
125 |
+ setInnerHTML(oSpan, (oBtn.length != 0 ? oBtn[0].firstChild.nodeValue : '')); |
|
126 |
+ } |
|
127 |
+ // Attach JS events to new links |
|
128 |
+ shd_urgencyControl.prototype.init(); |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+ else |
|
132 |
+ if (confirm(shd_ajax_problem)) |
|
133 |
+ window.location = smf_scripturl + '?action=helpdesk;sa=urgencychange;ticket=' + shd_urgencyControl.prototype.opts.ticket + ';change=' + shd_urgencyControl.prototype.opts.aButtonOps[shd_urgencyControl.prototype.opts.direction] + ';' + shd_urgencyControl.prototype.opts.sSession; |
|
134 |
+ |
|
135 |
+ return false; |
|
136 |
+} |
|
137 |
+ |
|
138 |
+/* Attachment selector, based on http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/ |
|
139 |
+* The code below is modified under the MIT licence, http://the-stickman.com/using-code-from-this-site-ie-licence/ not reproduced here for |
|
140 |
+* convenience of users using this software (as this is an active downloaded file) */ |
|
141 |
+function shd_attach_select(oOptions) |
|
142 |
+{ |
|
143 |
+ shd_attach_select.prototype.opts = oOptions; |
|
144 |
+ shd_attach_select.prototype.count = 0; |
|
145 |
+ shd_attach_select.prototype.id = 0; |
|
146 |
+ shd_attach_select.prototype.max = (oOptions.max) ? oOptions.max : -1; |
|
147 |
+ shd_attach_select.prototype.addElement(document.getElementById(shd_attach_select.prototype.opts.file_item)); |
|
148 |
+}; |
|
149 |
+ |
|
150 |
+shd_attach_select.prototype.addElement = function (element) |
|
151 |
+{ |
|
152 |
+ // Make sure it's a file input element, ignore it if not |
|
153 |
+ if (element.tagName == 'INPUT' && element.type == 'file') |
|
154 |
+ { |
|
155 |
+ element.name = 'file_' + this.id++; |
|
156 |
+ element.multi_selector = this; |
|
157 |
+ element.onchange = function() |
|
158 |
+ { |
|
159 |
+ if (element.value == '') |
|
160 |
+ return; |
|
161 |
+ |
|
162 |
+ // Check if it's a valid extension (if we're checking such things) |
|
163 |
+ if (!shd_attach_select.prototype.checkExtension(element.value)) |
|
164 |
+ { |
|
165 |
+ alert(shd_attach_select.prototype.opts.message_ext_error_final); |
|
166 |
+ element.value = ''; |
|
167 |
+ return; |
|
168 |
+ } |
|
169 |
+ |
|
170 |
+ var new_element = document.createElement('input'); |
|
171 |
+ new_element.type = 'file'; |
|
172 |
+ new_element.className = 'input_file'; |
|
173 |
+ new_element.setAttribute('size', '60'); |
|
174 |
+ |
|
175 |
+ // Add new element, update everything |
|
176 |
+ this.parentNode.insertBefore(new_element, this); |
|
177 |
+ this.multi_selector.addElement(new_element); |
|
178 |
+ this.multi_selector.addListRow(this); |
|
179 |
+ |
|
180 |
+ // Hide this: we can't use display:none because Safari doesn't like it |
|
181 |
+ this.style.position = 'absolute'; |
|
182 |
+ this.style.left = '-1000px'; |
|
183 |
+ }; |
|
184 |
+ |
|
185 |
+ this.count++; |
|
186 |
+ shd_attach_select.prototype.current_element = element; |
|
187 |
+ this.checkActive(); |
|
188 |
+ } |
|
189 |
+}; |
|
190 |
+ |
|
191 |
+shd_attach_select.prototype.checkExtension = function (filename) |
|
192 |
+{ |
|
193 |
+ if (!shd_attach_select.prototype.opts.attachment_ext) |
|
194 |
+ return true; // we're not checking |
|
195 |
+ |
|
196 |
+ if (!filename || filename.length == 0) |
|
197 |
+ { |
|
198 |
+ shd_attach_select.prototype.opts.message_ext_error_final = shd_attach_select.prototype.opts.message_ext_error.replace(' ({ext})', ''); |
|
199 |
+ return false; // pfft, didn't specify anything |
|
200 |
+ } |
|
201 |
+ |
|
202 |
+ var dot = filename.lastIndexOf("."); |
|
203 |
+ if (dot == -1) |
|
204 |
+ { |
|
205 |
+ shd_attach_select.prototype.opts.message_ext_error_final = shd_attach_select.prototype.opts.message_ext_error.replace(' ({ext})', ''); |
|
206 |
+ return false; // no extension |
|
207 |
+ } |
|
208 |
+ |
|
209 |
+ var ext = (filename.substr(dot + 1, filename.length)).toLowerCase(); |
|
210 |
+ var arr = shd_attach_select.prototype.opts.attachment_ext; |
|
211 |
+ var func = Array.prototype.indexOf ? |
|
212 |
+ function(arr, obj) { return arr.indexOf(obj) !== -1; } : |
|
213 |
+ function(arr, obj) { |
|
214 |
+ for(var i = -1, j = arr.length; ++i < j;) |
|
215 |
+ if(arr[i] === obj) return true; |
|
216 |
+ return false; |
|
217 |
+ }; |
|
218 |
+ var value = func(arr, ext); |
|
219 |
+ if (!value) |
|
220 |
+ shd_attach_select.prototype.opts.message_ext_error_final = shd_attach_select.prototype.opts.message_ext_error.replace('{ext}', ext); |
|
221 |
+ |
|
222 |
+ return value; |
|
223 |
+} |
|
224 |
+ |
|
225 |
+shd_attach_select.prototype.addListRow = function (element) |
|
226 |
+{ |
|
227 |
+ var new_row = document.createElement('div'); |
|
228 |
+ var new_row_button = document.createElement('input'); |
|
229 |
+ new_row_button.type = 'button'; |
|
230 |
+ new_row_button.value = this.opts.message_txt_delete; |
|
231 |
+ new_row_button.className = 'button_submit'; |
|
232 |
+ new_row.element = element; |
|
233 |
+ |
|
234 |
+ new_row_button.onclick = function () |
|
235 |
+ { |
|
236 |
+ // Remove element from form |
|
237 |
+ this.parentNode.element.parentNode.removeChild(this.parentNode.element); |
|
238 |
+ this.parentNode.parentNode.removeChild(this.parentNode); |
|
239 |
+ this.parentNode.element.multi_selector.count--; |
|
240 |
+ shd_attach_select.prototype.checkActive(); |
|
241 |
+ return false; |
|
242 |
+ }; |
|
243 |
+ |
|
244 |
+ new_row.innerHTML = element.value + ' '; |
|
245 |
+ new_row.appendChild(new_row_button); |
|
246 |
+ document.getElementById(this.opts.file_container).appendChild(new_row); |
|
247 |
+}; |
|
248 |
+ |
|
249 |
+shd_attach_select.prototype.checkActive = function() |
|
250 |
+{ |
|
251 |
+ var elements = document.getElementsByTagName('input'); |
|
252 |
+ var session_attach = 0; |
|
253 |
+ for (i in elements) |
|
254 |
+ { |
|
255 |
+ if (elements[i] && elements[i].type == 'checkbox' && elements[i].name == 'attach_del[]' && elements[i].checked == true) |
|
256 |
+ session_attach++; |
|
257 |
+ } |
|
258 |
+ |
|
259 |
+ var flag = !(shd_attach_select.prototype.max == -1 || (this.max >= (session_attach + shd_attach_select.prototype.count))); |
|
260 |
+ shd_attach_select.prototype.current_element.disabled = flag; |
|
261 |
+} |
|
262 |
+ |
|
263 |
+/* Quick reply stuff */ |
|
264 |
+ |
|
265 |
+function QuickReply(oOptions) |
|
266 |
+{ |
|
267 |
+ this.opt = oOptions; |
|
268 |
+ this.bCollapsed = this.opt.bDefaultCollapsed; |
|
269 |
+} |
|
270 |
+ |
|
271 |
+// When a user presses quote, put it in the quick reply box (if expanded). |
|
272 |
+QuickReply.prototype.quote = function (iMessageId, sSessionId, sSessionVar, bTemplateUpgraded) |
|
273 |
+{ |
|
274 |
+ // Add backwards compatibility with old themes. |
|
275 |
+ if (sSessionVar == true) |
|
276 |
+ { |
|
277 |
+ bTemplateUpgraded = true; |
|
278 |
+ sSessionVar = 'sesc'; |
|
279 |
+ } |
|
280 |
+ |
|
281 |
+ |
|
282 |
+ if (this.bCollapsed) |
|
283 |
+ { |
|
284 |
+ // This is for compatibility. |
|
285 |
+ if (bTemplateUpgraded) |
|
286 |
+ return true; |
|
287 |
+ else |
|
288 |
+ { |
|
289 |
+ window.location.href = smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=helpdesk;sa=reply;quote=' + iMessageId + ';ticket=' + this.opt.iTicketId + '.' + this.opt.iStart + ';' + sSessionVar + '=' + sSessionId; |
|
290 |
+ return false; |
|
291 |
+ } |
|
292 |
+ } |
|
293 |
+ else |
|
294 |
+ { |
|
295 |
+ // Doing it the XMLhttp way? |
|
296 |
+ if (window.XMLHttpRequest) |
|
297 |
+ { |
|
298 |
+ ajax_indicator(true); |
|
299 |
+ getXMLDocument(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=helpdesk;sa=ajax;op=quote;quote=' + iMessageId + ';' + sSessionVar + '=' + sSessionId + ';xml' + ';mode=' + (oEditorHandle_shd_message.bRichTextEnabled ? 1 : 0), this.onQuoteReceived); |
|
300 |
+ } |
|
301 |
+ |
|
302 |
+ // Move the view to the quick reply box. |
|
303 |
+ if (navigator.appName == 'Microsoft Internet Explorer') |
|
304 |
+ window.location.hash = this.opt.sJumpAnchor; |
|
305 |
+ else |
|
306 |
+ window.location.hash = '#' + this.opt.sJumpAnchor; |
|
307 |
+ |
|
308 |
+ return false; |
|
309 |
+ } |
|
310 |
+} |
|
311 |
+ |
|
312 |
+// This is the callback function used after the XMLhttp request. |
|
313 |
+QuickReply.prototype.onQuoteReceived = function (oXMLDoc) |
|
314 |
+{ |
|
315 |
+ var sQuoteText = ''; |
|
316 |
+ |
|
317 |
+ for (var i = 0; i < oXMLDoc.getElementsByTagName('quote')[0].childNodes.length; i++) |
|
318 |
+ sQuoteText += oXMLDoc.getElementsByTagName('quote')[0].childNodes[i].nodeValue; |
|
319 |
+ |
|
320 |
+ oEditorHandle_shd_message.insertText(sQuoteText, false, true); |
|
321 |
+ |
|
322 |
+ ajax_indicator(false); |
|
323 |
+} |
|
324 |
+ |
|
325 |
+// The function handling the swapping of the quick reply. |
|
326 |
+QuickReply.prototype.swap = function () |
|
327 |
+{ |
|
328 |
+ document.getElementById(this.opt.sImageId).src = this.opt.sImagesUrl + "/" + (this.bCollapsed ? this.opt.sImageCollapsed : this.opt.sImageExpanded); |
|
329 |
+ document.getElementById(this.opt.sContainerId).style.display = this.bCollapsed ? '' : 'none'; |
|
330 |
+ document.getElementById(this.opt.sFooterId).style.display = this.bCollapsed ? '' : 'none'; |
|
331 |
+ document.getElementById(this.opt.sHeaderId).setAttribute('class', (this.bCollapsed ? 'title_bar grid_header' : 'title_bar')); |
|
332 |
+ |
|
333 |
+ this.bCollapsed = !this.bCollapsed; |
|
334 |
+} |
|
335 |
+ |
|
336 |
+// The quick jump function |
|
337 |
+function shd_quickTicketJump(id_ticket) |
|
338 |
+{ |
|
339 |
+ window.location.href = smf_prepareScriptUrl(smf_scripturl) + '?action=helpdesk;sa=ticket;ticket=' + id_ticket; |
|
340 |
+ return false; |
|
341 |
+} |
|
0 | 342 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,104 @@ |
1 |
+// Handle the JavaScript surrounding the admin center. |
|
2 |
+function sd_AdminIndex(oOptions) |
|
3 |
+{ |
|
4 |
+ this.opt = oOptions; |
|
5 |
+ this.init(); |
|
6 |
+} |
|
7 |
+ |
|
8 |
+sd_AdminIndex.prototype.init = function () |
|
9 |
+{ |
|
10 |
+ window.adminIndexInstanceRef = this; |
|
11 |
+ var fHandlePageLoaded = function () { |
|
12 |
+ window.adminIndexInstanceRef.loadAdminIndex(); |
|
13 |
+ } |
|
14 |
+ addLoadEvent(fHandlePageLoaded); |
|
15 |
+} |
|
16 |
+ |
|
17 |
+sd_AdminIndex.prototype.loadAdminIndex = function () |
|
18 |
+{ |
|
19 |
+ // Load the text box containing the latest news items. |
|
20 |
+ if (this.opt.bLoadAnnouncements) |
|
21 |
+ this.setAnnouncements(); |
|
22 |
+ |
|
23 |
+ // Load the current SMF and your SMF version numbers. |
|
24 |
+ if (this.opt.bLoadVersions) |
|
25 |
+ this.showCurrentVersion(); |
|
26 |
+ |
|
27 |
+ // Load the text box that sais there's a new version available. |
|
28 |
+ if (this.opt.bLoadUpdateNotification) |
|
29 |
+ this.checkUpdateAvailable(); |
|
30 |
+} |
|
31 |
+ |
|
32 |
+ |
|
33 |
+sd_AdminIndex.prototype.setAnnouncements = function () |
|
34 |
+{ |
|
35 |
+ if (!('sdAnnouncements' in window) || !('length' in window.sdAnnouncements)) |
|
36 |
+ return; |
|
37 |
+ |
|
38 |
+ var sMessages = ''; |
|
39 |
+ for (var i = 0; i < window.sdAnnouncements.length; i++) |
|
40 |
+ sMessages += this.opt.sAnnouncementMessageTemplate.replace('%href%', window.sdAnnouncements[i].href).replace('%subject%', window.sdAnnouncements[i].subject).replace('%time%', window.sdAnnouncements[i].time).replace('%message%', window.sdAnnouncements[i].message).replace('%author%', window.sdAnnouncements[i].author).replace('%readmore%', window.sdAnnouncements[i].href); |
|
41 |
+ |
|
42 |
+ setInnerHTML(document.getElementById(this.opt.sAnnouncementContainerId), this.opt.sAnnouncementTemplate.replace('%content%', sMessages)); |
|
43 |
+} |
|
44 |
+ |
|
45 |
+sd_AdminIndex.prototype.showCurrentVersion = function () |
|
46 |
+{ |
|
47 |
+ if (!('sdVersion' in window)) |
|
48 |
+ return; |
|
49 |
+ |
|
50 |
+ var oSdVersionContainer = document.getElementById(this.opt.sSdVersionContainerId); |
|
51 |
+ var oYourVersionContainer = document.getElementById(this.opt.sYourVersionContainerId); |
|
52 |
+ |
|
53 |
+ setInnerHTML(oSdVersionContainer, window.sdVersion); |
|
54 |
+ |
|
55 |
+ var sCurrentVersion = getInnerHTML(oYourVersionContainer); |
|
56 |
+ if (sCurrentVersion != window.sdVersion) |
|
57 |
+ setInnerHTML(oYourVersionContainer, this.opt.sVersionOutdatedTemplate.replace('%currentVersion%', sCurrentVersion)); |
|
58 |
+} |
|
59 |
+ |
|
60 |
+sd_AdminIndex.prototype.checkUpdateAvailable = function () |
|
61 |
+{ |
|
62 |
+ if (!('sdUpdatePackage' in window)) |
|
63 |
+ return; |
|
64 |
+ |
|
65 |
+ var oContainer = document.getElementById(this.opt.sUpdateNotificationContainerId); |
|
66 |
+ |
|
67 |
+ // Are we setting a custom title and message? |
|
68 |
+ var sTitle = 'sdUpdateTitle' in window ? window.sdUpdateTitle : this.opt.sUpdateNotificationDefaultTitle; |
|
69 |
+ var sMessage = 'sdUpdateNotice' in window ? window.sdUpdateNotice : this.opt.sUpdateNotificationDefaultMessage; |
|
70 |
+ |
|
71 |
+ setInnerHTML(oContainer, this.opt.sUpdateNotificationTemplate.replace('%title%', sTitle).replace('%message%', sMessage).replace('%criticaltitle%', sTitle)); |
|
72 |
+ |
|
73 |
+ // Parse in the package download URL if it exists in the string. |
|
74 |
+ document.getElementById('update-link').href = this.opt.sUpdateNotificationLink.replace('%package%', window.sdUpdatePackage); |
|
75 |
+ |
|
76 |
+ if ('sdUpdateInformation' in window) |
|
77 |
+ { |
|
78 |
+ document.getElementById('information-link-span').style.display = 'block'; |
|
79 |
+ document.getElementById('information-link').href = this.opt.sUpdateInformationLink.replace('%information%', window.sdUpdateInformation); |
|
80 |
+ } |
|
81 |
+ |
|
82 |
+ // If we decide to override life into "red" mode, do it. |
|
83 |
+ if ('sdUpdateCritical' in window && window.sdUpdateCritical == true) |
|
84 |
+ { |
|
85 |
+ document.getElementById('update_container').className = 'errorbox'; |
|
86 |
+ document.getElementById('update_critical_title').style.display = 'block'; |
|
87 |
+ document.getElementById('update_critical_alert').style.display = 'block'; |
|
88 |
+ document.getElementById('update_title').style.display = 'none'; |
|
89 |
+ document.getElementById('update_content').className = ''; |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ document.getElementById('sd_update_section').style.display = 'block'; |
|
93 |
+} |
|
94 |
+ |
|
95 |
+// Ticket number information... |
|
96 |
+function shd_ticket_total_information() |
|
97 |
+{ |
|
98 |
+ var infocontainer = document.getElementById('shd_ticket_total_information'); |
|
99 |
+ |
|
100 |
+ if (infocontainer.style.display == 'none') |
|
101 |
+ infocontainer.style.display = 'block'; |
|
102 |
+ else |
|
103 |
+ infocontainer.style.display = 'none'; |
|
104 |
+} |
|
0 | 105 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,601 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Admin.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles the core of SimpleDesk's administrative information and options from within SMF's own admin panel. |
|
22 |
+ * |
|
23 |
+ * @package source |
|
24 |
+ * @since 1.0 |
|
25 |
+*/ |
|
26 |
+if (!defined('SMF')) |
|
27 |
+ die('Hacking attempt...'); |
|
28 |
+ |
|
29 |
+/** |
|
30 |
+ * The start point for all interaction with the SimpleDesk administration area. |
|
31 |
+ * |
|
32 |
+ * Enforces that users attempting to access the area have either forum or helpdesk administrative privileges, loads the SimpleDesk |
|
33 |
+ * administrative CSS and Javascript and promptly directs users to the specific function for the task they are performing. |
|
34 |
+ * |
|
35 |
+ * @since 1.0 |
|
36 |
+*/ |
|
37 |
+function shd_admin_main() |
|
38 |
+{ |
|
39 |
+ global $context, $scripturl, $sourcedir, $settings, $txt, $modSettings; |
|
40 |
+ |
|
41 |
+ // Templates and stuff |
|
42 |
+ loadTemplate('SimpleDesk-Admin'); |
|
43 |
+ shd_load_language('SimpleDeskAdmin'); |
|
44 |
+ |
|
45 |
+ // Load some extra CSS |
|
46 |
+ $context['html_headers'] .= ' |
|
47 |
+ <link rel="stylesheet" type="text/css" href="' . $settings['default_theme_url'] . '/css/helpdesk_admin.css" /> |
|
48 |
+ <link rel="stylesheet" type="text/css" href="' . $settings['default_theme_url'] . '/css/helpdesk.css" /> |
|
49 |
+ <script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/helpdesk_admin.js?rc2"></script>'; |
|
50 |
+ $context['page_title'] = $txt['shd_admin_title']; |
|
51 |
+ |
|
52 |
+ // Kick them in the kneecaps! |
|
53 |
+ shd_is_allowed_to(array('admin_forum', 'admin_helpdesk')); |
|
54 |
+ |
|
55 |
+ // We need this for later |
|
56 |
+ require_once($sourcedir . '/ManageServer.php'); |
|
57 |
+ require_once($sourcedir . '/Subs-SimpleDeskAdmin.php'); |
|
58 |
+ |
|
59 |
+ // Create some subactions |
|
60 |
+ $subActions = array( |
|
61 |
+ 'helpdesk_info' => 'shd_admin_info', |
|
62 |
+ 'helpdesk_options' => 'shd_admin_options', |
|
63 |
+ 'helpdesk_actionlog' => 'shd_admin_action_log', |
|
64 |
+ 'helpdesk_support' => 'shd_admin_support', |
|
65 |
+ ); |
|
66 |
+ |
|
67 |
+ // Make sure we can find a subaction. If not set, default to info |
|
68 |
+ $_REQUEST['area'] = isset($_REQUEST['area']) && isset($subActions[$_REQUEST['area']]) ? $_REQUEST['area'] : 'helpdesk_info'; |
|
69 |
+ $context['sub_action'] = $_REQUEST['area']; |
|
70 |
+ |
|
71 |
+ $context['shd_version'] = 'SimpleDesk 1.0.1'; |
|
72 |
+ |
|
73 |
+ // Call our subaction |
|
74 |
+ if ($_REQUEST['area'] == 'helpdesk_options') |
|
75 |
+ $subActions[$_REQUEST['area']](false); |
|
76 |
+ else |
|
77 |
+ $subActions[$_REQUEST['area']](); |
|
78 |
+ |
|
79 |
+ // Important ACS666 check up. |
|
80 |
+ if (isset($_REQUEST['cookies'])) |
|
81 |
+ shd_do_important(); |
|
82 |
+} |
|
83 |
+ |
|
84 |
+/** |
|
85 |
+ * Loads the main SimpleDesk information page for forum administrators. |
|
86 |
+ * |
|
87 |
+ * This function primarily collects information about SimpleDesk before handing over to the template: |
|
88 |
+ * <ul> |
|
89 |
+ * <li>list of helpdesk staff</li> |
|
90 |
+ * <li>totals of tickets in the system (open/closed/deleted)</li> |
|
91 |
+ * <li>credits</li> |
|
92 |
+ * <li>also, in the template, whether this is a current or outdated version of SimpleDesk</li> |
|
93 |
+ * </ul> |
|
94 |
+ * |
|
95 |
+ * @since 1.0 |
|
96 |
+*/ |
|
97 |
+function shd_admin_info() |
|
98 |
+{ |
|
99 |
+ global $context, $settings, $scripturl, $txt, $sourcedir, $smcFunc; |
|
100 |
+ |
|
101 |
+ // No little pixies allowed! |
|
102 |
+ shd_is_allowed_to(array('admin_forum', 'admin_helpdesk')); |
|
103 |
+ |
|
104 |
+ // Get a list of the staff members of the helpdesk. |
|
105 |
+ $members = shd_members_allowed_to('shd_staff'); |
|
106 |
+ $query = shd_db_query('', ' |
|
107 |
+ SELECT id_member, real_name |
|
108 |
+ FROM {db_prefix}members |
|
109 |
+ WHERE id_member IN ({array_int:members}) |
|
110 |
+ ORDER BY real_name', |
|
111 |
+ array( |
|
112 |
+ 'members' => $members, |
|
113 |
+ ) |
|
114 |
+ ); |
|
115 |
+ |
|
116 |
+ // Note this just gets everyone, doesn't worry about limiting it - IMO that's something for the template to decide. |
|
117 |
+ $context['staff'] = array(); |
|
118 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
119 |
+ $context['staff'][] = shd_profile_link($row['real_name'], $row['id_member']); |
|
120 |
+ |
|
121 |
+ $smcFunc['db_free_result']($query); |
|
122 |
+ |
|
123 |
+ // Make we sure give these slackers some credit. After all, they made sumfin fer ya! |
|
124 |
+ shd_credits(); |
|
125 |
+ |
|
126 |
+ $context['total_tickets'] = shd_count_helpdesk_tickets(); |
|
127 |
+ $context['open_tickets'] = shd_count_helpdesk_tickets('open'); |
|
128 |
+ $context['closed_tickets'] = shd_count_helpdesk_tickets('closed'); |
|
129 |
+ $context['recycled_tickets'] = shd_count_helpdesk_tickets('recycled'); |
|
130 |
+ |
|
131 |
+ // Final stuff before we go. |
|
132 |
+ $context['page_title'] = $txt['shd_admin_title']; |
|
133 |
+ $context['sub_template'] = 'shd_admin'; |
|
134 |
+} |
|
135 |
+ |
|
136 |
+/** |
|
137 |
+ * Configuration options and save functions generally for SimpleDesk. |
|
138 |
+ * |
|
139 |
+ * This function handles all the sub areas under General Options, and adds the options listed below in $modSettings. |
|
140 |
+ * |
|
141 |
+ * <strong>Display options</strong> |
|
142 |
+ * <ul> |
|
143 |
+ * <li>'shd_staff_badge' (dropdown) - selects the type of badge(s) to display: |
|
144 |
+ * <ul> |
|
145 |
+ * <li>nobadge (default): Display no badges, just a small staff icon for staff members</li> |
|
146 |
+ * <li>staffbadge: Display nothing for normal users, and badge/stars for staff</li> |
|
147 |
+ * <li>userbadge: Display nothing for staff and normal badge/staff for regular users</li> |
|
148 |
+ * <li>bothbadge: Display regular badges/stars for both staff and users</li> |
|
149 |
+ * </ul> |
|
150 |
+ * </li> |
|
151 |
+ * <li>'shd_display_avatar' (checkbox) - whether to display avatars in the replies area or not</li> |
|
152 |
+ * <li>'shd_ticketnav_style' (dropdown) - selects the type of navigation in the ticket area: |
|
153 |
+ * <ul> |
|
154 |
+ * <li>sd (default): use the original SimpleDesk style, icons+text in the bar just above the main ticket area</li> |
|
155 |
+ * <li>sdcompact: use the SimpleDesk icons, in the bar just above the main ticket area, but no captions</li> |
|
156 |
+ * <li>smf: use an SMF style button-strip above the ticket menu</li> |
|
157 |
+ * </ul> |
|
158 |
+ * </li> |
|
159 |
+ * |
|
160 |
+ * <strong>Posting options</strong> |
|
161 |
+ * <li>'shd_allow_ticket_bbc' (checkbox) - one-stop enable/disable of bbcode in tickets (see {@link shd_format_text()} for |
|
162 |
+ * where this is used)</li> |
|
163 |
+ * <li>'shd_allow_ticket_smileys' (checkbox) - one-stop enable/disable of smileys in tickets (see {@link shd_format_text()} |
|
164 |
+ * for where this is used)</li> |
|
165 |
+ * <li>'shd_attachments_mode' (dropdown) - selects the presentation of attachments to users: |
|
166 |
+ * <ul> |
|
167 |
+ * <li>ticket (default): treat attachments as if they are attached to the ticket overall; do not enforce max number per ticket</li> |
|
168 |
+ * <li>reply: treat all attachments as attached to replies; enforce same limit per reply as with posts normally</li> |
|
169 |
+ * </ul> |
|
170 |
+ * </li> |
|
171 |
+ * <li>'shd_bbc' (bbc) - enable/disable individual BBC tags around the helpdesk (see {@link shd_format_text()} for where this is used)</li> |
|
172 |
+ * </ul> |
|
173 |
+ * |
|
174 |
+ * <strong>Administrative options</strong> |
|
175 |
+ * <ul> |
|
176 |
+ * <li>'shd_disable_action_log' (checkbox) - if checked, no actions are added to the action log.</li> |
|
177 |
+ * <li>'shd_staff_ticket_self' (checkbox) - if checked, a ticket opened by a staff member can be assigned to them to action.</li> |
|
178 |
+ * <li>'shd_admins_not_assignable' (checkbox) - if checked, a ticket cannot be assigned to forum admins, only regular staff. (Since 1.1 only)</li> |
|
179 |
+ * <li>'shd_privacy_display' (dropdown) - whether to display privacy or not: |
|
180 |
+ * <ul> |
|
181 |
+ * <li>smart (default): Display ticket privacy if it's likely to be relevant (if users can alter ticket privacy, and/or see private tickets AND the ticket is private, show it)</li> |
|
182 |
+ * <li>always: Always display ticket privacy; likely to be confusing</li> |
|
183 |
+ * </ul> |
|
184 |
+ * </li> |
|
185 |
+ * </ul> |
|
186 |
+ * |
|
187 |
+ * <strong>Standalone options</strong> |
|
188 |
+ * <ul> |
|
189 |
+ * <li>'shd_helpdesk_only' (checkbox) - if checked, Standalone mode is active.</li> |
|
190 |
+ * <li>'shd_disable_pm' (checkbox) - if checked, personal messages will not be available at all when SimpleDesk is in (active) Standalone mode</li> |
|
191 |
+ * <li>'shd_disable_mlist' (checkbox) - if checked, the memberlist will not be available at all when SimpleDesk is in (active) Standalone mode</li> |
|
192 |
+ * </ul> |
|
193 |
+ * |
|
194 |
+ * @see shd_format_text() |
|
195 |
+ * @since 1.0 |
|
196 |
+*/ |
|
197 |
+function shd_admin_options($return_config, $override = '') |
|
198 |
+{ |
|
199 |
+ global $context, $scripturl, $sourcedir, $txt, $modSettings, $settings; |
|
200 |
+ |
|
201 |
+ $_REQUEST['sa'] = isset($_REQUEST['sa']) ? $_REQUEST['sa'] : 'display'; |
|
202 |
+ if (!empty($override)) |
|
203 |
+ $_REQUEST['sa'] = $override; |
|
204 |
+ |
|
205 |
+ // Set up defaults |
|
206 |
+ $defaults = array( |
|
207 |
+ 'shd_attachments_mode' => 'ticket', |
|
208 |
+ 'shd_ticketnav_style' => 'sd', |
|
209 |
+ 'shd_staff_badge' => 'nobadge', |
|
210 |
+ 'shd_privacy_display' => 'smart', |
|
211 |
+ ); |
|
212 |
+ |
|
213 |
+ foreach ($defaults as $var => $val) |
|
214 |
+ { |
|
215 |
+ if (empty($modSettings[$var])) |
|
216 |
+ $modSettings[$var] = $val; |
|
217 |
+ } |
|
218 |
+ |
|
219 |
+ $context[$context['admin_menu_name']]['tab_data'] = array( |
|
220 |
+ 'title' => '<img src="' . $settings['default_images_url'] . '/simpledesk/status.png" class="icon" alt="*" />' . $txt['shd_admin_options'], |
|
221 |
+ 'description' => $txt['shd_admin_options_desc'], |
|
222 |
+ 'tabs' => array( |
|
223 |
+ 'display' => array( |
|
224 |
+ 'description' => $txt['shd_admin_options_display_desc'], |
|
225 |
+ ), |
|
226 |
+ 'posting' => array( |
|
227 |
+ 'description' => $txt['shd_admin_options_posting_desc'], |
|
228 |
+ ), |
|
229 |
+ 'admin' => array( |
|
230 |
+ 'description' => $txt['shd_admin_options_admin_desc'], |
|
231 |
+ ), |
|
232 |
+ 'standalone' => array( |
|
233 |
+ 'description' => $txt['shd_admin_options_standalone_desc'], |
|
234 |
+ ), |
|
235 |
+ ), |
|
236 |
+ ); |
|
237 |
+ |
|
238 |
+ switch ($_REQUEST['sa']) |
|
239 |
+ { |
|
240 |
+ case 'display': |
|
241 |
+ default: |
|
242 |
+ $_REQUEST['sa'] = 'display'; // just in case it wasn't valid before |
|
243 |
+ $config_vars = array( |
|
244 |
+ array('select', 'shd_staff_badge', array('nobadge' => $txt['shd_staff_badge_nobadge'], 'staffbadge' => $txt['shd_staff_badge_staffbadge'], 'userbadge' => $txt['shd_staff_badge_userbadge'], 'bothbadge' => $txt['shd_staff_badge_bothbadge']), 'subtext' => $txt['shd_staff_badge_note']), |
|
245 |
+ array('check', 'shd_display_avatar'), |
|
246 |
+ array('select', 'shd_ticketnav_style', array('sd' => $txt['shd_ticketnav_style_sd'], 'sdcompact' => $txt['shd_ticketnav_style_sdcompact'], 'smf' => $txt['shd_ticketnav_style_smf']), 'subtext' => $txt['shd_ticketnav_style_note']), |
|
247 |
+ ); |
|
248 |
+ $context['settings_title'] = $txt['shd_admin_options_display']; |
|
249 |
+ $context['settings_icon'] = 'details.png'; |
|
250 |
+ break; |
|
251 |
+ |
|
252 |
+ case 'posting': |
|
253 |
+ $config_vars = array( |
|
254 |
+ array('check', 'shd_allow_ticket_bbc'), |
|
255 |
+ array('check', 'shd_allow_ticket_smileys'), |
|
256 |
+ array('select', 'shd_attachments_mode', array('ticket' => $txt['shd_attachments_mode_ticket'], 'reply' => $txt['shd_attachments_mode_reply']), 'subtext' => $txt['shd_attachments_mode_note']), |
|
257 |
+ array('bbc', 'shd_bbc', 'subtext' => $txt['shd_bbc_desc']), |
|
258 |
+ ); |
|
259 |
+ $context['settings_title'] = $txt['shd_admin_options_posting']; |
|
260 |
+ $context['settings_icon'] = 'smiley.png'; |
|
261 |
+ $context['enabled_tags']['shd_bbc'] = !empty($modSettings['shd_enabled_bbc']) ? explode(',', $modSettings['shd_enabled_bbc']) : array(); |
|
262 |
+ $context['available_tags'] = parse_bbc(false); |
|
263 |
+ $context['all_enabled']['shd_bbc'] = count($context['available_tags']) == count($context['enabled_tags']['shd_bbc']) ? 1 : 0; |
|
264 |
+ break; |
|
265 |
+ |
|
266 |
+ case 'admin': |
|
267 |
+ $config_vars = array( |
|
268 |
+ array('check', 'shd_disable_action_log'), |
|
269 |
+ array('check', 'shd_staff_ticket_self'), |
|
270 |
+ array('check', 'shd_admins_not_assignable'), |
|
271 |
+ array('select', 'shd_privacy_display', array('smart' => $txt['shd_privacy_display_smart'], 'always' => $txt['shd_privacy_display_always']), 'subtext' => $txt['shd_privacy_display_note']), |
|
272 |
+ ); |
|
273 |
+ $context['settings_title'] = $txt['shd_admin_options_admin']; |
|
274 |
+ $context['settings_icon'] = 'admin.png'; |
|
275 |
+ break; |
|
276 |
+ |
|
277 |
+ case 'standalone': |
|
278 |
+ $config_vars = array( |
|
279 |
+ array('check', 'shd_helpdesk_only', 'subtext' => $txt['shd_helpdesk_only_note']), |
|
280 |
+ array('check', 'shd_disable_pm'), |
|
281 |
+ array('check', 'shd_disable_mlist'), |
|
282 |
+ ); |
|
283 |
+ $context['settings_title'] = $txt['shd_admin_options_standalone']; |
|
284 |
+ $context['settings_icon'] = 'standalone.png'; |
|
285 |
+ break; |
|
286 |
+ } |
|
287 |
+ |
|
288 |
+ if ($return_config) |
|
289 |
+ return $config_vars; |
|
290 |
+ |
|
291 |
+ loadTemplate('SimpleDesk-Admin'); |
|
292 |
+ $context['sub_template'] = 'shd_show_settings'; |
|
293 |
+ |
|
294 |
+ $context['post_url'] = $scripturl . '?action=admin;area=helpdesk_options;save;sa=' . $_REQUEST['sa']; |
|
295 |
+ |
|
296 |
+ // Saving? |
|
297 |
+ if (isset($_GET['save'])) |
|
298 |
+ { |
|
299 |
+ checkSession(); |
|
300 |
+ $save_vars = $config_vars; |
|
301 |
+ |
|
302 |
+ // If we're saving the posting options, we need to process the BBC tags. |
|
303 |
+ if ($_REQUEST['sa'] == 'posting') |
|
304 |
+ { |
|
305 |
+ |
|
306 |
+ if (!isset($_POST['shd_bbc_enabledTags'])) |
|
307 |
+ $_POST['shd_bbc_enabledTags'] = array(); |
|
308 |
+ elseif (!is_array($_POST['shd_bbc_enabledTags'])) |
|
309 |
+ $_POST['shd_bbc_enabledTags'] = array($_POST['shd_bbc_enabledTags']); |
|
310 |
+ |
|
311 |
+ $_POST['shd_enabled_bbc'] = implode(',', $_POST['shd_bbc_enabledTags']); |
|
312 |
+ |
|
313 |
+ if (empty($_POST['shd_enabled_bbc'])) |
|
314 |
+ $_POST['shd_enabled_bbc'] = 'shd_all_tags_disabled'; |
|
315 |
+ |
|
316 |
+ $save_vars[] = array('text', 'shd_enabled_bbc'); |
|
317 |
+ } |
|
318 |
+ |
|
319 |
+ saveDBSettings($save_vars); |
|
320 |
+ redirectexit('action=admin;area=helpdesk_options;sa=' . $_REQUEST['sa']); |
|
321 |
+ } |
|
322 |
+ |
|
323 |
+ prepareDBSettingContext($config_vars); |
|
324 |
+} |
|
325 |
+ |
|
326 |
+// Since we only have one master function doing it all, not multiple normal functions... we have to do this to appease the God of Admin Search |
|
327 |
+/** |
|
328 |
+ * Provide a helper callback for admin search area. |
|
329 |
+ * |
|
330 |
+ * SMF 2.0 features an admin search area, and to identify what settings there are, it calls the function that will handle the searching, |
|
331 |
+ * which is required to then return a list of possible options' language strings. |
|
332 |
+ * |
|
333 |
+ * Since all of the SD options are currently handled in a single parameterised function, we have to provide a non-parameterised version |
|
334 |
+ * that the ACP can call, which is this function. |
|
335 |
+ * |
|
336 |
+ * @param bool $return_config Whether to return configuration items or not; this is provided solely for SMF ACP compatibility (it expects to pass bool true in to get a list of options) |
|
337 |
+ * |
|
338 |
+ * @return array An array of items that make up the search options on the given admin page, each item is itself an array of (type, option name/language string, [other related information]) |
|
339 |
+ * @since 1.0 |
|
340 |
+ * @see shd_admin_options() |
|
341 |
+*/ |
|
342 |
+function shd_modify_display_options($return_config) |
|
343 |
+{ |
|
344 |
+ return shd_admin_options($return_config, 'display'); |
|
345 |
+} |
|
346 |
+ |
|
347 |
+/** |
|
348 |
+ * Provide a helper callback for admin search area. |
|
349 |
+ * |
|
350 |
+ * SMF 2.0 features an admin search area, and to identify what settings there are, it calls the function that will handle the searching, |
|
351 |
+ * which is required to then return a list of possible options' language strings. |
|
352 |
+ * |
|
353 |
+ * Since all of the SD options are currently handled in a single parameterised function, we have to provide a non-parameterised version |
|
354 |
+ * that the ACP can call, which is this function. |
|
355 |
+ * |
|
356 |
+ * @param bool $return_config Whether to return configuration items or not; this is provided solely for SMF ACP compatibility (it expects to pass bool true in to get a list of options) |
|
357 |
+ * |
|
358 |
+ * @return array An array of items that make up the search options on the given admin page, each item is itself an array of (type, option name/language string, [other related information]) |
|
359 |
+ * @since 1.0 |
|
360 |
+ * @see shd_admin_options() |
|
361 |
+*/ |
|
362 |
+function shd_modify_posting_options($return_config) |
|
363 |
+{ |
|
364 |
+ return shd_admin_options($return_config, 'posting'); |
|
365 |
+} |
|
366 |
+ |
|
367 |
+/** |
|
368 |
+ * Provide a helper callback for admin search area. |
|
369 |
+ * |
|
370 |
+ * SMF 2.0 features an admin search area, and to identify what settings there are, it calls the function that will handle the searching, |
|
371 |
+ * which is required to then return a list of possible options' language strings. |
|
372 |
+ * |
|
373 |
+ * Since all of the SD options are currently handled in a single parameterised function, we have to provide a non-parameterised version |
|
374 |
+ * that the ACP can call, which is this function. |
|
375 |
+ * |
|
376 |
+ * @param bool $return_config Whether to return configuration items or not; this is provided solely for SMF ACP compatibility (it expects to pass bool true in to get a list of options) |
|
377 |
+ * |
|
378 |
+ * @return array An array of items that make up the search options on the given admin page, each item is itself an array of (type, option name/language string, [other related information]) |
|
379 |
+ * @since 1.0 |
|
380 |
+ * @see shd_admin_options() |
|
381 |
+*/ |
|
382 |
+function shd_modify_admin_options($return_config) |
|
383 |
+{ |
|
384 |
+ return shd_admin_options($return_config, 'admin'); |
|
385 |
+} |
|
386 |
+ |
|
387 |
+/** |
|
388 |
+ * Provide a helper callback for admin search area. |
|
389 |
+ * |
|
390 |
+ * SMF 2.0 features an admin search area, and to identify what settings there are, it calls the function that will handle the searching, |
|
391 |
+ * which is required to then return a list of possible options' language strings. |
|
392 |
+ * |
|
393 |
+ * Since all of the SD options are currently handled in a single parameterised function, we have to provide a non-parameterised version |
|
394 |
+ * that the ACP can call, which is this function. |
|
395 |
+ * |
|
396 |
+ * @param bool $return_config Whether to return configuration items or not; this is provided solely for SMF ACP compatibility (it expects to pass bool true in to get a list of options) |
|
397 |
+ * |
|
398 |
+ * @return array An array of items that make up the search options on the given admin page, each item is itself an array of (type, option name/language string, [other related information]) |
|
399 |
+ * @since 1.0 |
|
400 |
+ * @see shd_admin_options() |
|
401 |
+*/ |
|
402 |
+function shd_modify_standalone_options($return_config) |
|
403 |
+{ |
|
404 |
+ return shd_admin_options($return_config, 'standalone'); |
|
405 |
+} |
|
406 |
+ |
|
407 |
+/** |
|
408 |
+ * Initialises the helpdesk action log. |
|
409 |
+ * |
|
410 |
+ * This function loads the language strings, and hands off to {@link shd_load_action_log_entries()} to perform the actual log |
|
411 |
+ * generation. |
|
412 |
+ * |
|
413 |
+ * Before doing so, however, this function will also prepare for deletion of old entries, as well as sorting out the columns and |
|
414 |
+ * ordering rules before handing control to the other function. |
|
415 |
+ * |
|
416 |
+ * @since 1.0 |
|
417 |
+*/ |
|
418 |
+function shd_admin_action_log() |
|
419 |
+{ |
|
420 |
+ global $context, $settings, $scripturl, $txt, $sourcedir, $smcFunc, $sort_types; |
|
421 |
+ |
|
422 |
+ shd_load_language('SimpleDeskLogAction'); |
|
423 |
+ |
|
424 |
+ // Top information stuff. |
|
425 |
+ $context[$context['admin_menu_name']]['tab_data'] = array( |
|
426 |
+ 'title' => $txt['shd_admin_options'], |
|
427 |
+ 'help' => $txt['shd_admin_options_desc'], |
|
428 |
+ 'description' => $txt['shd_admin_options_desc'], |
|
429 |
+ 'tabs' => array(), |
|
430 |
+ ); |
|
431 |
+ |
|
432 |
+ $context['can_delete'] = shd_allowed_to('admin_forum'); |
|
433 |
+ |
|
434 |
+ $context['displaypage'] = 30; |
|
435 |
+ $context['hoursdisable'] = 24; |
|
436 |
+ $context['waittime'] = time() - $context['hoursdisable'] * 3600; |
|
437 |
+ |
|
438 |
+ // Handle deletion... |
|
439 |
+ if (isset($_REQUEST['removeall']) && $context['can_delete']) |
|
440 |
+ shd_db_query('', ' |
|
441 |
+ DELETE FROM {db_prefix}helpdesk_log_action |
|
442 |
+ WHERE log_time < {int:twenty_four_hours_wait}', |
|
443 |
+ array( |
|
444 |
+ 'twenty_four_hours_wait' => $context['waittime'], |
|
445 |
+ ) |
|
446 |
+ ); |
|
447 |
+ elseif (!empty($_REQUEST['remove']) && $context['can_delete']) |
|
448 |
+ shd_db_query('', ' |
|
449 |
+ DELETE FROM {db_prefix}helpdesk_log_action |
|
450 |
+ WHERE id_action = {int:gtfo} |
|
451 |
+ AND log_time < {int:twenty_four_hours_wait}', |
|
452 |
+ array( |
|
453 |
+ 'twenty_four_hours_wait' => $context['waittime'], |
|
454 |
+ 'gtfo' => (int) $_REQUEST['remove'], |
|
455 |
+ ) |
|
456 |
+ ); |
|
457 |
+ |
|
458 |
+ // Do the column stuff! |
|
459 |
+ $sort_types = array( |
|
460 |
+ 'action' =>'la.action', |
|
461 |
+ 'time' => 'la.log_time', |
|
462 |
+ 'member' => 'mem.real_name', |
|
463 |
+ 'position' => 'mg.group_name', |
|
464 |
+ 'ip' => 'la.ip', |
|
465 |
+ ); |
|
466 |
+ |
|
467 |
+ // Setup the direction stuff... |
|
468 |
+ $context['sort'] = isset($_REQUEST['sort']) && isset($sort_types[$_REQUEST['sort']]) ? $sort_types[$_REQUEST['sort']] : $sort_types['time']; |
|
469 |
+ $context['start'] = isset($_REQUEST['start']) ? $_REQUEST['start'] : 0; |
|
470 |
+ $context['order'] = isset($_REQUEST['asc']) ? 'ASC' : 'DESC'; |
|
471 |
+ $context['url_sort'] = isset($_REQUEST['sort']) ? ';sort=' . $_REQUEST['sort'] : ''; |
|
472 |
+ $context['url_order'] = isset($_REQUEST['asc']) ? ';asc' : ''; |
|
473 |
+ |
|
474 |
+ // Get all action log entries |
|
475 |
+ $context['actions'] = shd_load_action_log_entries($context['start'], $context['displaypage'], $context['sort'], $context['order']); |
|
476 |
+ |
|
477 |
+ $context['page_index'] = shd_no_expand_pageindex($scripturl . '?action=admin;area=helpdesk_actionlog' . $context['url_sort'] . $context['url_order'], $_REQUEST['start'], shd_count_action_log_entries(), $context['displaypage']); |
|
478 |
+ |
|
479 |
+ $context['sub_template'] = 'shd_action_log'; |
|
480 |
+} |
|
481 |
+ |
|
482 |
+/** |
|
483 |
+ * Loads the support page for users to submit support requests directly to SimpleDesk.net |
|
484 |
+ * |
|
485 |
+ * Very small function because essentially it just loads a template; there is no logic or processing to actually perform. |
|
486 |
+ * |
|
487 |
+ * @since 1.0 |
|
488 |
+*/ |
|
489 |
+function shd_admin_support() |
|
490 |
+{ |
|
491 |
+ global $context; |
|
492 |
+ |
|
493 |
+ $context['shd_support_url'] = 'http://www.simpledesk.net/support/post.php'; |
|
494 |
+ $context['sub_template'] = 'shd_support'; |
|
495 |
+} |
|
496 |
+ |
|
497 |
+/** |
|
498 |
+ * Loads the list of credits of people who've worked on SimpleDesk. |
|
499 |
+ * |
|
500 |
+ * This defines the list of peoples' names, and none of it will be in language strings; the actual category titles and positions |
|
501 |
+ * will be, but the names themselves can live in this file normally. |
|
502 |
+ * |
|
503 |
+ * @since 1.0 |
|
504 |
+*/ |
|
505 |
+function shd_credits() |
|
506 |
+{ |
|
507 |
+ global $context, $txt, $scripturl; |
|
508 |
+ |
|
509 |
+ // Credits! |
|
510 |
+ $context['shd_credits'] = array( |
|
511 |
+ array( |
|
512 |
+ 'pretext' => $txt['shd_credits_pretext'], |
|
513 |
+ 'groups' => array( |
|
514 |
+ array( |
|
515 |
+ 'title' => $txt['shd_credits_devs'], |
|
516 |
+ 'desc' => $txt['shd_credits_devs_desc'], |
|
517 |
+ 'members' => array( |
|
518 |
+ 'Peter "Arantor" Spicer', |
|
519 |
+ 'Jason "JBlaze" Clemons', |
|
520 |
+ 'Marcus "Nas" Forsberg', |
|
521 |
+ ), |
|
522 |
+ ), |
|
523 |
+ array( |
|
524 |
+ 'title' => $txt['shd_credits_projectsupport'], |
|
525 |
+ 'desc' => $txt['shd_credits_projectsupport_desc'], |
|
526 |
+ 'members' => array( |
|
527 |
+ 'Graeme "Trekkie101" Spence', |
|
528 |
+ 'Jeremy "SleePy" Darwood', |
|
529 |
+ ), |
|
530 |
+ ), |
|
531 |
+ array( |
|
532 |
+ 'title' => $txt['shd_credits_marketing'], |
|
533 |
+ 'desc' => $txt['shd_credits_marketing_desc'], |
|
534 |
+ 'members' => array( |
|
535 |
+ 'Brannon "Bª" Hall', |
|
536 |
+ ), |
|
537 |
+ ), |
|
538 |
+ array( |
|
539 |
+ 'title' => $txt['shd_credits_globalizer'], |
|
540 |
+ 'desc' => $txt['shd_credits_globalizer_desc'], |
|
541 |
+ 'members' => array( |
|
542 |
+ 'Jerry Osborne', |
|
543 |
+ ), |
|
544 |
+ ), |
|
545 |
+ array( |
|
546 |
+ 'title' => $txt['shd_credits_support'], |
|
547 |
+ 'desc' => $txt['shd_credits_support_desc'], |
|
548 |
+ 'members' => array( |
|
549 |
+ 'Tyrsson', |
|
550 |
+ 'Ha2', |
|
551 |
+ ), |
|
552 |
+ ), |
|
553 |
+ array( |
|
554 |
+ 'title' => $txt['shd_credits_qualityassurance'], |
|
555 |
+ 'desc' => $txt['shd_credits_qualityassurance_desc'], |
|
556 |
+ 'members' => array( |
|
557 |
+ 'Sinan "[SiNaN]" Çevik', |
|
558 |
+ 'Alex "Cleo" Tokar', |
|
559 |
+ ), |
|
560 |
+ ), |
|
561 |
+ array( |
|
562 |
+ 'title' => $txt['shd_credits_beta'], |
|
563 |
+ 'desc' => $txt['shd_credits_beta_desc'], |
|
564 |
+ 'members' => array( |
|
565 |
+ 'Chris "ccbtimewiz" Batista', |
|
566 |
+ 'Wade "Acans" Poulsen', |
|
567 |
+ 'Aldo "hadesflames" Barreras', |
|
568 |
+ 'tfs', |
|
569 |
+ 'Edwin "Dismal Shadow" Mendez', |
|
570 |
+ 'Treznax', |
|
571 |
+ 'Mark "KiLLuMiNaTi−7−" Longworth', |
|
572 |
+ 'NIBOGO', |
|
573 |
+ 'Robert "Robbo" Clancy', |
|
574 |
+ 'Yağizcan Arslan', |
|
575 |
+ ), |
|
576 |
+ ), |
|
577 |
+ array( |
|
578 |
+ 'title' => $txt['shd_credits_alltherest'], |
|
579 |
+ 'desc' => '', // This group has its description included in the title. |
|
580 |
+ 'members' => array( |
|
581 |
+ 'Fluffy - ' . sprintf($txt['shd_fluffy'],'onclick="window.location.href=\'' . $scripturl . '?action=admin;area=helpdesk_info;cookies\'"'), |
|
582 |
+ '<br /><a href="http://led24.de/iconset/">LED Icon Set</a> - ' . $txt['shd_credits_ledicons'], |
|
583 |
+ '<br />' . $txt['shd_credits_user'], |
|
584 |
+ ), |
|
585 |
+ ), |
|
586 |
+ ), |
|
587 |
+ ), |
|
588 |
+ ); |
|
589 |
+} |
|
590 |
+ |
|
591 |
+/** |
|
592 |
+ * @ignore |
|
593 |
+ * @since 1.0 |
|
594 |
+*/ |
|
595 |
+function shd_do_important() |
|
596 |
+{ |
|
597 |
+ // Execute code number 66. |
|
598 |
+ die(base64_decode('PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgVHJhbnNpdGlvbmFsLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXRyYW5zaXRpb25hbC5kdGQiPjxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj48aGVhZD48dGl0bGU+Rmx1ZmZ5IC0gR3VhcmRpYW4gb2YgdGhlIGNvb2tpZXo8L3RpdGxlPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ym9keXtiYWNrZ3JvdW5kOnB1cnBsZTtjb2xvcjp3aGl0ZTtmb250LXNpemU6MzBweDt0ZXh0LWFsaWduOmNlbnRlcjt9PC9zdHlsZT48L2hlYWQ+PGJvZHk+PGltZyBzcmM9Imh0dHA6Ly93d3cuc2ltcGxlZGVzay5uZXQvaW1hZ2VzL3NpdGUvZ3VhcmRkb2c0MDMuanBnIiBhbHQ9IiIgb25jbGljaz0iYWxlcnQoJ1dhcm5pbmc6IEhlIG1heSBiaXRlIScpIi8+PGJyIC8+PGJyIC8+PHN0cm9uZz5GbHVmZnk8L3N0cm9uZz4gc2VlcyB5b3UuIEZsdWZmeSB3aWxsIHByb3RlY3Qgb3VyIGNhbmR5IDxzdHJvbmc+Zm9yIGV2ZXI8L3N0cm9uZz4uIEZsdWZmeSBpcyB0aGUgPHN0cm9uZz5ndWFyZGlhbjwvc3Ryb25nPiBvZiB0aGUgPHN0cm9uZz5jb29raWVzPC9zdHJvbmc+LiBCZSBhd2FyZS48L2JvZHk+PC9odG1sPg==')); // It will be done, my lord. |
|
599 |
+} |
|
600 |
+ |
|
601 |
+?> |
|
0 | 602 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,361 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-AjaxHandler.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles all the actions that can be carried out through AJAX methods, performing them and providing adequate feedback/information. |
|
22 |
+ * |
|
23 |
+ * @package source |
|
24 |
+ * @since 1.0 |
|
25 |
+*/ |
|
26 |
+ |
|
27 |
+if (!defined('SMF')) |
|
28 |
+ die('Hacking attempt...'); |
|
29 |
+ |
|
30 |
+// This file handles AJAX actions. This file accepts params and only dumps XML out, much like News.php we do it all here. |
|
31 |
+// What happens is we expect $context['ajax_return'], an array of responses, to be populated. |
|
32 |
+// key => value for single XML tag, key => array (values) for multiple tags |
|
33 |
+// e.g. array('errors' => 'You do not have permission') => <errors><![CDATA[You do not have permission]]></errors> |
|
34 |
+// or array('data' => array('myval1', 'myval2')) => <data><![CDATA[myval1]]></data> <data><![CDATA[myval2]]></data> |
|
35 |
+ |
|
36 |
+/** |
|
37 |
+ * Receives AJAX requests and facilitates replying to them. |
|
38 |
+ * |
|
39 |
+ * This function sets up and calls the AJAX handlers; it is the primary receiver for action=helpdesk;sa=ajax. |
|
40 |
+ * |
|
41 |
+ * Primarily, it expects $context['ajax_return'] to be populated as an array of tags to be returned as XML items to the user, with this element |
|
42 |
+ * being a key-value pair (e.g. $context['ajax_return']['message'] = 'Success!') to be returned as a literal tag, element message, value of |
|
43 |
+ * Success!, wrapped in the character data block. |
|
44 |
+ * |
|
45 |
+ * An AJAX handler function may also return content in $context['ajax_raw'], this is when the function has prepared its own XML block to return. |
|
46 |
+ * In such an instance, this function simply outputs the xml headers and assumes the return value is otherwise value. |
|
47 |
+ * |
|
48 |
+ * For example, if the error subarray is populated (['error'] = 'Insufficient permission'), the XML block will contain a tag called error, |
|
49 |
+ * with a CDATA block containing 'Insufficient permission'. |
|
50 |
+ * |
|
51 |
+ * @since 1.0 |
|
52 |
+*/ |
|
53 |
+function shd_ajax() |
|
54 |
+{ |
|
55 |
+ global $context; |
|
56 |
+ |
|
57 |
+ // Just in case |
|
58 |
+ loadLanguage('Errors'); |
|
59 |
+ |
|
60 |
+ $subactions = array( |
|
61 |
+ 'privacy' => 'shd_ajax_privacy', |
|
62 |
+ 'urgency' => 'shd_ajax_urgency', |
|
63 |
+ 'quote' => 'shd_ajax_quote', |
|
64 |
+ ); |
|
65 |
+ |
|
66 |
+ $context['ajax_return'] = array(); |
|
67 |
+ $context['ajax_raw'] = ''; |
|
68 |
+ |
|
69 |
+ if (!empty($_REQUEST['op']) && !empty($subactions[$_REQUEST['op']])) |
|
70 |
+ $subactions[$_REQUEST['op']](); |
|
71 |
+ |
|
72 |
+ header('Content-Type: text/xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set'])); |
|
73 |
+ echo '<?xml version="1.0" encoding="', $context['character_set'], '"?' . '>'; |
|
74 |
+ |
|
75 |
+ if (empty($context['ajax_raw'])) // if something wants to do something funky, let it otherwise use the standard format |
|
76 |
+ { |
|
77 |
+ echo '<response>'; |
|
78 |
+ |
|
79 |
+ if (!empty($context['ajax_return'])) |
|
80 |
+ { |
|
81 |
+ foreach ($context['ajax_return'] as $key => $value) |
|
82 |
+ { |
|
83 |
+ if (empty($value)) // for <tag /> |
|
84 |
+ echo ' |
|
85 |
+ <', $key, ' />'; |
|
86 |
+ else |
|
87 |
+ { |
|
88 |
+ $value = (array) $value; |
|
89 |
+ foreach ($value as $thisvalue) |
|
90 |
+ echo ' |
|
91 |
+ <', $key, '><![CDATA[', $thisvalue, ']]></', $key, '>'; |
|
92 |
+ } |
|
93 |
+ } |
|
94 |
+ } |
|
95 |
+ |
|
96 |
+ echo ' |
|
97 |
+</response>'; |
|
98 |
+ } |
|
99 |
+ else |
|
100 |
+ { |
|
101 |
+ echo $context['ajax_raw']; // assumed to be just well formed XML sans the header |
|
102 |
+ } |
|
103 |
+ obExit(false); |
|
104 |
+} |
|
105 |
+ |
|
106 |
+/** |
|
107 |
+ * Handles AJAX updates to privacy. |
|
108 |
+ * |
|
109 |
+ * Receives a request via ?action=helpdesk;sa=ajax;op=privacy to flip the privacy setting. |
|
110 |
+ * |
|
111 |
+ * Operations: |
|
112 |
+ * - silent session check; if fail, add to $context['ajax_return']['error'] |
|
113 |
+ * - ticket id check; if fail, add to $context['ajax_return']['error'] |
|
114 |
+ * - get enough ticket data to do this |
|
115 |
+ * - check if the ticket is not able to be updated (either is closed/deleted, or insufficient permissions); if fail add to $context['ajax_return']['error'] |
|
116 |
+ * - switch privacy, update database |
|
117 |
+ * - clear the cache of tickets for the Helpdesk menu item |
|
118 |
+ * - return $context['ajax_return']['message'] as the new privacy item |
|
119 |
+*/ |
|
120 |
+function shd_ajax_privacy() |
|
121 |
+{ |
|
122 |
+ global $smcFunc, $user_info, $context, $txt, $sourcedir; |
|
123 |
+ |
|
124 |
+ $session_check = checkSession('get', '', false); // check the session but don't die fatally. |
|
125 |
+ if (!empty($session_check)) |
|
126 |
+ { |
|
127 |
+ $context['ajax_return'] = array('error' => $txt[$session_check]); |
|
128 |
+ return; |
|
129 |
+ } |
|
130 |
+ |
|
131 |
+ // First, figure out the state of the ticket - is it private or not? Can we even see it? |
|
132 |
+ if (empty($context['ticket_id'])) |
|
133 |
+ { |
|
134 |
+ $context['ajax_return'] = array('error' => $txt['shd_no_ticket']); |
|
135 |
+ return; |
|
136 |
+ } |
|
137 |
+ |
|
138 |
+ $query = shd_db_query('', ' |
|
139 |
+ SELECT id_member_started, subject, private, status |
|
140 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
141 |
+ WHERE {query_see_ticket} |
|
142 |
+ AND id_ticket = {int:current_ticket}', |
|
143 |
+ array( |
|
144 |
+ 'current_ticket' => $context['ticket_id'], |
|
145 |
+ ) |
|
146 |
+ ); |
|
147 |
+ |
|
148 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
149 |
+ { |
|
150 |
+ if (in_array($row['status'], array(TICKET_STATUS_CLOSED, TICKET_STATUS_DELETED)) || !shd_allowed_to('shd_alter_privacy_any') && (!shd_allowed_to('shd_alter_privacy_own') || $row['id_member_started'] != $user_info['id'])) |
|
151 |
+ { |
|
152 |
+ $context['ajax_return'] = array('error' => $txt['shd_cannot_change_privacy']); |
|
153 |
+ return; |
|
154 |
+ } |
|
155 |
+ |
|
156 |
+ $smcFunc['db_free_result']($query); |
|
157 |
+ |
|
158 |
+ $new = empty($row['private']) ? 1 : 0; |
|
159 |
+ $action = empty($row['private']) ? 'markprivate' : 'marknotprivate'; |
|
160 |
+ |
|
161 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
162 |
+ $msgOptions = array(); |
|
163 |
+ $posterOptions = array(); |
|
164 |
+ $ticketOptions = array( |
|
165 |
+ 'id' => $context['ticket_id'], |
|
166 |
+ 'private' => empty($row['private']), |
|
167 |
+ ); |
|
168 |
+ |
|
169 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
170 |
+ |
|
171 |
+ shd_log_action($action, |
|
172 |
+ array( |
|
173 |
+ 'ticket' => $context['ticket_id'], |
|
174 |
+ 'subject' => $row['subject'], |
|
175 |
+ ) |
|
176 |
+ ); |
|
177 |
+ |
|
178 |
+ // Make sure we recalculate the number of tickets on next page load |
|
179 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
180 |
+ |
|
181 |
+ $context['ajax_return'] = array('message' => $new ? $txt['shd_ticket_private'] : $txt['shd_ticket_notprivate']); |
|
182 |
+ } |
|
183 |
+ else |
|
184 |
+ { |
|
185 |
+ $context['ajax_return'] = array('error' => $txt['shd_no_ticket']); |
|
186 |
+ return; |
|
187 |
+ } |
|
188 |
+} |
|
189 |
+ |
|
190 |
+/** |
|
191 |
+ * Handles AJAX updates to ticket urgency. |
|
192 |
+ * |
|
193 |
+ * Receives request through ?action=helpdesk;sa=ajax;op=urgency;change=x where x is increase or decrease. |
|
194 |
+ * |
|
195 |
+ * Operations: |
|
196 |
+ * - silent session check; if fail, add to $context['ajax_return']['error'] |
|
197 |
+ * - ticket id check; if fail, add to $context['ajax_return']['error'] |
|
198 |
+ * - get enough ticket data to do this |
|
199 |
+ * - check permissions with {@link shd_can_alter_urgency()} and permissions; if fail, add to $context['ajax_return']['error'] |
|
200 |
+ * - identify whether the new urgency needs 'urgent' styling or not and put the new urgency in $context['ajax_return']['message'] |
|
201 |
+ * - update the database with the new urgency |
|
202 |
+ * - identify whether the new urgency continues to allow the current user to change urgency or not |
|
203 |
+ * - put the button links if appropriate into $context['ajax_return']['increase'] and $context['ajax_return']['decrease'] and return |
|
204 |
+*/ |
|
205 |
+function shd_ajax_urgency() |
|
206 |
+{ |
|
207 |
+ global $smcFunc, $user_info, $context, $txt, $scripturl, $settings, $sourcedir; |
|
208 |
+ |
|
209 |
+ $session_check = checkSession('get', '', false); // check the session but don't die fatally. |
|
210 |
+ if (!empty($session_check)) |
|
211 |
+ { |
|
212 |
+ $context['ajax_return'] = array('error' => $txt[$session_check]); |
|
213 |
+ return; |
|
214 |
+ } |
|
215 |
+ |
|
216 |
+ // First, figure out the state of the ticket - is it private or not? Can we even see it? |
|
217 |
+ if (empty($context['ticket_id'])) |
|
218 |
+ { |
|
219 |
+ $context['ajax_return'] = array('error' => $txt['shd_no_ticket']); |
|
220 |
+ return; |
|
221 |
+ } |
|
222 |
+ |
|
223 |
+ $query = shd_db_query('', ' |
|
224 |
+ SELECT id_member_started, subject, urgency, status |
|
225 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
226 |
+ WHERE {query_see_ticket} |
|
227 |
+ AND id_ticket = {int:current_ticket}', |
|
228 |
+ array( |
|
229 |
+ 'current_ticket' => $context['ticket_id'], |
|
230 |
+ ) |
|
231 |
+ ); |
|
232 |
+ |
|
233 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
234 |
+ { |
|
235 |
+ $can_urgency = shd_can_alter_urgency($row['urgency'], $row['id_member_started'], ($row['status'] == TICKET_STATUS_CLOSED), ($row['status'] == TICKET_STATUS_DELETED)); |
|
236 |
+ |
|
237 |
+ if (empty($_GET['change']) || empty($can_urgency[$_GET['change']])) |
|
238 |
+ { |
|
239 |
+ $context['ajax_return'] = array('error' => $txt['shd_cannot_change_urgency']); |
|
240 |
+ return; |
|
241 |
+ } |
|
242 |
+ |
|
243 |
+ $new_urgency = $row['urgency'] + ($_GET['change'] == 'increase' ? 1 : -1); |
|
244 |
+ $action = 'urgency_' . $_GET['change']; |
|
245 |
+ |
|
246 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
247 |
+ $msgOptions = array(); |
|
248 |
+ $posterOptions = array(); |
|
249 |
+ $ticketOptions = array( |
|
250 |
+ 'id' => $context['ticket_id'], |
|
251 |
+ 'urgency' => $new_urgency, |
|
252 |
+ ); |
|
253 |
+ |
|
254 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
255 |
+ |
|
256 |
+ shd_log_action($action, |
|
257 |
+ array( |
|
258 |
+ 'ticket' => $context['ticket_id'], |
|
259 |
+ 'subject' => $row['subject'], |
|
260 |
+ 'urgency' => $new_urgency, |
|
261 |
+ ) |
|
262 |
+ ); |
|
263 |
+ |
|
264 |
+ $new_options = shd_can_alter_urgency($new_urgency, $row['id_member_started'], ($row['status'] == TICKET_STATUS_CLOSED), ($row['status'] == TICKET_STATUS_DELETED)); |
|
265 |
+ |
|
266 |
+ $context['ajax_return'] = array( |
|
267 |
+ 'message' => $new_urgency > TICKET_URGENCY_HIGH ? '<span class="error">' . $txt['shd_urgency_' . $new_urgency] . '</span>' : $txt['shd_urgency_' . $new_urgency], |
|
268 |
+ ); |
|
269 |
+ |
|
270 |
+ $array = array( |
|
271 |
+ 'increase' => '<a id="urglink_increase" href="' . $scripturl . '?action=helpdesk;sa=urgencychange;ticket=' . $context['ticket_id'] . ';change=increase;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_urgency_increase'] . '"><img src="' . $settings['images_url'] . '/sort_up.gif" width="9px" alt="' . $txt['shd_urgency_increase'] . '" /></a>', |
|
272 |
+ 'decrease' => '<a id="urglink_decrease" href="' . $scripturl . '?action=helpdesk;sa=urgencychange;ticket=' . $context['ticket_id'] . ';change=decrease;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_urgency_decrease'] . '"><img src="' . $settings['images_url'] . '/sort_down.gif" width="9px" alt="' . $txt['shd_urgency_decrease'] . '" /></a>', |
|
273 |
+ ); |
|
274 |
+ |
|
275 |
+ foreach ($new_options as $button => $can) |
|
276 |
+ if ($can) |
|
277 |
+ $context['ajax_return'][$button] = $array[$button]; |
|
278 |
+ |
|
279 |
+ return; |
|
280 |
+ } |
|
281 |
+ else |
|
282 |
+ { |
|
283 |
+ $context['ajax_return'] = array('error' => $txt['shd_no_ticket']); |
|
284 |
+ return; |
|
285 |
+ } |
|
286 |
+} |
|
287 |
+ |
|
288 |
+/** |
|
289 |
+ * Collects ticket post data for quoting posts through AJAX (i.e. inserting a quote live into the postbox) |
|
290 |
+ * |
|
291 |
+ * Operations: |
|
292 |
+ * - Session check; failing in a regular fashion (as opposed to normal return since we're using ;xml in the URL; the SMF handler can deal with that) |
|
293 |
+ * - If a message id is provided, query for it. If not found (or not provided), die, otherwise continue. |
|
294 |
+ * - Call un_preparsecode to remove extraneous sanity encoding. |
|
295 |
+ * - Build the [quote] bbcode around the post body. |
|
296 |
+ * - Convert to SMF style BBC-to-HTML if using WYSIWYG |
|
297 |
+ * - Do other XML sanitising |
|
298 |
+ * - Return via $context['ajax_raw'] for {@link shd_ajax()} to output |
|
299 |
+*/ |
|
300 |
+function shd_ajax_quote() |
|
301 |
+{ |
|
302 |
+ global $modSettings, $user_info, $txt, $settings, $context; |
|
303 |
+ global $sourcedir, $smcFunc; |
|
304 |
+ |
|
305 |
+ loadLanguage('Post'); |
|
306 |
+ checkSession('get'); |
|
307 |
+ |
|
308 |
+ include_once($sourcedir . '/Subs-Post.php'); |
|
309 |
+ |
|
310 |
+ $_REQUEST['quote'] = !empty($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : 0; |
|
311 |
+ $message = ''; |
|
312 |
+ if (!empty($_REQUEST['quote'])) |
|
313 |
+ { |
|
314 |
+ $query = shd_db_query('', ' |
|
315 |
+ SELECT hdtr.body, IFNULL(mem.real_name, hdtr.poster_name) AS poster_name, hdtr.poster_time, hdt.id_ticket, hdt.id_first_msg |
|
316 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
317 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
318 |
+ LEFT JOIN {db_prefix}members AS mem ON (hdtr.id_member = mem.id_member) |
|
319 |
+ WHERE {query_see_ticket} |
|
320 |
+ AND id_msg = {int:msg}', |
|
321 |
+ array( |
|
322 |
+ 'msg' => $_REQUEST['quote'], |
|
323 |
+ ) |
|
324 |
+ ); |
|
325 |
+ |
|
326 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
327 |
+ { |
|
328 |
+ $smcFunc['db_free_result']($query); |
|
329 |
+ $row['body'] = un_preparsecode($row['body']); |
|
330 |
+ |
|
331 |
+ // Censor the message! |
|
332 |
+ censorText($row['body']); |
|
333 |
+ $row['body'] = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']); |
|
334 |
+ |
|
335 |
+ if (strpos($row['poster_name'], '[') !== false || strpos($row['poster_name'], ']') !== false) |
|
336 |
+ $row['poster_name'] = '"' . $row['poster_name'] . '"'; |
|
337 |
+ |
|
338 |
+ // Make the body HTML if need be. |
|
339 |
+ if (!empty($_REQUEST['mode'])) |
|
340 |
+ { |
|
341 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
342 |
+ $row['body'] = strtr($row['body'], array('<' => '#smlt#', '>' => '#smgt#', '&' => '#smamp#')); |
|
343 |
+ $row['body'] = bbc_to_html($row['body']); |
|
344 |
+ $lb = '<br />'; |
|
345 |
+ } |
|
346 |
+ else |
|
347 |
+ $lb = "\n"; |
|
348 |
+ |
|
349 |
+ $message = '[quote author=' . $row['poster_name'] . ' link=action=helpdesk;sa=ticket;ticket=' . $row['id_ticket']; |
|
350 |
+ if ($row['id_first_msg'] != $_REQUEST['quote']) // don't add the msg if we're quoting the ticket itself |
|
351 |
+ $message .= '.msg' . $_REQUEST['quote'] . '#msg' . $_REQUEST['quote']; |
|
352 |
+ |
|
353 |
+ $message .= ' date=' . $row['poster_time'] . ']' . $lb . $row['body'] . $lb . '[/quote]'; |
|
354 |
+ } |
|
355 |
+ } |
|
356 |
+ |
|
357 |
+ $message = strtr($message, array(' ' => ' ', '<' => '<', '>' => '>')); |
|
358 |
+ |
|
359 |
+ $context['ajax_raw'] = '<quote>' . $message . '</quote>'; |
|
360 |
+} |
|
361 |
+?> |
|
0 | 362 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,359 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Assign.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles ticket assignments, both the user interface for the assignment page, plus |
|
22 |
+ * actually assigning users to tickets. There are also helper functions here for that purpose. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @since 1.0 |
|
26 |
+*/ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Sets up the assignment UI and invokes the template. |
|
33 |
+ * |
|
34 |
+ * This validates that the user can see the ticket in question initially, before determining the level of assignment that can be |
|
35 |
+ * carried out. |
|
36 |
+ * |
|
37 |
+ * Users who can assign any ticket cause a query to trigger to identify users who have shd_staff permission (and thus can be the |
|
38 |
+ * target of assignment) and the template is loaded with a dropdown to provide this choice to the user. |
|
39 |
+ * |
|
40 |
+ * Users who can only assign to themselves will at this point have the ticket assigned to them if it was unassigned before, or |
|
41 |
+ * unassigned from them if they are able to assign tickets to themselves in the first place; if it was assigned to someone else, |
|
42 |
+ * they will not have the option. |
|
43 |
+ * |
|
44 |
+ * Access through action=helpdesk;sa=assign;ticket=x;sessvar=sessid before redirecting back to the ticket, or add ;home to the |
|
45 |
+ * URL to have it redirect back to the home page (passed through to the form for {@link shd_assign2()}'s use too) |
|
46 |
+ * |
|
47 |
+ * @see shd_assign2() |
|
48 |
+ * @see shd_get_possible_assignees() |
|
49 |
+ * @since 1.0 |
|
50 |
+*/ |
|
51 |
+function shd_assign() |
|
52 |
+{ |
|
53 |
+ global $smcFunc, $context, $user_info, $sourcedir, $txt, $scripturl; |
|
54 |
+ |
|
55 |
+ checkSession('get'); |
|
56 |
+ |
|
57 |
+ if (empty($context['ticket_id'])) |
|
58 |
+ fatal_lang_error('shd_no_ticket'); |
|
59 |
+ |
|
60 |
+ $context['shd_return_to'] = isset($_REQUEST['home']) ? 'home' : 'ticket'; |
|
61 |
+ |
|
62 |
+ // Get ticket details - and kick it out if they shouldn't be able to see it. |
|
63 |
+ $query = shd_db_query('', ' |
|
64 |
+ SELECT id_member_started, id_member_assigned, private, subject |
|
65 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
66 |
+ WHERE {query_see_ticket} AND id_ticket = {int:ticket}', |
|
67 |
+ array( |
|
68 |
+ 'ticket' => $context['ticket_id'], |
|
69 |
+ ) |
|
70 |
+ ); |
|
71 |
+ |
|
72 |
+ $log_params = array(); |
|
73 |
+ if ($row = $smcFunc['db_fetch_row']($query)) |
|
74 |
+ { |
|
75 |
+ list($ticket_starter, $ticket_owner, $private, $subject) = $row; |
|
76 |
+ $log_params = array( |
|
77 |
+ 'subject' => $subject, |
|
78 |
+ 'ticket' => $context['ticket_id'], |
|
79 |
+ ); |
|
80 |
+ } |
|
81 |
+ else |
|
82 |
+ { |
|
83 |
+ $smcFunc['db_free_result']($query); |
|
84 |
+ fatal_lang_error('shd_no_ticket'); |
|
85 |
+ } |
|
86 |
+ |
|
87 |
+ if (shd_allowed_to('shd_assign_ticket_any')) // can regularly assign? If so, load up potential candidates and throw it at the template. |
|
88 |
+ { |
|
89 |
+ $members = shd_get_possible_assignees($private, $ticket_starter); |
|
90 |
+ |
|
91 |
+ if (!in_array($ticket_owner, $members)) // if for whatever reason the current assignee is not accessible staff, treat it as unassigned |
|
92 |
+ $ticket_owner = 0; |
|
93 |
+ |
|
94 |
+ if (!empty($members)) |
|
95 |
+ { |
|
96 |
+ $query = shd_db_query('', ' |
|
97 |
+ SELECT id_member, real_name |
|
98 |
+ FROM {db_prefix}members |
|
99 |
+ WHERE id_member IN ({array_int:members}) |
|
100 |
+ ORDER BY real_name', |
|
101 |
+ array( |
|
102 |
+ 'members' => $members, |
|
103 |
+ ) |
|
104 |
+ ); |
|
105 |
+ |
|
106 |
+ $members = array(); |
|
107 |
+ |
|
108 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
109 |
+ $members[$row['id_member']] = $row['real_name']; |
|
110 |
+ } |
|
111 |
+ |
|
112 |
+ if (empty($members)) |
|
113 |
+ fatal_lang_error('shd_no_staff_assign'); |
|
114 |
+ |
|
115 |
+ $context['linktree'][] = array( |
|
116 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
117 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
118 |
+ ); |
|
119 |
+ $context['linktree'][] = array( |
|
120 |
+ 'url' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'], |
|
121 |
+ 'name' => $subject, |
|
122 |
+ ); |
|
123 |
+ $context['linktree'][] = array( |
|
124 |
+ 'name' => $txt['shd_ticket_assign_ticket'], |
|
125 |
+ ); |
|
126 |
+ |
|
127 |
+ $context['member_list'] = array(0 => $txt['shd_unassigned']) + $members; |
|
128 |
+ $context['ticket_assigned'] = $ticket_owner; |
|
129 |
+ |
|
130 |
+ $context['page_title'] = $txt['shd_ticket_assign_ticket']; |
|
131 |
+ |
|
132 |
+ loadTemplate('SimpleDesk-Assign'); |
|
133 |
+ $context['sub_template'] = 'assign'; |
|
134 |
+ } |
|
135 |
+ elseif (shd_allowed_to('shd_assign_ticket_own') && shd_allowed_to('shd_staff')) // can't just randomly assign (and must be staff), so look at if it's already assigned or not. |
|
136 |
+ { |
|
137 |
+ if ($ticket_owner == 0) // unassigned |
|
138 |
+ { |
|
139 |
+ $log_params += array( |
|
140 |
+ 'user_id' => $user_info['id'], |
|
141 |
+ 'user_name' => $user_info['name'], |
|
142 |
+ ); |
|
143 |
+ shd_log_action('assign', $log_params); |
|
144 |
+ shd_commit_assignment($context['ticket_id'], $user_info['id']); |
|
145 |
+ } |
|
146 |
+ elseif ($ticket_starter == $user_info['id']) // assigned to self already, unassign it |
|
147 |
+ { |
|
148 |
+ shd_log_action('unassign', $log_params); |
|
149 |
+ shd_commit_assignment($context['ticket_id'], 0); |
|
150 |
+ } |
|
151 |
+ else // oops, assigned to somebody else |
|
152 |
+ fatal_lang_error('shd_cannot_assign_other', false); |
|
153 |
+ } |
|
154 |
+ else |
|
155 |
+ fatal_lang_error('shd_cannot_assign', false); |
|
156 |
+} |
|
157 |
+ |
|
158 |
+/** |
|
159 |
+ * Handles the actual assignment form, validates it and carries it out. |
|
160 |
+ * |
|
161 |
+ * Primarily this is just about receiving the form, making the same checks that {@link shd_assign()} does and then |
|
162 |
+ * logging the action before passing over to {@link shd_commit_assignment()} to actually assign the ticket. |
|
163 |
+ * |
|
164 |
+ * @see shd_assign() |
|
165 |
+ * @see shd_commit_assignment() |
|
166 |
+ * @since 1.0 |
|
167 |
+*/ |
|
168 |
+function shd_assign2() |
|
169 |
+{ |
|
170 |
+ global $context, $smcFunc, $user_info, $sourcedir; |
|
171 |
+ |
|
172 |
+ checkSession(); |
|
173 |
+ checkSubmitOnce('check'); |
|
174 |
+ |
|
175 |
+ if (empty($context['ticket_id'])) |
|
176 |
+ fatal_lang_error('shd_no_ticket'); |
|
177 |
+ |
|
178 |
+ $context['shd_return_to'] = isset($_REQUEST['home']) ? 'home' : 'ticket'; |
|
179 |
+ |
|
180 |
+ $assignee = isset($_REQUEST['to_user']) ? (int) $_REQUEST['to_user'] : 0; |
|
181 |
+ |
|
182 |
+ // Get ticket details - and kick it out if they shouldn't be able to see it. |
|
183 |
+ $query = shd_db_query('', ' |
|
184 |
+ SELECT id_member_started, id_member_assigned, private, subject |
|
185 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
186 |
+ WHERE {query_see_ticket} AND id_ticket = {int:ticket}', |
|
187 |
+ array( |
|
188 |
+ 'ticket' => $context['ticket_id'], |
|
189 |
+ ) |
|
190 |
+ ); |
|
191 |
+ |
|
192 |
+ $log_params = array(); |
|
193 |
+ |
|
194 |
+ if ($row = $smcFunc['db_fetch_row']($query)) |
|
195 |
+ { |
|
196 |
+ list($ticket_starter, $ticket_owner, $private, $subject) = $row; |
|
197 |
+ |
|
198 |
+ // The core details that we'll be logging |
|
199 |
+ $log_params = array( |
|
200 |
+ 'subject' => $subject, |
|
201 |
+ 'ticket' => $context['ticket_id'], |
|
202 |
+ ); |
|
203 |
+ } |
|
204 |
+ else |
|
205 |
+ { |
|
206 |
+ $smcFunc['db_free_result']($query); |
|
207 |
+ fatal_lang_error('shd_no_ticket'); |
|
208 |
+ } |
|
209 |
+ |
|
210 |
+ // Just in case, are they cancelling? |
|
211 |
+ if (isset($_REQUEST['cancel'])) |
|
212 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
213 |
+ |
|
214 |
+ if (shd_allowed_to('shd_assign_ticket_any')) // can regularly assign? If so, see if our requested member is staff and can see the ticket |
|
215 |
+ { |
|
216 |
+ if ($assignee == 0) // can always unassign a ticket |
|
217 |
+ { |
|
218 |
+ shd_log_action('unassign', $log_params); |
|
219 |
+ shd_commit_assignment($context['ticket_id'], 0); |
|
220 |
+ } |
|
221 |
+ else |
|
222 |
+ { |
|
223 |
+ $members = shd_get_possible_assignees($private, $ticket_starter); |
|
224 |
+ |
|
225 |
+ if (in_array($assignee, $members)) // can only assign a ticket to a member if they're on Santa's good list |
|
226 |
+ { |
|
227 |
+ global $user_profile; |
|
228 |
+ loadMemberData($assignee, false, 'minimal'); |
|
229 |
+ $log_params += array( |
|
230 |
+ 'user_id' => $assignee, |
|
231 |
+ 'user_name' => $user_profile[$assignee]['real_name'], |
|
232 |
+ ); |
|
233 |
+ shd_log_action('assign', $log_params); |
|
234 |
+ shd_commit_assignment($context['ticket_id'], $assignee); |
|
235 |
+ } |
|
236 |
+ else |
|
237 |
+ fatal_lang_error('shd_assigned_not_permitted', false); |
|
238 |
+ } |
|
239 |
+ } |
|
240 |
+ elseif (shd_allowed_to('shd_assign_ticket_own') && shd_allowed_to('shd_staff')) // can't just randomly assign (and must be staff), so look at if it's already assigned or not. |
|
241 |
+ { |
|
242 |
+ if ($ticket_owner == 0) // unassigned |
|
243 |
+ { |
|
244 |
+ $log_params += array( |
|
245 |
+ 'user_id' => $user_info['id'], |
|
246 |
+ 'user_name' => $user_info['name'], |
|
247 |
+ ); |
|
248 |
+ shd_log_action('assign', $log_params); |
|
249 |
+ shd_commit_assignment($context['ticket_id'], $user_info['id']); |
|
250 |
+ } |
|
251 |
+ elseif ($ticket_starter == $user_info['id']) // assigned to self already, unassign it |
|
252 |
+ { |
|
253 |
+ shd_log_action('unassign', $log_params); |
|
254 |
+ shd_commit_assignment($context['ticket_id'], 0); |
|
255 |
+ } |
|
256 |
+ else // oops, assigned to somebody else |
|
257 |
+ fatal_lang_error('shd_cannot_assign_other', false); |
|
258 |
+ } |
|
259 |
+ else |
|
260 |
+ fatal_lang_error('shd_cannot_assign', false); |
|
261 |
+} |
|
262 |
+ |
|
263 |
+/** |
|
264 |
+ * Actually commits a ticket assignment to the database. |
|
265 |
+ * |
|
266 |
+ * This function sets up the relevant options before handing over to shd_modify_ticket_post() which is the preferred way to modify |
|
267 |
+ * tickets generally. No permissions check is performed here. |
|
268 |
+ * |
|
269 |
+ * Relies on $context['shd_return_to'] to have been set, defaults to 'ticket' to return to ticket, otherwise return to home page |
|
270 |
+ * on value of 'home'. |
|
271 |
+ * |
|
272 |
+ * @param int $ticket Ticket id number, assumed to exist. |
|
273 |
+ * @param int $assignment User id of the user to which this ticket will be assigned; can be 0 to unassign a ticket |
|
274 |
+ * |
|
275 |
+ * @see shd_assign() |
|
276 |
+ * @see shd_assign2() |
|
277 |
+*/ |
|
278 |
+function shd_commit_assignment($ticket, $assignment) |
|
279 |
+{ |
|
280 |
+ global $smcFunc, $sourcedir, $context; |
|
281 |
+ |
|
282 |
+ require($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
283 |
+ |
|
284 |
+ $msgOptions = array(); |
|
285 |
+ $posterOptions = array(); |
|
286 |
+ $ticketOptions = array( |
|
287 |
+ 'id' => $context['ticket_id'], |
|
288 |
+ 'assigned' => $assignment, |
|
289 |
+ ); |
|
290 |
+ |
|
291 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
292 |
+ |
|
293 |
+ if (!empty($context['shd_return_to']) && $context['shd_return_to'] == 'home') |
|
294 |
+ redirectexit('action=helpdesk;sa=main'); |
|
295 |
+ else |
|
296 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $ticket); |
|
297 |
+} |
|
298 |
+ |
|
299 |
+/** |
|
300 |
+ * Return a list of possible users that can be assigned a ticket. |
|
301 |
+ * |
|
302 |
+ * This function centralises who a ticket can be assigned to. Currently this is: |
|
303 |
+ * - user with shd_staff permission |
|
304 |
+ * - can see "any" ticket (not just their own) |
|
305 |
+ * - additionally, if the ticket is private, the user must also be able to see 'any' private ticket. |
|
306 |
+ * - additionally, check whether user is staff + ticket starter, and then whether we should block them from being assigned |
|
307 |
+ * - (since 1.1) additionally if we have set the option, which users are true admins, and if so, remove them from the list too |
|
308 |
+ * |
|
309 |
+ * @param bool $private Whether the ticket in question is private or not. |
|
310 |
+ * @param int $ticket_owner User id of the ticket owner |
|
311 |
+ * |
|
312 |
+ * @return array An indexed array of member ids that this ticket could be assigned to. |
|
313 |
+ * @see shd_assign() |
|
314 |
+ * @see shd_assign2() |
|
315 |
+ * @since 1.0 |
|
316 |
+*/ |
|
317 |
+function shd_get_possible_assignees($private = false, $ticket_owner = 0) |
|
318 |
+{ |
|
319 |
+ global $context, $smcFunc, $modSettings; |
|
320 |
+ |
|
321 |
+ // people who can handle a ticket |
|
322 |
+ $staff = shd_members_allowed_to('shd_staff'); |
|
323 |
+ |
|
324 |
+ // is it private, if so, remove that list |
|
325 |
+ if ((bool) $private == true) |
|
326 |
+ { |
|
327 |
+ $private = shd_members_allowed_to('shd_view_ticket_private_any'); |
|
328 |
+ $staff = array_intersect($staff, $private); |
|
329 |
+ } |
|
330 |
+ |
|
331 |
+ // What about admins? We ignoring them? Note we're talking about *real* admins who implicitly have every permission, not any homebrew |
|
332 |
+ if (!empty($modSettings['shd_admins_not_assignable'])) |
|
333 |
+ { |
|
334 |
+ $query = $smcFunc['db_query']('', ' |
|
335 |
+ SELECT id_member |
|
336 |
+ FROM {db_prefix}members |
|
337 |
+ WHERE id_group = 1 |
|
338 |
+ OR FIND_IN_SET(1, additional_groups)', |
|
339 |
+ array() |
|
340 |
+ ); |
|
341 |
+ |
|
342 |
+ $admins = array(); |
|
343 |
+ while ($row = $smcFunc['db_fetch_row']($query)) |
|
344 |
+ $admins[] = $row[0]; |
|
345 |
+ |
|
346 |
+ $smcFunc['db_free_result']($query); |
|
347 |
+ $staff = array_diff($staff, $admins); |
|
348 |
+ } |
|
349 |
+ |
|
350 |
+ // can they actually see said ticket |
|
351 |
+ $visible = shd_members_allowed_to('shd_view_ticket_any'); |
|
352 |
+ |
|
353 |
+ if (empty($modSettings['shd_staff_ticket_self'])) // by default, staff members can't be assigned a ticket if they started it |
|
354 |
+ $staff = array_diff($staff, array($ticket_owner)); |
|
355 |
+ |
|
356 |
+ // spit back the list of staff members who can see any ticket (+private if dealt with) |
|
357 |
+ return array_intersect($staff, $visible); |
|
358 |
+} |
|
359 |
+?> |
|
0 | 360 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,628 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Delete.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file deals with deletion/recycling of tickets and replies, subsequent restoration back to |
|
22 |
+ * the helpdesk, and lastly, permanent deletion of the same. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @todo Finish documenting this file. |
|
26 |
+ * @since 1.0 |
|
27 |
+*/ |
|
28 |
+ |
|
29 |
+if (!defined('SMF')) |
|
30 |
+ die('Hacking attempt...'); |
|
31 |
+ |
|
32 |
+/** |
|
33 |
+ * Delete the given ticket, i.e move it to the recycling bin. |
|
34 |
+ * |
|
35 |
+ * Accessed through ?action=helpdesk;sa=deleteticket;ticket=x;sessvar=sessid |
|
36 |
+ * |
|
37 |
+ * Operations: |
|
38 |
+ * - Session check |
|
39 |
+ * - Check there's a ticket id |
|
40 |
+ * - Check the ticket exists and is visible to the current user |
|
41 |
+ * - Check permission to delete ticket matches (i.e. can delete any, or can delete own and this is one of ours) |
|
42 |
+ * - Update the ticket's status to deleted |
|
43 |
+ * - Log the deletion |
|
44 |
+ * - Clear the menu's Helpdesk active items cache |
|
45 |
+ * - return to the front page |
|
46 |
+ * |
|
47 |
+ * @since 1.0 |
|
48 |
+*/ |
|
49 |
+function shd_ticket_delete() |
|
50 |
+{ |
|
51 |
+ global $smcFunc, $user_info, $context; |
|
52 |
+ |
|
53 |
+ checkSession('get'); |
|
54 |
+ |
|
55 |
+ if (empty($context['ticket_id'])) |
|
56 |
+ fatal_lang_error('shd_no_ticket', false); |
|
57 |
+ |
|
58 |
+ // Check we can actually see the ticket we're deleting, and if we can only delete our own, we are the owner |
|
59 |
+ $query_ticket = shd_db_query('', ' |
|
60 |
+ SELECT id_ticket, id_member_started, subject |
|
61 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
62 |
+ WHERE {query_see_ticket} |
|
63 |
+ AND id_ticket = {int:ticket}', |
|
64 |
+ array( |
|
65 |
+ 'ticket' => $context['ticket_id'], |
|
66 |
+ ) |
|
67 |
+ ); |
|
68 |
+ |
|
69 |
+ if ($row = $smcFunc['db_fetch_assoc']($query_ticket)) |
|
70 |
+ { |
|
71 |
+ $smcFunc['db_free_result']($query_ticket); |
|
72 |
+ if (!shd_allowed_to('shd_delete_ticket_any') && (!shd_allowed_to('shd_delete_ticket_own') || $user_info['id'] != $row['id_member_started'])) |
|
73 |
+ fatal_lang_error('shd_cannot_delete_ticket', false); |
|
74 |
+ } |
|
75 |
+ else |
|
76 |
+ { |
|
77 |
+ $smcFunc['db_free_result']($query_ticket); |
|
78 |
+ fatal_lang_error('shd_no_ticket', false); |
|
79 |
+ } |
|
80 |
+ |
|
81 |
+ $subject = $row['subject']; |
|
82 |
+ |
|
83 |
+ // Move it to deleted status |
|
84 |
+ $query_ticket = shd_db_query('', ' |
|
85 |
+ UPDATE {db_prefix}helpdesk_tickets AS hdt |
|
86 |
+ SET status = {int:status_deleted}, |
|
87 |
+ id_member_assigned = 0 |
|
88 |
+ WHERE id_ticket = {int:current_ticket} |
|
89 |
+ AND {query_see_ticket}', |
|
90 |
+ array( |
|
91 |
+ 'current_ticket' => $context['ticket_id'], |
|
92 |
+ 'status_deleted' => TICKET_STATUS_DELETED, // just move it, don't bother calling merge (or shd_determine_status) |
|
93 |
+ ) |
|
94 |
+ ); |
|
95 |
+ |
|
96 |
+ shd_log_action('delete', |
|
97 |
+ array( |
|
98 |
+ 'ticket' => $context['ticket_id'], |
|
99 |
+ 'subject' => $subject, |
|
100 |
+ ) |
|
101 |
+ ); |
|
102 |
+ |
|
103 |
+ // Expire the cache of count(active tickets) |
|
104 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
105 |
+ |
|
106 |
+ // Go to the home |
|
107 |
+ redirectexit('action=helpdesk;sa=main'); |
|
108 |
+} |
|
109 |
+ |
|
110 |
+function shd_reply_delete() |
|
111 |
+{ |
|
112 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
113 |
+ |
|
114 |
+ checkSession('get'); |
|
115 |
+ |
|
116 |
+ $_REQUEST['reply'] = !empty($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0; |
|
117 |
+ |
|
118 |
+ if (empty($_REQUEST['reply']) || empty($context['ticket_id'])) |
|
119 |
+ fatal_lang_error('shd_no_ticket'); |
|
120 |
+ |
|
121 |
+ // Check we can actually see the ticket we're deleting, that this reply is in this ticket and that we can delete this reply |
|
122 |
+ $query_ticket = shd_db_query('', ' |
|
123 |
+ SELECT hdt.id_ticket, hdtr.id_member, hdt.id_member_started, subject, status |
|
124 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
125 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_ticket = hdtr.id_ticket) |
|
126 |
+ WHERE {query_see_ticket} |
|
127 |
+ AND hdt.id_ticket = {int:ticket} |
|
128 |
+ AND hdtr.id_msg = {int:reply} |
|
129 |
+ AND hdt.id_first_msg != {int:reply2}', |
|
130 |
+ array( |
|
131 |
+ 'ticket' => $context['ticket_id'], |
|
132 |
+ 'reply' => $_REQUEST['reply'], |
|
133 |
+ 'reply2' => $_REQUEST['reply'], // since we can't delete the first message through the reply interface! |
|
134 |
+ ) |
|
135 |
+ ); |
|
136 |
+ |
|
137 |
+ if ($row = $smcFunc['db_fetch_assoc']($query_ticket)) |
|
138 |
+ { |
|
139 |
+ $smcFunc['db_free_result']($query_ticket); |
|
140 |
+ if (($row['status'] == TICKET_STATUS_CLOSED || $row['status'] == TICKET_STATUS_DELETED) || (!shd_allowed_to('shd_delete_ticket_any') && (!shd_allowed_to('shd_delete_ticket_own') || $user_info['id'] != $row['id_member']))) |
|
141 |
+ fatal_lang_error('shd_cannot_delete_reply', false); |
|
142 |
+ } |
|
143 |
+ else |
|
144 |
+ { |
|
145 |
+ $smcFunc['db_free_result']($query_ticket); |
|
146 |
+ fatal_lang_error('shd_no_ticket', false); |
|
147 |
+ } |
|
148 |
+ |
|
149 |
+ $subject = $row['subject']; |
|
150 |
+ |
|
151 |
+ // OK, let's clear this one, hasta la vista... ticket. |
|
152 |
+ shd_db_query('', ' |
|
153 |
+ UPDATE {db_prefix}helpdesk_ticket_replies |
|
154 |
+ SET message_status = {int:msg_status_deleted} |
|
155 |
+ WHERE id_msg = {int:reply}', |
|
156 |
+ array( |
|
157 |
+ 'msg_status_deleted' => MSG_STATUS_DELETED, |
|
158 |
+ 'reply' => $_REQUEST['reply'], |
|
159 |
+ ) |
|
160 |
+ ); |
|
161 |
+ |
|
162 |
+ // Logtastic! |
|
163 |
+ shd_log_action('delete_reply', |
|
164 |
+ array( |
|
165 |
+ 'ticket' => $context['ticket_id'], |
|
166 |
+ 'subject' => $subject, |
|
167 |
+ 'msg' => $_REQUEST['reply'], |
|
168 |
+ ) |
|
169 |
+ ); |
|
170 |
+ |
|
171 |
+ // OK, last but definitely not least, update num_replies and id_last_msg on the old ticket, and fix the old ticket's status |
|
172 |
+ list($starter, $replier, $num_replies) = shd_recalc_ids($context['ticket_id']); |
|
173 |
+ $query_reply = shd_db_query('', ' |
|
174 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
175 |
+ SET status = {int:status} |
|
176 |
+ WHERE id_ticket = {int:ticket}', |
|
177 |
+ array( |
|
178 |
+ 'ticket' => $context['ticket_id'], |
|
179 |
+ 'status' => shd_determine_status('deletereply', $starter, $replier, $num_replies), |
|
180 |
+ ) |
|
181 |
+ ); |
|
182 |
+ |
|
183 |
+ // Expire the cache of count(active tickets) |
|
184 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
185 |
+ |
|
186 |
+ // Back to the ticket |
|
187 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
188 |
+} |
|
189 |
+ |
|
190 |
+// Delete the given reply or ticket from the database. This is the final deletion which cannot be undone. |
|
191 |
+function shd_perma_delete() |
|
192 |
+{ |
|
193 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
194 |
+ |
|
195 |
+ checkSession('get'); |
|
196 |
+ shd_is_allowed_to('shd_delete_recycling'); |
|
197 |
+ |
|
198 |
+ // We have to have either a ticket or a reply to know what to delete (Or do you want me to drop your whole database? >:D) |
|
199 |
+ if (empty($context['ticket_id']) && empty($_REQUEST['reply'])) |
|
200 |
+ fatal_lang_error('shd_no_ticket', false); |
|
201 |
+ |
|
202 |
+ // If we're deleting a whole ticket... |
|
203 |
+ if (!empty($context['ticket_id']) && empty($_REQUEST['reply'])) |
|
204 |
+ { |
|
205 |
+ // Can we even see this ticket? |
|
206 |
+ $query_ticket = shd_db_query('', ' |
|
207 |
+ SELECT id_ticket, subject, id_member_started, status |
|
208 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
209 |
+ WHERE {query_see_ticket} |
|
210 |
+ AND id_ticket = {int:ticket}', |
|
211 |
+ array( |
|
212 |
+ 'ticket' => $context['ticket_id'], |
|
213 |
+ ) |
|
214 |
+ ); |
|
215 |
+ |
|
216 |
+ if ($smcFunc['db_num_rows']($query_ticket) == 0) |
|
217 |
+ { |
|
218 |
+ $smcFunc['db_free_result']($query_ticket); |
|
219 |
+ fatal_lang_error('shd_no_ticket', false); |
|
220 |
+ } |
|
221 |
+ else |
|
222 |
+ { |
|
223 |
+ $row = $smcFunc['db_fetch_assoc']($query_ticket); |
|
224 |
+ $smcFunc['db_free_result']($query_ticket); |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ if ($row['status'] != TICKET_STATUS_DELETED) |
|
228 |
+ fatal_lang_error('shd_cannot_delete_ticket', false); |
|
229 |
+ |
|
230 |
+ $subject = $row['subject']; |
|
231 |
+ // Expire the cache of count(active tickets) |
|
232 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
233 |
+ |
|
234 |
+ // Start by deleting the actual ticket. |
|
235 |
+ shd_db_query('', ' |
|
236 |
+ DELETE FROM {db_prefix}helpdesk_tickets |
|
237 |
+ WHERE id_ticket = {int:current_ticket}', |
|
238 |
+ array( |
|
239 |
+ 'current_ticket' => $context['ticket_id'], |
|
240 |
+ ) |
|
241 |
+ ); |
|
242 |
+ |
|
243 |
+ // Then remove any replies associated with it. |
|
244 |
+ shd_db_query('', ' |
|
245 |
+ DELETE FROM {db_prefix}helpdesk_ticket_replies |
|
246 |
+ WHERE id_ticket = {int:current_ticket}', |
|
247 |
+ array( |
|
248 |
+ 'current_ticket' => $context['ticket_id'], |
|
249 |
+ ) |
|
250 |
+ ); |
|
251 |
+ |
|
252 |
+ // And attachments... work out which attachments that is |
|
253 |
+ $query = shd_db_query('', ' |
|
254 |
+ SELECT id_attach |
|
255 |
+ FROM {db_prefix}helpdesk_attachments |
|
256 |
+ WHERE id_ticket = {int:ticket}', |
|
257 |
+ array( |
|
258 |
+ 'ticket' => $context['ticket_id'], |
|
259 |
+ ) |
|
260 |
+ ); |
|
261 |
+ |
|
262 |
+ $attachIDs = array(); |
|
263 |
+ while ($row = $smcFunc['db_fetch_row']($query)) |
|
264 |
+ $attachIDs[] = $row[0]; |
|
265 |
+ |
|
266 |
+ $smcFunc['db_free_result']($query); |
|
267 |
+ |
|
268 |
+ if (!empty($attachIDs)) |
|
269 |
+ { |
|
270 |
+ // OK, so we have some ids |
|
271 |
+ require_once($sourcedir . '/ManageAttachments.php'); |
|
272 |
+ $attachmentQuery = array( |
|
273 |
+ 'attachment_type' => 0, |
|
274 |
+ 'id_msg' => 0, |
|
275 |
+ 'id_attach' => $attachIDs, |
|
276 |
+ ); |
|
277 |
+ removeAttachments($attachmentQuery); |
|
278 |
+ } |
|
279 |
+ |
|
280 |
+ shd_log_action('permadelete', |
|
281 |
+ array( |
|
282 |
+ 'ticket' => $context['ticket_id'], |
|
283 |
+ 'subject' => $subject, |
|
284 |
+ ) |
|
285 |
+ ); |
|
286 |
+ |
|
287 |
+ redirectexit('action=helpdesk;sa=recyclebin'); |
|
288 |
+ } |
|
289 |
+ // Or just a single reply... |
|
290 |
+ elseif (!empty($_REQUEST['reply'])) |
|
291 |
+ { |
|
292 |
+ // Check we can actually see the ticket we're deleting, that this reply is in this ticket and that we can delete this reply |
|
293 |
+ $query_ticket = shd_db_query('', ' |
|
294 |
+ SELECT hdt.id_ticket, hdtr.id_member, hdt.subject, hdt.id_member_started, hdt.status, hdtr.message_status |
|
295 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
296 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_ticket = hdtr.id_ticket) |
|
297 |
+ WHERE {query_see_ticket} |
|
298 |
+ AND hdt.id_ticket = {int:ticket} |
|
299 |
+ AND hdtr.id_msg = {int:reply} |
|
300 |
+ AND hdt.id_first_msg != {int:reply2}', |
|
301 |
+ array( |
|
302 |
+ 'ticket' => $context['ticket_id'], |
|
303 |
+ 'reply' => $_REQUEST['reply'], |
|
304 |
+ 'reply2' => $_REQUEST['reply'], // since we can't delete the first message through the reply interface! |
|
305 |
+ ) |
|
306 |
+ ); |
|
307 |
+ |
|
308 |
+ if ($smcFunc['db_num_rows']($query_ticket) == 0) |
|
309 |
+ { |
|
310 |
+ $smcFunc['db_free_result']($query_ticket); |
|
311 |
+ fatal_lang_error('shd_no_ticket', false); |
|
312 |
+ } |
|
313 |
+ else |
|
314 |
+ { |
|
315 |
+ $row = $smcFunc['db_fetch_assoc']($query_ticket); |
|
316 |
+ $smcFunc['db_free_result']($query_ticket); |
|
317 |
+ } |
|
318 |
+ |
|
319 |
+ if ($row['status'] == TICKET_STATUS_DELETED || $row['message_status'] != MSG_STATUS_DELETED) |
|
320 |
+ fatal_lang_error('shd_cannot_delete_reply', false); |
|
321 |
+ |
|
322 |
+ $subject = $row['subject']; |
|
323 |
+ // Expire the cache of count(active tickets) |
|
324 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
325 |
+ |
|
326 |
+ // Just remove the reply. |
|
327 |
+ $query_reply = shd_db_query('', ' |
|
328 |
+ DELETE FROM {db_prefix}helpdesk_ticket_replies |
|
329 |
+ WHERE id_msg = {int:current_reply}', |
|
330 |
+ array( |
|
331 |
+ 'current_reply' => (int) $_REQUEST['reply'], |
|
332 |
+ ) |
|
333 |
+ ); |
|
334 |
+ |
|
335 |
+ // Now to handle attachments |
|
336 |
+ $query = shd_db_query('', ' |
|
337 |
+ SELECT id_attach |
|
338 |
+ FROM {db_prefix}helpdesk_attachments |
|
339 |
+ WHERE id_msg = {int:msg}', |
|
340 |
+ array( |
|
341 |
+ 'msg' => (int) $_REQUEST['reply'], |
|
342 |
+ ) |
|
343 |
+ ); |
|
344 |
+ |
|
345 |
+ $attachIDs = array(); |
|
346 |
+ while ($row = $smcFunc['db_fetch_row']($query)) |
|
347 |
+ $attachIDs[] = $row[0]; |
|
348 |
+ |
|
349 |
+ $smcFunc['db_free_result']($query); |
|
350 |
+ |
|
351 |
+ if (!empty($attachIDs)) |
|
352 |
+ { |
|
353 |
+ // OK, so we have some ids |
|
354 |
+ require_once($sourcedir . '/ManageAttachments.php'); |
|
355 |
+ $attachmentQuery = array( |
|
356 |
+ 'attachment_type' => 0, |
|
357 |
+ 'id_msg' => 0, |
|
358 |
+ 'id_attach' => $attachIDs, |
|
359 |
+ ); |
|
360 |
+ removeAttachments($attachmentQuery); |
|
361 |
+ } |
|
362 |
+ |
|
363 |
+ shd_log_action('permadelete_reply', |
|
364 |
+ array( |
|
365 |
+ 'ticket' => $context['ticket_id'], |
|
366 |
+ 'subject' => $subject, |
|
367 |
+ ) |
|
368 |
+ ); |
|
369 |
+ |
|
370 |
+ list($starter, $replier, $num_replies) = shd_recalc_ids($context['ticket_id']); |
|
371 |
+ $query_reply = shd_db_query('', ' |
|
372 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
373 |
+ SET status = {int:status} |
|
374 |
+ WHERE id_ticket = {int:ticket}', |
|
375 |
+ array( |
|
376 |
+ 'ticket' => $context['ticket_id'], |
|
377 |
+ 'status' => shd_determine_status('deletereply', $starter, $replier, $num_replies), |
|
378 |
+ ) |
|
379 |
+ ); |
|
380 |
+ |
|
381 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
382 |
+ } |
|
383 |
+ else |
|
384 |
+ fatal_lang_error('shd_no_ticket'); |
|
385 |
+} |
|
386 |
+ |
|
387 |
+// Restore the given ticket from the recycling bin. |
|
388 |
+function shd_ticket_restore() |
|
389 |
+{ |
|
390 |
+ global $smcFunc, $user_info, $context; |
|
391 |
+ |
|
392 |
+ checkSession('get'); |
|
393 |
+ |
|
394 |
+ if (empty($context['ticket_id'])) |
|
395 |
+ fatal_lang_error('shd_no_ticket', false); |
|
396 |
+ |
|
397 |
+ // Does the ticket we're trying to restore exist and can we see it? |
|
398 |
+ $query_ticket = shd_db_query('', ' |
|
399 |
+ SELECT id_ticket, id_member_started, id_member_updated, subject, num_replies, status |
|
400 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
401 |
+ WHERE {query_see_ticket} |
|
402 |
+ AND id_ticket = {int:ticket}', |
|
403 |
+ array( |
|
404 |
+ 'ticket' => $context['ticket_id'], |
|
405 |
+ ) |
|
406 |
+ ); |
|
407 |
+ |
|
408 |
+ if ($row = $smcFunc['db_fetch_assoc']($query_ticket)) |
|
409 |
+ { |
|
410 |
+ $smcFunc['db_free_result']($query_ticket); |
|
411 |
+ if ($row['status'] != TICKET_STATUS_DELETED || (!shd_allowed_to('shd_restore_ticket_any') && (!shd_allowed_to('shd_restore_ticket_own') || $user_info['id'] != $row['id_member_started']))) |
|
412 |
+ fatal_lang_error('shd_cannot_restore_ticket', false); |
|
413 |
+ |
|
414 |
+ $subject = $row['subject']; |
|
415 |
+ $starter = $row['id_member_started']; |
|
416 |
+ $replier = $row['id_member_updated']; |
|
417 |
+ $num_replies = $row['num_replies']; |
|
418 |
+ } |
|
419 |
+ else |
|
420 |
+ { |
|
421 |
+ $smcFunc['db_free_result']($query_ticket); |
|
422 |
+ fatal_lang_error('shd_no_ticket', false); |
|
423 |
+ } |
|
424 |
+ |
|
425 |
+ shd_db_query('', ' |
|
426 |
+ UPDATE {db_prefix}helpdesk_tickets AS hdt |
|
427 |
+ SET status = {int:status_new} |
|
428 |
+ WHERE id_ticket = {int:current_ticket} |
|
429 |
+ AND {query_see_ticket}', |
|
430 |
+ array( |
|
431 |
+ 'current_ticket' => $context['ticket_id'], |
|
432 |
+ 'status_new' => shd_determine_status('restoreticket', $starter, $replier, $num_replies), |
|
433 |
+ ) |
|
434 |
+ ); |
|
435 |
+ |
|
436 |
+ // Expire the cache of count(active tickets) |
|
437 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
438 |
+ |
|
439 |
+ shd_log_action('restore', |
|
440 |
+ array( |
|
441 |
+ 'ticket' => $context['ticket_id'], |
|
442 |
+ 'subject' => $subject, |
|
443 |
+ ) |
|
444 |
+ ); |
|
445 |
+ |
|
446 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
447 |
+} |
|
448 |
+ |
|
449 |
+// Restore the given reply from the recycling bin. |
|
450 |
+function shd_reply_restore() |
|
451 |
+{ |
|
452 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
453 |
+ |
|
454 |
+ checkSession('get'); |
|
455 |
+ |
|
456 |
+ $_REQUEST['reply'] = empty($_REQUEST['reply']) ? 0 : (int) $_REQUEST['reply']; |
|
457 |
+ |
|
458 |
+ if (empty($_REQUEST['reply'])) |
|
459 |
+ fatal_lang_error('shd_no_ticket', false); |
|
460 |
+ |
|
461 |
+ // Check we can actually see the ticket we're restoring from, and that we can restore this reply |
|
462 |
+ $query_ticket = shd_db_query('', ' |
|
463 |
+ SELECT hdt.id_ticket, hdtr.id_member, hdt.id_member_started, hdt.id_member_updated, hdt.num_replies, hdt.subject, hdt.status, hdtr.message_status |
|
464 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
465 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_ticket = hdtr.id_ticket) |
|
466 |
+ WHERE {query_see_ticket} |
|
467 |
+ AND hdtr.id_msg = {int:reply} |
|
468 |
+ AND hdt.id_first_msg != {int:reply2}', |
|
469 |
+ array( |
|
470 |
+ 'reply' => $_REQUEST['reply'], |
|
471 |
+ 'reply2' => $_REQUEST['reply'], |
|
472 |
+ ) |
|
473 |
+ ); |
|
474 |
+ |
|
475 |
+ if ($row = $smcFunc['db_fetch_assoc']($query_ticket)) |
|
476 |
+ { |
|
477 |
+ $smcFunc['db_free_result']($query_ticket); |
|
478 |
+ if (($row['status'] == TICKET_STATUS_DELETED || $row['status'] == TICKET_STATUS_CLOSED || $row['message_status'] != MSG_STATUS_DELETED) || (!shd_allowed_to('shd_restore_reply_any') && (!shd_allowed_to('shd_restore_reply_own') || $user_info['id'] != $row['id_member']))) |
|
479 |
+ fatal_lang_error('shd_cannot_restore_reply', false); |
|
480 |
+ |
|
481 |
+ $context['ticket_id'] = (int) $row['id_ticket']; |
|
482 |
+ $subject = $row['subject']; |
|
483 |
+ $starter = $row['id_member_started']; |
|
484 |
+ $replier = $row['id_member_updated']; |
|
485 |
+ $num_replies = $row['num_replies']; |
|
486 |
+ } |
|
487 |
+ else |
|
488 |
+ { |
|
489 |
+ $smcFunc['db_free_result']($query_ticket); |
|
490 |
+ fatal_lang_error('shd_no_ticket', false); |
|
491 |
+ } |
|
492 |
+ |
|
493 |
+ // OK, let's clear this one, hasta la vista... ticket. |
|
494 |
+ shd_db_query('', ' |
|
495 |
+ UPDATE {db_prefix}helpdesk_ticket_replies |
|
496 |
+ SET message_status = {int:msg_status_deleted} |
|
497 |
+ WHERE id_msg = {int:reply}', |
|
498 |
+ array( |
|
499 |
+ 'msg_status_deleted' => MSG_STATUS_NORMAL, |
|
500 |
+ 'reply' => $_REQUEST['reply'], |
|
501 |
+ ) |
|
502 |
+ ); |
|
503 |
+ |
|
504 |
+ // Captain's Log, stardate 18.3.10.1010 |
|
505 |
+ shd_log_action('restore_reply', |
|
506 |
+ array( |
|
507 |
+ 'ticket' => $context['ticket_id'], |
|
508 |
+ 'subject' => $subject, |
|
509 |
+ 'msg' => $_REQUEST['reply'], |
|
510 |
+ ) |
|
511 |
+ ); |
|
512 |
+ |
|
513 |
+ // Fix the topic data |
|
514 |
+ list($starter, $replier, $num_replies) = shd_recalc_ids($context['ticket_id']); |
|
515 |
+ $query_reply = shd_db_query('', ' |
|
516 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
517 |
+ SET status = {int:status} |
|
518 |
+ WHERE id_ticket = {int:ticket}', |
|
519 |
+ array( |
|
520 |
+ 'ticket' => $context['ticket_id'], |
|
521 |
+ 'status' => shd_determine_status('restorereply', $starter, $replier, $num_replies), |
|
522 |
+ ) |
|
523 |
+ ); |
|
524 |
+ |
|
525 |
+ // Expire the cache of count(active tickets) |
|
526 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
527 |
+ |
|
528 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
529 |
+} |
|
530 |
+ |
|
531 |
+/** |
|
532 |
+ * Clean up tickets that have been modified by replies being altered through restore and delete. |
|
533 |
+ * |
|
534 |
+ * Operations: |
|
535 |
+ * - Identify how many deleted and non deleted replies there are in the ticket. |
|
536 |
+ * - Identify the last non deleted reply in the ticket (if there are no undeleted replies, use the ticket post itself for cohesion) |
|
537 |
+ * - Update the ticket's record with the first and last posters, as well as the correct number of active and deleted replies, and whether there are any deleted replies on the ticket generally |
|
538 |
+ * |
|
539 |
+ * @param int $ticket The ticket id to recalculate. |
|
540 |
+ * |
|
541 |
+ * @return array An array detailing the user id of the starter, the last replier and the number of active replies in a ticket. |
|
542 |
+*/ |
|
543 |
+function shd_recalc_ids($ticket) |
|
544 |
+{ |
|
545 |
+ global $smcFunc; |
|
546 |
+ |
|
547 |
+ $query = shd_db_query('', ' |
|
548 |
+ SELECT hdt.id_first_msg |
|
549 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
550 |
+ WHERE hdt.id_ticket = {int:ticket}', |
|
551 |
+ array( |
|
552 |
+ 'ticket' => $ticket, |
|
553 |
+ ) |
|
554 |
+ ); |
|
555 |
+ list($first_msg) = $smcFunc['db_fetch_row']($query); |
|
556 |
+ $smcFunc['db_free_result']($query); |
|
557 |
+ |
|
558 |
+ $query = shd_db_query('', ' |
|
559 |
+ SELECT hdtr.message_status, COUNT(hdtr.message_status) AS messages, hdt.id_first_msg, MAX(hdtr.id_msg) AS id_last_msg |
|
560 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
561 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdt.id_ticket = hdtr.id_ticket) |
|
562 |
+ WHERE hdtr.id_msg > hdt.id_first_msg |
|
563 |
+ AND hdt.id_ticket = {int:ticket} |
|
564 |
+ GROUP BY hdtr.message_status', |
|
565 |
+ array( |
|
566 |
+ 'ticket' => $ticket, |
|
567 |
+ ) |
|
568 |
+ ); |
|
569 |
+ |
|
570 |
+ $messages = array( |
|
571 |
+ MSG_STATUS_NORMAL => 0, // message_status = 0 |
|
572 |
+ MSG_STATUS_DELETED => 0, // message_status = 1 |
|
573 |
+ ); |
|
574 |
+ |
|
575 |
+ $last_msg = 0; |
|
576 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
577 |
+ { |
|
578 |
+ $first_msg = $row['id_first_msg']; |
|
579 |
+ $messages[$row['message_status']] = $row['messages']; |
|
580 |
+ if ($row['message_status'] == MSG_STATUS_NORMAL) |
|
581 |
+ $last_msg = $row['id_last_msg']; |
|
582 |
+ } |
|
583 |
+ |
|
584 |
+ $smcFunc['db_free_result']($query); |
|
585 |
+ |
|
586 |
+ if (empty($last_msg)) |
|
587 |
+ $last_msg = $first_msg; |
|
588 |
+ |
|
589 |
+ // OK, so we have the last message id and correct number of replies, which is awesome. Now we need to ensure user ids are right |
|
590 |
+ $query = shd_db_query('', ' |
|
591 |
+ SELECT hdtr_first.id_member, hdtr_last.id_member |
|
592 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
593 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdtr_first.id_msg = {int:first_msg}) |
|
594 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdtr_last.id_msg = {int:last_msg}) |
|
595 |
+ WHERE hdt.id_ticket = {int:ticket}', |
|
596 |
+ array( |
|
597 |
+ 'first_msg' => $first_msg, |
|
598 |
+ 'last_msg' => $last_msg, |
|
599 |
+ 'ticket' => $ticket, |
|
600 |
+ ) |
|
601 |
+ ); |
|
602 |
+ list($starter, $replier) = $smcFunc['db_fetch_row']($query); |
|
603 |
+ $smcFunc['db_free_result']($query); |
|
604 |
+ |
|
605 |
+ shd_db_query('', ' |
|
606 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
607 |
+ SET num_replies = {int:num_replies}, |
|
608 |
+ deleted_replies = {int:deleted_replies}, |
|
609 |
+ id_last_msg = {int:last_msg}, |
|
610 |
+ id_member_started = {int:starter}, |
|
611 |
+ id_member_updated = {int:replier}, |
|
612 |
+ withdeleted = {int:has_deleted} |
|
613 |
+ WHERE id_ticket = {int:ticket}', |
|
614 |
+ array( |
|
615 |
+ 'num_replies' => $messages[MSG_STATUS_NORMAL], |
|
616 |
+ 'deleted_replies' => $messages[MSG_STATUS_DELETED], |
|
617 |
+ 'last_msg' => $last_msg, |
|
618 |
+ 'starter' => $starter, |
|
619 |
+ 'replier' => $replier, |
|
620 |
+ 'has_deleted' => ($messages[MSG_STATUS_DELETED] > 0) ? 1 : 0, |
|
621 |
+ 'ticket' => $ticket, |
|
622 |
+ ) |
|
623 |
+ ); |
|
624 |
+ |
|
625 |
+ return array($starter, $replier, $messages[MSG_STATUS_NORMAL]); |
|
626 |
+} |
|
627 |
+ |
|
628 |
+?> |
|
0 | 629 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,725 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Display.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file sets up the regular ticket view, including the menu of operations that can |
|
22 |
+ * be applied to a ticket. It is also resposible for setting up the AJAX items for modifying privacy and urgency from |
|
23 |
+ * the ticket view itself, as well as all the handling responsible for Quick Reply including the 'Go Advanced' mode. |
|
24 |
+ * |
|
25 |
+ * @package source |
|
26 |
+ * @since 1.0 |
|
27 |
+*/ |
|
28 |
+ |
|
29 |
+if (!defined('SMF')) |
|
30 |
+ die('Hacking attempt...'); |
|
31 |
+ |
|
32 |
+/** |
|
33 |
+ * Loads all the data and sets all the options for displaying a ticket. |
|
34 |
+ * |
|
35 |
+ * This function does a lot of work in setting up a ticket to be displayed: |
|
36 |
+ * <ul> |
|
37 |
+ * <li>Invokes shd_load_ticket() to get the principle data</li> |
|
38 |
+ * <li>Creates $context['ticket'] to hold the data block, some of which is derived from the return of shd_load_ticket(): |
|
39 |
+ * <ul> |
|
40 |
+ * <li>id: regular numeric ticket id</li> |
|
41 |
+ * <li>display_id: zero padded ticket id (e.g. 00001)</li> |
|
42 |
+ * <li>subject: censored version of the subject</li> |
|
43 |
+ * <li>first_msg: id of the opening post that forms the ticket body</li> |
|
44 |
+ * <li>body: formatted (parsed for smileys and bbcode) version of the ticket post</li> |
|
45 |
+ * <li>id_member: user id of the ticket's poster</li> |
|
46 |
+ * <li>id_member_assigned: user id of the ticket's assigned user</li> |
|
47 |
+ * <li>member: hash array of the ticket poster's details: |
|
48 |
+ * <ul> |
|
49 |
+ * <li>id: their user id</li> |
|
50 |
+ * <li>name: the name stated in the ticket post for that use</li> |
|
51 |
+ * <li>link: link to the profile of the user</li> |
|
52 |
+ * </ul> |
|
53 |
+ * </li> |
|
54 |
+ * <li>assigned: hash array of the assignee of the ticket: |
|
55 |
+ * <ul> |
|
56 |
+ * <li>id: their user id</li> |
|
57 |
+ * <li>name: name of the assignee, or 'Unassigned'</li> |
|
58 |
+ * <li>link: a full HTML link to their profile, or 'Unassigned' in red text</li> |
|
59 |
+ * </ul> |
|
60 |
+ * </li> |
|
61 |
+ * <li>assigned_self: boolean, whether the ticket is assigned to the current user or not</li> |
|
62 |
+ * <li>ticket_opener: boolean, whether the current user is the user who opened this ticket</li> |
|
63 |
+ * <li>urgency: hash array |
|
64 |
+ * <ul> |
|
65 |
+ * <li>level: numeric identifier of current ticket urgency</li> |
|
66 |
+ * <li>label: the HTML label of the urgency, including being in red for "Very High" or above</li> |
|
67 |
+ * <li>increase: Boolean, whether the current ticket urgency can be increased given the current ticket state and user permissions</li> |
|
68 |
+ * <li>decrease: Boolean, whether the current ticket urgency can be increased given the current ticket state and user permissions</li> |
|
69 |
+ * </ul> |
|
70 |
+ * </li> |
|
71 |
+ * <li>status: hash array |
|
72 |
+ * <ul> |
|
73 |
+ * <li>level: numeric, current status identifier</li> |
|
74 |
+ * <li>label: string representing the current status</li> |
|
75 |
+ * </ul> |
|
76 |
+ * <li>num_replies: the number of replies to the ticket so far</li> |
|
77 |
+ * <li>deleted_replies: how many deleted replies in this ticket</li> |
|
78 |
+ * <li>poster_time: formatted string containing the time the ticket was opened</li> |
|
79 |
+ * <li>privacy: hash array |
|
80 |
+ * <ul> |
|
81 |
+ * <li>label: current label to be used with the privacy item</li> |
|
82 |
+ * <li>can_change: Boolean, whether the user's permission with this ticket allows us to edit the ticket privacy</li> |
|
83 |
+ * </ul> |
|
84 |
+ * </li> |
|
85 |
+ * <li>closed: Boolean, represents whether this ticket is closed (used a lot with the navigation menu)</li> |
|
86 |
+ * <li>deleted: Boolean, represents whether this ticket is deleted (used a lot with the navigation menu)</li> |
|
87 |
+ * <li>ip_address: IP address logged at the time the ticket was opened; if moderate_forum_members permission is available, this will be a link to the track IP area</li> |
|
88 |
+ * <li>modified: if the ticket has been modified, also get the modified details: |
|
89 |
+ * <ul> |
|
90 |
+ * <li>id: user id who edited the ticket (not always available)</li> |
|
91 |
+ * <li>time: formatted string of the time the post was edited</li> |
|
92 |
+ * <li>timestamp: raw timestamp of the time the post was edited</li> |
|
93 |
+ * <li>name: user name of the editing user; if we have a definite user id, this should contain the current name, falling back to the previously stored name</li> |
|
94 |
+ * <li>link: if we have a known, valid user id for the post's editor, this will contain a link to their profile, with the link text using their current display name; alternatively it will contain a regular string which is the username stored with the edit.</li> |
|
95 |
+ * </ul> |
|
96 |
+ * </li> |
|
97 |
+ * <li>display_recycle: Either holds the $txt identifier of the message to apply as a warning, or false if displaying of recycling stuff in this ticket isn't appropriate (either for permissions or just because of no deleted replies, or we're just in regular ticket view)</li> |
|
98 |
+ * </ul> |
|
99 |
+ * </li> |
|
100 |
+ * <li>define the page index with SMF's constructPageIndex</li> |
|
101 |
+ * <li>query for all the ids of messages we might display, followed by querying for the message details themselves, pushing that query resource to $reply_request so we can use it in shd_view_replies() later</li> |
|
102 |
+ * <li>load details of all the users applicable for posts in this page</li> |
|
103 |
+ * <li>request all the visible attachments from {@link shd_display_load_attachments()}</li> |
|
104 |
+ * <li>since we are viewing this ticket, mark it read</li> |
|
105 |
+ * <li>set up the breadcrumb trail</li> |
|
106 |
+ * <li>set up the ticket navigation menu</li> |
|
107 |
+ * <li>call in the editor component from SimpleDesk-Post.php and friends, ready for Quick Reply</li> |
|
108 |
+ * <li>invoke the different Javascript objects that are applicable on the page: |
|
109 |
+ * <ul> |
|
110 |
+ * <li>privacy changer</li> |
|
111 |
+ * <li>urgency changer</li> |
|
112 |
+ * <li>quick reply / quote / go advanced</li> |
|
113 |
+ * </ul> |
|
114 |
+ * </li> |
|
115 |
+ * </ul> |
|
116 |
+ * |
|
117 |
+ * @see shd_prepare_ticket_context() |
|
118 |
+ * @since 1.0 |
|
119 |
+*/ |
|
120 |
+function shd_view_ticket() |
|
121 |
+{ |
|
122 |
+ global $context, $txt, $scripturl, $settings, $reply_request, $smcFunc, $modSettings, $memberContext, $sourcedir, $user_info, $options; |
|
123 |
+ |
|
124 |
+ loadTemplate('SimpleDesk-Display'); |
|
125 |
+ |
|
126 |
+ $ticketinfo = shd_load_ticket(); |
|
127 |
+ |
|
128 |
+ // How much are we sticking on each page? |
|
129 |
+ $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages']; |
|
130 |
+ |
|
131 |
+ censorText($ticketinfo['subject']); |
|
132 |
+ censorText($ticketinfo['body']); |
|
133 |
+ |
|
134 |
+ $context['user_list'] = array(); // as we go along, build a list of users who are relevant |
|
135 |
+ |
|
136 |
+ $context['ticket'] = array( |
|
137 |
+ 'id' => $context['ticket_id'], |
|
138 |
+ 'display_id' => str_pad($context['ticket_id'], 5, '0', STR_PAD_LEFT), |
|
139 |
+ 'subject' => $ticketinfo['subject'], |
|
140 |
+ 'first_msg' => $ticketinfo['id_first_msg'], |
|
141 |
+ 'body' => shd_format_text($ticketinfo['body'], $ticketinfo['smileys_enabled'], 'shd_ticket_' . $context['ticket_id']), |
|
142 |
+ 'id_member' => $ticketinfo['id_member'], |
|
143 |
+ 'id_member_assigned' => $ticketinfo['assigned_id'], |
|
144 |
+ 'member' => array( |
|
145 |
+ 'id' => $ticketinfo['starter_id'], |
|
146 |
+ 'name' => $ticketinfo['starter_name'], |
|
147 |
+ 'link' => shd_profile_link($ticketinfo['starter_name'], $ticketinfo['starter_id']), |
|
148 |
+ ), |
|
149 |
+ 'assigned' => array( |
|
150 |
+ 'id' => $ticketinfo['assigned_id'], |
|
151 |
+ 'name' => ($ticketinfo['assigned_id'] > 0) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], |
|
152 |
+ 'link' => ($ticketinfo['assigned_id'] > 0) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
153 |
+ ), |
|
154 |
+ 'assigned_self' => $ticketinfo['assigned_id'] == $user_info['id'], |
|
155 |
+ 'ticket_opener' => $ticketinfo['starter_id'] == $user_info['id'], |
|
156 |
+ 'urgency' => array( |
|
157 |
+ 'level' => $ticketinfo['urgency'], |
|
158 |
+ 'label' => $ticketinfo['urgency'] > TICKET_URGENCY_HIGH ? '<span class="error">' . $txt['shd_urgency_' . $ticketinfo['urgency']] . '</span>' : $txt['shd_urgency_' . $ticketinfo['urgency']], |
|
159 |
+ ), |
|
160 |
+ 'status' => array( |
|
161 |
+ 'level' => $ticketinfo['status'], |
|
162 |
+ 'label' => $txt['shd_status_' . $ticketinfo['status']], |
|
163 |
+ ), |
|
164 |
+ 'num_replies' => $ticketinfo['num_replies'], |
|
165 |
+ 'deleted_replies' => $ticketinfo['deleted_replies'], |
|
166 |
+ 'poster_time' => timeformat($ticketinfo['poster_time']), |
|
167 |
+ 'privacy' => array( |
|
168 |
+ 'label' => $ticketinfo['private'] ? $txt['shd_ticket_private'] : $txt['shd_ticket_notprivate'], |
|
169 |
+ 'can_change' => shd_allowed_to('shd_alter_privacy_any') || (shd_allowed_to('shd_alter_privacy_own') && $ticketinfo['id_member'] == $user_info['id']), |
|
170 |
+ ), |
|
171 |
+ 'closed' => $ticketinfo['closed'], |
|
172 |
+ 'deleted' => $ticketinfo['deleted'], |
|
173 |
+ 'ip_address' => $ticketinfo['link_ip'] ? ('<a href="' . $scripturl . '?action=trackip;searchip=' . $ticketinfo['starter_ip'] . '">' . $ticketinfo['starter_ip'] . '</a>') : $ticketinfo['starter_ip'], |
|
174 |
+ ); |
|
175 |
+ |
|
176 |
+ // Stuff concerning whether the ticket is deleted or not |
|
177 |
+ // Display recycling stuff if: ticket is deleted (if we can see it, we can see the bin) OR ticket has deleted replies and we can see the bin and we requested to see them |
|
178 |
+ $context['ticket']['display_recycle_replies'] = true; |
|
179 |
+ if ($context['ticket']['deleted']) |
|
180 |
+ $context['ticket']['display_recycle'] = $txt['shd_ticket_has_been_deleted']; |
|
181 |
+ elseif ($context['ticket']['deleted_replies'] > 0) |
|
182 |
+ { |
|
183 |
+ if (shd_allowed_to('shd_access_recyclebin')) |
|
184 |
+ { |
|
185 |
+ $context['ticket']['display_recycle'] = $txt['shd_ticket_replies_deleted']; |
|
186 |
+ $ticketlink = $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . (isset($_REQUEST['recycle']) ? '' : ';recycle'); |
|
187 |
+ $context['ticket']['display_recycle'] .= ' ' . sprintf((isset($_REQUEST['recycle']) ? $txt['shd_ticket_replies_deleted_view'] : $txt['shd_ticket_replies_deleted_link']), $ticketlink); |
|
188 |
+ $context['ticket']['display_recycle_replies'] = (isset($_REQUEST['recycle'])); |
|
189 |
+ } |
|
190 |
+ else |
|
191 |
+ $context['ticket']['display_recycle_replies'] = false; |
|
192 |
+ } |
|
193 |
+ else |
|
194 |
+ { |
|
195 |
+ $context['ticket']['display_recycle'] = false; |
|
196 |
+ $context['ticket']['display_recycle_replies'] = false; |
|
197 |
+ } |
|
198 |
+ |
|
199 |
+ // Ticket privacy |
|
200 |
+ $context['ticket']['privacy']['can_change'] = $context['ticket']['privacy']['can_change'] && (!$context['ticket']['closed'] && !$context['ticket']['deleted']); |
|
201 |
+ if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') |
|
202 |
+ $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any') || shd_allowed_to('shd_alter_privacy_own') || shd_allowed_to('shd_alter_privacy_any') || $ticketinfo['private']; |
|
203 |
+ else |
|
204 |
+ $context['display_private'] = true; |
|
205 |
+ |
|
206 |
+ $context['link_ip_address'] = $ticketinfo['link_ip']; |
|
207 |
+ |
|
208 |
+ if ($ticketinfo['modified_time'] > 0) |
|
209 |
+ { |
|
210 |
+ $context['ticket']['modified'] = array( |
|
211 |
+ 'id' => $ticketinfo['modified_id'], |
|
212 |
+ 'name' => $ticketinfo['modified_name'], |
|
213 |
+ 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id']), |
|
214 |
+ 'timestamp' => $ticketinfo['modified_time'], |
|
215 |
+ 'time' => timeformat($ticketinfo['modified_time']), |
|
216 |
+ ); |
|
217 |
+ } |
|
218 |
+ |
|
219 |
+ $context['ticket']['urgency'] += shd_can_alter_urgency($ticketinfo['urgency'], $ticketinfo['starter_id'], $ticketinfo['closed'], $ticketinfo['deleted']); |
|
220 |
+ |
|
221 |
+ $context['page_index'] = shd_no_expand_pageindex($scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '.%1$d' . (isset($_REQUEST['recycle']) ? ';recycle' : '') . '#replies', $context['ticket_start'], (empty($context['display_recycle']) ? $context['ticket']['num_replies'] : (int) $context['ticket']['num_replies'] + (int) $context['ticket']['deleted_replies']), $context['messages_per_page'], true); |
|
222 |
+ |
|
223 |
+ $context['get_replies'] = 'shd_prepare_ticket_context'; |
|
224 |
+ |
|
225 |
+ $query = shd_db_query('', ' |
|
226 |
+ SELECT id_msg, id_member, modified_member |
|
227 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
228 |
+ WHERE id_ticket = {int:ticket} |
|
229 |
+ AND id_msg > {int:first_msg}' . (!empty($context['ticket']['display_recycle_replies']) ? '' : ' |
|
230 |
+ AND message_status = {int:msg_status}') . ' |
|
231 |
+ ORDER BY id_msg ' . ($context['messages_per_page'] == -1 ? '' : ' |
|
232 |
+ LIMIT ' . $context['ticket_start'] . ', ' . $context['messages_per_page']), |
|
233 |
+ array( |
|
234 |
+ 'ticket' => $context['ticket_id'], |
|
235 |
+ 'first_msg' => $ticketinfo['id_first_msg'], |
|
236 |
+ 'msg_status' => MSG_STATUS_NORMAL, |
|
237 |
+ ) |
|
238 |
+ ); |
|
239 |
+ |
|
240 |
+ $context['ticket_messages'] = array(); |
|
241 |
+ $posters = array(); |
|
242 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
243 |
+ { |
|
244 |
+ if (!empty($row['id_member'])) |
|
245 |
+ $posters[] = $row['id_member']; |
|
246 |
+ |
|
247 |
+ if (!empty($row['modified_member'])) |
|
248 |
+ $posters[] = $row['modified_member']; |
|
249 |
+ |
|
250 |
+ $context['ticket_messages'][] = $row['id_msg']; |
|
251 |
+ } |
|
252 |
+ $smcFunc['db_free_result']($query); |
|
253 |
+ |
|
254 |
+ // We might want the OP's avatar, add 'em to the list -- just in case. |
|
255 |
+ $posters[] = $context['ticket']['id_member']; |
|
256 |
+ |
|
257 |
+ $posters = array_unique($posters); |
|
258 |
+ |
|
259 |
+ $context['is_team'] = array(); |
|
260 |
+ // Get the poster data |
|
261 |
+ if (!empty($posters)) |
|
262 |
+ { |
|
263 |
+ loadMemberData($posters); |
|
264 |
+ |
|
265 |
+ // Are they current team members? |
|
266 |
+ $team = array_intersect($posters, shd_members_allowed_to('shd_staff')); |
|
267 |
+ |
|
268 |
+ foreach ($team as $member) |
|
269 |
+ $context['is_team'][$member] = true; |
|
270 |
+ } |
|
271 |
+ |
|
272 |
+ if (!empty($context['ticket_messages'])) |
|
273 |
+ { |
|
274 |
+ $reply_request = shd_db_query('', ' |
|
275 |
+ SELECT |
|
276 |
+ id_msg, poster_time, poster_ip, id_member, modified_time, modified_name, modified_member, body, |
|
277 |
+ smileys_enabled, poster_name, poster_email, message_status |
|
278 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
279 |
+ WHERE id_msg IN ({array_int:message_list})' . (!empty($context['ticket']['display_recycle']) ? '' : ' |
|
280 |
+ AND message_status IN ({array_int:msg_normal})') . ' |
|
281 |
+ ORDER BY id_msg', |
|
282 |
+ array( |
|
283 |
+ 'message_list' => $context['ticket_messages'], |
|
284 |
+ 'msg_normal' => array(MSG_STATUS_NORMAL), |
|
285 |
+ ) |
|
286 |
+ ); |
|
287 |
+ } |
|
288 |
+ else |
|
289 |
+ { |
|
290 |
+ $reply_request = false; |
|
291 |
+ $context['first_message'] = 0; |
|
292 |
+ $context['first_new_message'] = false; |
|
293 |
+ } |
|
294 |
+ |
|
295 |
+ // Grab the avatar for the poster |
|
296 |
+ $context['ticket']['poster_avatar'] = empty($context['ticket']['member']['id']) ? array() : (loadMemberContext($context['ticket']['id_member']) ? $memberContext[$context['ticket']['id_member']]['avatar'] : array()); |
|
297 |
+ |
|
298 |
+ // Before we grab attachments, also make sure we get any from the first msg (i.e. the ticket) |
|
299 |
+ $context['ticket_messages'][] = $context['ticket']['first_msg']; |
|
300 |
+ shd_display_load_attachments(); |
|
301 |
+ |
|
302 |
+ // Mark read goes here |
|
303 |
+ if (!empty($user_info['id'])) |
|
304 |
+ { |
|
305 |
+ $smcFunc['db_insert']('replace', |
|
306 |
+ '{db_prefix}helpdesk_log_read', |
|
307 |
+ array( |
|
308 |
+ 'id_ticket' => 'int', 'id_member' => 'int', 'id_msg' => 'int', |
|
309 |
+ ), |
|
310 |
+ array( |
|
311 |
+ $context['ticket_id'], $user_info['id'], $ticketinfo['id_last_msg'], |
|
312 |
+ ), |
|
313 |
+ array('id_member', 'id_topic') |
|
314 |
+ ); |
|
315 |
+ } |
|
316 |
+ |
|
317 |
+ // Build the link tree. If the ticket is recycled, display 'Recycle bin', else 'Tickets'. |
|
318 |
+ $context['linktree'][] = array( |
|
319 |
+ 'url' => $context['ticket']['status']['level'] == TICKET_STATUS_DELETED ? $scripturl . '?action=helpdesk;sa=recyclebin' : $scripturl . '?action=helpdesk;sa=main', |
|
320 |
+ 'name' => $context['ticket']['status']['level'] == TICKET_STATUS_DELETED ? $txt['shd_recycle_bin'] : $txt['shd_linktree_tickets'], |
|
321 |
+ ); |
|
322 |
+ // If it's closed, add that to the linktree. |
|
323 |
+ if ($context['ticket']['status']['level'] == TICKET_STATUS_CLOSED) |
|
324 |
+ $context['linktree'][] = array( |
|
325 |
+ 'url' => $scripturl . '?action=helpdesk;sa=closedtickets', |
|
326 |
+ 'name' => $txt['shd_tickets_closed'], |
|
327 |
+ ); |
|
328 |
+ // Lastly add the ticket name and link. |
|
329 |
+ $context['linktree'][] = array( |
|
330 |
+ 'url' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'], |
|
331 |
+ 'name' => $context['ticket']['subject'], |
|
332 |
+ ); |
|
333 |
+ |
|
334 |
+ // Template stuff |
|
335 |
+ $context['sub_template'] = 'viewticket'; |
|
336 |
+ $context['page_title'] = $txt['shd_helpdesk'] . ' [' . $context['ticket']['display_id'] . '] ' . $context['ticket']['subject']; |
|
337 |
+ |
|
338 |
+ // Ticket navigation |
|
339 |
+ $context['can_reply'] = !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_reply_ticket_any') || ($context['ticket']['ticket_opener'] && shd_allowed_to('shd_reply_ticket_own'))); // needs perms - calc'd here because we use it in display template too |
|
340 |
+ $context['can_quote'] = $context['can_reply'] && !empty($modSettings['shd_allow_ticket_bbc']); |
|
341 |
+ $context['can_go_advanced'] = !empty($modSettings['shd_allow_ticket_bbc']) || !empty($modSettings['allow_ticket_smileys']) || shd_allowed_to('shd_post_attachment'); |
|
342 |
+ $context['can_see_ip'] = shd_allowed_to('shd_staff'); |
|
343 |
+ |
|
344 |
+ $context['ticket_navigation'] = array(); |
|
345 |
+ $context['ticket_navigation'][] = array( |
|
346 |
+ 'url' => $scripturl . '?action=helpdesk;sa=editticket;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
347 |
+ 'icon' => 'edit', |
|
348 |
+ 'alt' => '*', |
|
349 |
+ 'display' => !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_edit_reply_any') || ($context['ticket']['ticket_opener'] && shd_allowed_to('shd_edit_reply_own'))), |
|
350 |
+ 'text' => 'shd_ticket_edit', |
|
351 |
+ ); |
|
352 |
+ $context['ticket_navigation'][] = array( |
|
353 |
+ 'url' => $scripturl . '?action=helpdesk;sa=markunread;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
354 |
+ 'icon' => 'unread', |
|
355 |
+ 'alt' => '*', |
|
356 |
+ 'display' => !$context['ticket']['closed'] && !$context['ticket']['deleted'], |
|
357 |
+ 'text' => 'shd_ticket_markunread', |
|
358 |
+ ); |
|
359 |
+ $context['ticket_navigation'][] = array( |
|
360 |
+ 'url' => $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
361 |
+ 'icon' => !$context['ticket']['closed'] ? 'resolved' : 'unresolved', |
|
362 |
+ 'alt' => '*', |
|
363 |
+ 'display' => !$context['ticket']['deleted'] && (shd_allowed_to('shd_resolve_ticket_any') || (shd_allowed_to('shd_resolve_ticket_own') && $context['ticket']['ticket_opener'])), |
|
364 |
+ 'text' => !$context['ticket']['closed'] ? 'shd_ticket_resolved' : 'shd_ticket_unresolved', |
|
365 |
+ ); |
|
366 |
+ |
|
367 |
+ // This is always going to be a pain. But it should be possible to contextualise it nicely. |
|
368 |
+ // And while this isn't quite as nicely formatted as a single nice array definition, |
|
369 |
+ // imagine trying to debug the display and text options later if it were done with nested ternaries... *shudder* |
|
370 |
+ $assign_nav = array( |
|
371 |
+ 'url' => $scripturl . '?action=helpdesk;sa=assign;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
372 |
+ 'icon' => 'assign', |
|
373 |
+ 'alt' => '*', |
|
374 |
+ 'text' => '', |
|
375 |
+ 'display' => false, |
|
376 |
+ ); |
|
377 |
+ if (shd_allowed_to('shd_assign_ticket_any')) |
|
378 |
+ { |
|
379 |
+ $assign_nav['display'] = true && !$context['ticket']['closed'] && !$context['ticket']['deleted']; |
|
380 |
+ $assign_nav['text'] = empty($context['ticket']['id_member_assigned']) ? 'shd_ticket_assign' : 'shd_ticket_reassign'; |
|
381 |
+ } |
|
382 |
+ elseif (shd_allowed_to('shd_assign_ticket_own')) |
|
383 |
+ { |
|
384 |
+ $assign_nav['display'] = !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (empty($context['ticket']['id_member_assigned']) || $context['ticket']['assigned_self']); // either not assigned or assigned to self |
|
385 |
+ $assign_nav['text'] = $context['ticket']['assigned_self'] ? 'shd_ticket_unassign' : 'shd_ticket_assign_self'; |
|
386 |
+ } |
|
387 |
+ |
|
388 |
+ $context['ticket_navigation'][] = $assign_nav; |
|
389 |
+ |
|
390 |
+ $context['ticket_navigation'][] = array( |
|
391 |
+ 'url' => $scripturl . '?action=helpdesk;sa=deleteticket;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
392 |
+ 'icon' => 'delete', |
|
393 |
+ 'alt' => '*', |
|
394 |
+ 'display' => !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_delete_ticket_any') || (shd_allowed_to('shd_delete_ticket_own') && $context['ticket']['ticket_opener'])), |
|
395 |
+ 'text' => 'shd_ticket_delete', |
|
396 |
+ 'onclick' => 'return confirm(' . JavaScriptEscape($txt['shd_delete_confirm']) . ');', |
|
397 |
+ ); |
|
398 |
+ $context['ticket_navigation'][] = array( |
|
399 |
+ 'url' => $scripturl . '?action=helpdesk;sa=restoreticket;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
400 |
+ 'icon' => 'restore', |
|
401 |
+ 'alt' => '*', |
|
402 |
+ 'display' => $context['ticket']['deleted'] && (shd_allowed_to('shd_restore_ticket_any') || (shd_allowed_to('shd_restore_ticket_own') && $context['ticket']['ticket_opener'])), |
|
403 |
+ 'text' => 'shd_ticket_restore', |
|
404 |
+ ); |
|
405 |
+ $context['ticket_navigation'][] = array( |
|
406 |
+ 'url' => $scripturl . '?action=helpdesk;sa=permadelete;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
407 |
+ 'icon' => 'delete', |
|
408 |
+ 'alt' => '*', |
|
409 |
+ 'display' => $context['ticket']['deleted'] && shd_allowed_to('shd_delete_recycling'), |
|
410 |
+ 'text' => 'shd_delete_permanently', |
|
411 |
+ 'onclick' => 'return confirm(' . JavaScriptEscape($txt['shd_delete_permanently_confirm']) . ');', |
|
412 |
+ ); |
|
413 |
+ |
|
414 |
+ $context['shd_can_move_to_topic'] = shd_allowed_to('shd_ticket_to_topic') && empty($modSettings['shd_helpdesk_only']); |
|
415 |
+ $context['ticket_navigation'][] = array( |
|
416 |
+ 'url' => $scripturl . '?action=helpdesk;sa=tickettotopic;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'], |
|
417 |
+ 'icon' => 'tickettotopic', |
|
418 |
+ 'alt' => '*', |
|
419 |
+ 'display' => $context['shd_can_move_to_topic'] && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && ($context['ticket']['deleted_replies'] == 0 || shd_allowed_to('shd_access_recyclebin')), |
|
420 |
+ 'text' => 'shd_ticket_move_to_topic', |
|
421 |
+ ); |
|
422 |
+ |
|
423 |
+ // If we are going SMF style with the navigation, we need to rework the structure a wee bit. |
|
424 |
+ // No sense making a new array, mind, just fix up the existing one a touch, and don't do this on the master as we don't always need it. |
|
425 |
+ if (empty($modSettings['shd_ticketnav_style']) || !in_array($modSettings['shd_ticketnav_style'], array('sd', 'sdcompact', 'smf'))) |
|
426 |
+ $modSettings['shd_ticketnav_style'] = 'sd'; |
|
427 |
+ |
|
428 |
+ if ($modSettings['shd_ticketnav_style'] == 'smf') |
|
429 |
+ foreach ($context['ticket_navigation'] as $key => $button) |
|
430 |
+ { |
|
431 |
+ $context['can_' . $button['text']] = $button['display']; |
|
432 |
+ $context['ticket_navigation'][$key] += array( |
|
433 |
+ 'lang' => true, |
|
434 |
+ 'test' => 'can_' . $button['text'], |
|
435 |
+ 'image' => 'shd_ticket_' . $button['icon'] . '.png', |
|
436 |
+ ); |
|
437 |
+ } |
|
438 |
+ |
|
439 |
+ if (empty($modSettings['shd_staff_badge'])) |
|
440 |
+ $modSettings['shd_staff_badge'] = 'nobadge'; |
|
441 |
+ |
|
442 |
+ // Quick reply stuffs |
|
443 |
+ require_once($sourcedir . '/SimpleDesk-Post.php'); |
|
444 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
445 |
+ loadTemplate('SimpleDesk-Post'); |
|
446 |
+ |
|
447 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
448 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; |
|
449 |
+ |
|
450 |
+ $context['ticket_form']['ticket'] = $context['ticket_id']; |
|
451 |
+ $context['ticket_form']['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) || $modSettings['shd_attachments_mode'] == 'ticket' ? -1 : $modSettings['attachmentNumPerPostLimit']; |
|
452 |
+ $context['ticket_form']['do_attach'] = shd_allowed_to('shd_post_attachment'); |
|
453 |
+ $context['ticket_form']['num_replies'] = $context['ticket']['num_replies']; |
|
454 |
+ $context['ticket_form']['disable_smileys'] = empty($modSettings['shd_allow_ticket_smileys']); |
|
455 |
+ |
|
456 |
+ // Set up the fancy editor |
|
457 |
+ shd_postbox( |
|
458 |
+ 'shd_message', |
|
459 |
+ '', |
|
460 |
+ array( |
|
461 |
+ 'post_button' => $txt['shd_reply_ticket'], |
|
462 |
+ ) |
|
463 |
+ ); |
|
464 |
+ |
|
465 |
+ // Lastly, our magic AJAX stuff ;D and we know we already made html_headers exist in SimpleDesk.php, score! |
|
466 |
+ $context['html_headers'] .= ' |
|
467 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
468 |
+ var sSessI = "' . $context['session_id'] . '"; |
|
469 |
+ var sSessV = "' . $context['session_var'] . '";'; |
|
470 |
+ |
|
471 |
+ if ($context['ticket']['privacy']['can_change']) |
|
472 |
+ $context['html_headers'] .= ' |
|
473 |
+ var shd_ajax_problem = ' . JavaScriptEscape($txt['shd_ajax_problem']) . '; |
|
474 |
+ var privacyCtl = new shd_privacyControl({ |
|
475 |
+ ticket: ' . $context['ticket_id'] . ', |
|
476 |
+ sUrl: smf_scripturl + "?action=helpdesk;sa=ajax;op=privacy;ticket=' . $context['ticket_id'] . '", |
|
477 |
+ sSession: sSessV + "=" + sSessI, |
|
478 |
+ sSrcA: "privlink", |
|
479 |
+ sDestSpan: "privacy" |
|
480 |
+ });'; |
|
481 |
+ |
|
482 |
+ if ($context['ticket']['urgency']['increase'] || $context['ticket']['urgency']['decrease']) |
|
483 |
+ $context['html_headers'] .= ' |
|
484 |
+ var urgencyCtl = new shd_urgencyControl({ |
|
485 |
+ ticket: ' . $context['ticket_id'] . ', |
|
486 |
+ sUrl: smf_scripturl + "?action=helpdesk;sa=ajax;op=urgency;ticket=' . $context['ticket_id'] . ';change=", |
|
487 |
+ sSession: sSessV + "=" + sSessI, |
|
488 |
+ sDestSpan: "urgency", |
|
489 |
+ aButtons: ["up", "down"], |
|
490 |
+ aButtonOps: { up: "increase", down: "decrease" } |
|
491 |
+ });'; |
|
492 |
+ |
|
493 |
+ if (!empty($options['display_quick_reply'])) |
|
494 |
+ $context['html_headers'] .= ' |
|
495 |
+ var oQuickReply = new QuickReply({ |
|
496 |
+ bDefaultCollapsed: ' . (!empty($options['display_quick_reply']) && $options['display_quick_reply'] == 2 ? 'false' : 'true') . ', |
|
497 |
+ iTicketId: ' . $context['ticket_id'] . ', |
|
498 |
+ iStart: ' . $context['start'] . ', |
|
499 |
+ sScriptUrl: smf_scripturl, |
|
500 |
+ sImagesUrl: "' . $settings['images_url'] . '", |
|
501 |
+ sContainerId: "quickReplyOptions", |
|
502 |
+ sImageId: "quickReplyExpand", |
|
503 |
+ sImageCollapsed: "collapse.gif", |
|
504 |
+ sImageExpanded: "expand.gif", |
|
505 |
+ sJumpAnchor: "quickreply", |
|
506 |
+ sHeaderId: "quickreplyheader", |
|
507 |
+ sFooterId: "quickreplyfooter" |
|
508 |
+ });'; |
|
509 |
+ |
|
510 |
+ if (!empty($options['display_quick_reply']) && $context['can_go_advanced']) |
|
511 |
+ $context['html_headers'] .= ' |
|
512 |
+ function goAdvanced() |
|
513 |
+ { |
|
514 |
+ document.getElementById("shd_bbcbox").style.display = ' . (!empty($modSettings['shd_allow_ticket_bbc']) ? '""' : '"none"') . '; |
|
515 |
+ document.getElementById("shd_smileybox").style.display = ' . (!empty($modSettings['shd_allow_ticket_smileys']) ? '""' : '"none"') . '; |
|
516 |
+ document.getElementById("shd_attach_container").style.display = ' . (!empty($context['ticket_form']['do_attach']) ? '""' : '"none"') . '; |
|
517 |
+ document.getElementById("shd_goadvancedbutton").style.display = "none";' . (!empty($context['controls']['richedit']['shd_message']['rich_active']) ? ' |
|
518 |
+ oEditorHandle_shd_message.toggleView(true);' : '') . ' |
|
519 |
+ } |
|
520 |
+ '; |
|
521 |
+ |
|
522 |
+ $context['html_headers'] .= ' |
|
523 |
+ // ]' . ']></script>'; |
|
524 |
+ |
|
525 |
+ $context['shd_display'] = true; |
|
526 |
+ $context['controls']['richedit']['shd_message']['rich_active'] = 0; // we don't want it by default! |
|
527 |
+ |
|
528 |
+ // Register this form in the session variables. |
|
529 |
+ checkSubmitOnce('register'); |
|
530 |
+} |
|
531 |
+ |
|
532 |
+/** |
|
533 |
+ * Callback function for the template to load messages. |
|
534 |
+ * |
|
535 |
+ * The process set up by shd_view_ticket() and invoked within template_view_replies() is reasonably complex. |
|
536 |
+ * {@link shd_view_ticket()} identifies what messages should be displayed on the current page of the ticket, and performs a query |
|
537 |
+ * to load the ticket data. Instead, however, of retrieving every row directly into memory before passing to the template, |
|
538 |
+ * it passes the query result, and the name of a handler function into $context, so the template can call to get an |
|
539 |
+ * individual row at a time, which saves memory amongst other things. |
|
540 |
+ * |
|
541 |
+ * With respect to {@link shd_view_ticket()}, the relevant items are $reply_request being defined and $context['get_replies'] |
|
542 |
+ * being defined as the name of this function, and in {@link template_view_replies()}, the reference is $reply = $context['get_replies']() |
|
543 |
+ * |
|
544 |
+ * @return mixed The function returns the "next" message reply's details, or simply false if no replies were available, or no further replies are available. Assuming a reply can be returned, it will be a hash array in the following format: |
|
545 |
+ * <ul> |
|
546 |
+ * <li>id: numeric message id</li> |
|
547 |
+ * <li>member: hash array containing details of the poster; normally the return value from SMF's loadMemberContext() function. A minimal set of details is prepared if the poster holds no current SMF account. Common values: |
|
548 |
+ * <ul> |
|
549 |
+ * <li>name: User's name (falls back to the poster name specified in the replies table)</li> |
|
550 |
+ * <li>id: User's id</li> |
|
551 |
+ * <li>group: Name of the assigned group/post count group of the user</li> |
|
552 |
+ * <li>link: HTML for a hyperlink to their profile</li> |
|
553 |
+ * <li>email: Email address of the poster</li> |
|
554 |
+ * <li>ip: IP address of the poster</li> |
|
555 |
+ * </ul> |
|
556 |
+ * </li> |
|
557 |
+ * <li>body: censored, parsed for smileys and bbcode (in {@link shd_format_text()})</li> |
|
558 |
+ * <li>time: string of the time the reply was posted</li> |
|
559 |
+ * <li>timestamp: internal stored timestamp attached to the reply</li> |
|
560 |
+ * <li>is_team: boolean value of whether the posting member is currently helpdesk staff</li> |
|
561 |
+ * <li>can_edit: boolean value reflecting if this reply can be edited</li> |
|
562 |
+ * <li>can_delete: boolean value reflecting if this reply can be deleted</li> |
|
563 |
+ * <li>can_restore: boolean value reflecting if this reply can be restored</li> |
|
564 |
+ * <li>ip_address: IP address used to post the message (not necessarily the user's normal IP address); if the user has moderate_forum_members permission, this returns a link to the track IP area, with the IP address as the link text, alternatively simply the IP address if not (is only displayed to helpdesk staff)</li> |
|
565 |
+ * <li>modified: may not be declared, if it is, the message was modified some time after posting, and the following data items are in the hash array within: |
|
566 |
+ * <ul> |
|
567 |
+ * <li>id: user id who edited the reply (not always available)</li> |
|
568 |
+ * <li>time: formatted string of the time the post was edited</li> |
|
569 |
+ * <li>timestamp: raw timestamp of the time the post was edited</li> |
|
570 |
+ * <li>name: user name of the editing user; if we have a definite user id, this should contain the current name, falling back to the previously stored name</li> |
|
571 |
+ * <li>link: if we have a known, valid user id for the post's editor, this will contain a link to their profile, with the link text using their current display name; alternatively it will contain a regular string which is the username stored with the edit.</li> |
|
572 |
+ * </ul> |
|
573 |
+ * </li> |
|
574 |
+ * </ul> |
|
575 |
+ * |
|
576 |
+ * @see shd_view_ticket() |
|
577 |
+ * @since 1.0 |
|
578 |
+*/ |
|
579 |
+function shd_prepare_ticket_context() |
|
580 |
+{ |
|
581 |
+ global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc; |
|
582 |
+ global $memberContext, $context, $reply_request, $user_profile; |
|
583 |
+ |
|
584 |
+ if (empty($reply_request)) |
|
585 |
+ return false; |
|
586 |
+ |
|
587 |
+ $message = $smcFunc['db_fetch_assoc']($reply_request); |
|
588 |
+ if (!$message) |
|
589 |
+ { |
|
590 |
+ $smcFunc['db_free_result']($reply_request); |
|
591 |
+ return false; |
|
592 |
+ } |
|
593 |
+ |
|
594 |
+ if (!loadMemberContext($message['id_member'], true)) |
|
595 |
+ { |
|
596 |
+ // Notice this information isn't used anywhere else.... |
|
597 |
+ $memberContext[$message['id_member']]['name'] = $message['poster_name']; |
|
598 |
+ $memberContext[$message['id_member']]['id'] = 0; |
|
599 |
+ $memberContext[$message['id_member']]['group'] = $txt['guest_title']; |
|
600 |
+ $memberContext[$message['id_member']]['link'] = $message['poster_name']; |
|
601 |
+ $memberContext[$message['id_member']]['email'] = $message['poster_email']; |
|
602 |
+ $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); |
|
603 |
+ $memberContext[$message['id_member']]['is_guest'] = true; |
|
604 |
+ $memberContext[$message['id_member']]['group_stars'] = ''; |
|
605 |
+ } |
|
606 |
+ $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; |
|
607 |
+ |
|
608 |
+ censorText($message['body']); |
|
609 |
+ $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']); |
|
610 |
+ |
|
611 |
+ $output = array( |
|
612 |
+ 'id' => $message['id_msg'], |
|
613 |
+ 'member' => &$memberContext[$message['id_member']], |
|
614 |
+ 'time' => timeformat($message['poster_time']), |
|
615 |
+ 'timestamp' => forum_time(true, $message['poster_time']), |
|
616 |
+ 'body' => $message['body'], |
|
617 |
+ 'is_team' => !empty($context['is_team'][$message['id_member']]), |
|
618 |
+ 'can_edit' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_edit_reply_any') || ($message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own'))), |
|
619 |
+ 'can_delete' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_delete_reply_any') || ($message['id_member'] == $user_info['id'] && shd_allowed_to('shd_delete_reply_own'))), |
|
620 |
+ 'can_restore' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_restore_reply_any') || ($message['id_member'] == $user_info['id'] && shd_allowed_to('shd_restore_reply_own'))), |
|
621 |
+ 'can_permadelete' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && shd_allowed_to('shd_delete_recycling'), |
|
622 |
+ 'ip_address' => $context['link_ip_address'] ? ('<a href="' . $scripturl . '?action=trackip;searchip=' . $message['poster_ip'] . '">' . $message['poster_ip'] . '</a>') : $message['poster_ip'], |
|
623 |
+ 'message_status' => $message['message_status'], |
|
624 |
+ ); |
|
625 |
+ |
|
626 |
+ if (!empty($message['modified_time'])) |
|
627 |
+ { |
|
628 |
+ $output['modified'] = array( |
|
629 |
+ 'time' => timeformat($message['modified_time']), |
|
630 |
+ 'timestamp' => forum_time(true, $message['modified_time']), |
|
631 |
+ 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, |
|
632 |
+ 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name'], |
|
633 |
+ ); |
|
634 |
+ $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']); |
|
635 |
+ } |
|
636 |
+ |
|
637 |
+ return $output; |
|
638 |
+} |
|
639 |
+ |
|
640 |
+/** |
|
641 |
+ * Loads data on all the attachments that will be displayed in a ticket's view. |
|
642 |
+ * |
|
643 |
+ * Queries the {db_prefix}helpdesk_attachments table for the current ticket, or the messages that will be displayed |
|
644 |
+ * (previously identified by {@link shd_view_ticket()}) and loads the id, name and size of them for display purposes. Differentiation |
|
645 |
+ * between "attach to ticket" and "attach to reply" is made here; the data is loaded differently depending on the context; |
|
646 |
+ * "attach to ticket" is simply loaded into an indexed array stored in $context['ticket_attach']['ticket'], while "attach |
|
647 |
+ * to reply" is loaded into an indexed array subset in $context['ticket_attach']['reply'][msg_id] to retain the association. |
|
648 |
+ * |
|
649 |
+ * @return array Builds an array within $contxt['ticket_attach'], as noted above. The individual data items per attachment are: |
|
650 |
+ * - id: Numeric id for attachment itself |
|
651 |
+ * - name: HTML sanitised name of the attachment's filename |
|
652 |
+ * - size: string listing the size of the attachment, converted to kilobytes and rounded to two decimal places |
|
653 |
+ * - byte_size: integer of raw size of attachment |
|
654 |
+ * - href: the URL that would be used to access the attachment (required $context['ticket_id'] to be available, which it would anyway) |
|
655 |
+ * - link: full HTML "a" element linking to the attachment, using the filename as the link text |
|
656 |
+ * @since 1.0 |
|
657 |
+*/ |
|
658 |
+function shd_display_load_attachments() |
|
659 |
+{ |
|
660 |
+ global $modSettings, $context, $smcFunc, $scripturl, $txt; |
|
661 |
+ |
|
662 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
663 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; // just in case we never actually go to the admin page!! |
|
664 |
+ |
|
665 |
+ $context['ticket_attach'][$modSettings['shd_attachments_mode']] = array(); |
|
666 |
+ |
|
667 |
+ if ($modSettings['shd_attachments_mode'] == 'ticket') |
|
668 |
+ { |
|
669 |
+ $query = shd_db_query('', ' |
|
670 |
+ SELECT hda.id_attach, a.filename, a.size |
|
671 |
+ FROM {db_prefix}helpdesk_attachments AS hda |
|
672 |
+ INNER JOIN {db_prefix}attachments AS a ON (hda.id_attach = a.id_attach) |
|
673 |
+ WHERE hda.id_ticket = {int:ticket} |
|
674 |
+ AND a.attachment_type != {int:thumb} |
|
675 |
+ ORDER BY hda.id_attach', |
|
676 |
+ array( |
|
677 |
+ 'ticket' => $context['ticket_id'], |
|
678 |
+ 'thumb' => 3, |
|
679 |
+ ) |
|
680 |
+ ); |
|
681 |
+ |
|
682 |
+ // Ticket ones can just be added on, they're nice and straightforward |
|
683 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
684 |
+ $context['ticket_attach'][$modSettings['shd_attachments_mode']][] = array( |
|
685 |
+ 'id' => $row['id_attach'], |
|
686 |
+ 'name' => preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'])), |
|
687 |
+ 'size' => round($row['size'] / 1024, 2) . ' ' . $txt['kilobyte'], |
|
688 |
+ 'byte_size' => $row['size'], |
|
689 |
+ 'href' => $scripturl . '?action=dlattach;ticket=' . $context['ticket_id'] . '.0;attach=' . $row['id_attach'], |
|
690 |
+ 'link' => '<a href="' . $scripturl . '?action=dlattach;ticket=' . $context['ticket_id'] . '.0;attach=' . $row['id_attach'] . '">' . htmlspecialchars($row['filename']) . '</a>', |
|
691 |
+ ); |
|
692 |
+ } |
|
693 |
+ else |
|
694 |
+ { |
|
695 |
+ if (empty($context['ticket_messages'])) |
|
696 |
+ return; |
|
697 |
+ |
|
698 |
+ $query = shd_db_query('', ' |
|
699 |
+ SELECT hda.id_attach, hda.id_msg, a.filename, a.size |
|
700 |
+ FROM {db_prefix}helpdesk_attachments AS hda |
|
701 |
+ INNER JOIN {db_prefix}attachments AS a ON (hda.id_attach = a.id_attach) |
|
702 |
+ WHERE hda.id_msg IN ({array_int:msg}) |
|
703 |
+ AND a.attachment_type != {int:thumb} |
|
704 |
+ ORDER BY hda.id_attach', |
|
705 |
+ array( |
|
706 |
+ 'msg' => $context['ticket_messages'], |
|
707 |
+ 'thumb' => 3, |
|
708 |
+ ) |
|
709 |
+ ); |
|
710 |
+ |
|
711 |
+ // Message ones are a little trickier since we actually need to tie them to msg ids |
|
712 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
713 |
+ $context['ticket_attach'][$modSettings['shd_attachments_mode']][$row['id_msg']][] = array( |
|
714 |
+ 'id' => $row['id_attach'], |
|
715 |
+ 'name' => preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'])), |
|
716 |
+ 'size' => round($row['size'] / 1024, 2) . ' ' . $txt['kilobyte'], |
|
717 |
+ 'byte_size' => $row['size'], |
|
718 |
+ 'href' => $scripturl . '?action=dlattach;ticket=' . $context['ticket_id'] . '.0;attach=' . $row['id_attach'], |
|
719 |
+ 'link' => '<a href="' . $scripturl . '?action=dlattach;ticket=' . $context['ticket_id'] . '.0;attach=' . $row['id_attach'] . '">' . htmlspecialchars($row['filename']) . '</a>', |
|
720 |
+ ); |
|
721 |
+ } |
|
722 |
+ |
|
723 |
+ $smcFunc['db_free_result']($query); |
|
724 |
+} |
|
725 |
+?> |
|
0 | 726 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,270 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-MiscActions.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles miscellaneous actions that aren't really tied to anything, that are mostly |
|
22 |
+ * self-contained and aren't big enough to warrant their own file. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @since 1.0 |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Marks a ticket unread. |
|
33 |
+ * |
|
34 |
+ * There are no permission checks made; other than that the user is who they claim to be. If a ticket is marked unread |
|
35 |
+ * but they can't see it anyway, the consequence is that the database gets lighter. |
|
36 |
+ * |
|
37 |
+ * Invoked through ?action=helpdesk;sa=unreadticket;ticket=x;sessvar=sessid before redirecting back to the main helpdesk page. |
|
38 |
+ * |
|
39 |
+ * @since 1.0 |
|
40 |
+*/ |
|
41 |
+function shd_ticket_unread() |
|
42 |
+{ |
|
43 |
+ global $smcFunc, $user_info, $context; |
|
44 |
+ |
|
45 |
+ is_not_guest(); |
|
46 |
+ checkSession('get'); |
|
47 |
+ |
|
48 |
+ if (!empty($context['ticket_id'])) |
|
49 |
+ $result = shd_db_query('', ' |
|
50 |
+ DELETE FROM {db_prefix}helpdesk_log_read |
|
51 |
+ WHERE id_ticket = {int:current_ticket} |
|
52 |
+ AND id_member = {int:user}', |
|
53 |
+ array( |
|
54 |
+ 'current_ticket' => $context['ticket_id'], |
|
55 |
+ 'user' => $user_info['id'], |
|
56 |
+ ) |
|
57 |
+ ); |
|
58 |
+ |
|
59 |
+ redirectexit('action=helpdesk;sa=main'); |
|
60 |
+} |
|
61 |
+ |
|
62 |
+/** |
|
63 |
+ * Marks a ticket resolved or unresolved. |
|
64 |
+ * |
|
65 |
+ * This function identifies whether a given ticket is resolved or not, if not resolved, mark it resolved. If it was resolved |
|
66 |
+ * reopen the ticket back to an appropriate status based on last respondent. In both cases, the action is logged in the action log. |
|
67 |
+ * It is also unassigned from having a user on either closure or reopen. |
|
68 |
+ * |
|
69 |
+ * Accessed through ?action=helpdesk;sa=resolve;ticket=x;sessvar=sessid before redirecting back to the ticket, or add ;home to the |
|
70 |
+ * URL to have it redirect back to the home page. |
|
71 |
+ * |
|
72 |
+ * @since 1.0 |
|
73 |
+*/ |
|
74 |
+function shd_ticket_resolve() |
|
75 |
+{ |
|
76 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
77 |
+ |
|
78 |
+ checkSession('get'); |
|
79 |
+ |
|
80 |
+ // First, figure out the state of the ticket - is it resolved or not? Can we even see it? |
|
81 |
+ if (empty($context['ticket_id'])) |
|
82 |
+ fatal_lang_error('shd_no_ticket', false); |
|
83 |
+ |
|
84 |
+ $context['shd_return_to'] = isset($_REQUEST['home']) ? 'home' : 'ticket'; |
|
85 |
+ |
|
86 |
+ $query = shd_db_query('', ' |
|
87 |
+ SELECT id_member_started, id_member_updated, status, num_replies, subject |
|
88 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
89 |
+ WHERE {query_see_ticket} |
|
90 |
+ AND id_ticket = {int:current_ticket}', |
|
91 |
+ array( |
|
92 |
+ 'current_ticket' => $context['ticket_id'], |
|
93 |
+ ) |
|
94 |
+ ); |
|
95 |
+ |
|
96 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
97 |
+ { |
|
98 |
+ $smcFunc['db_free_result']($query); |
|
99 |
+ |
|
100 |
+ if (!shd_allowed_to('shd_resolve_ticket_any') && (!shd_allowed_to('shd_resolve_ticket_own') || $row['id_member_started'] != $user_info['id'])) |
|
101 |
+ fatal_lang_error('shd_cannot_resolve', false); |
|
102 |
+ |
|
103 |
+ $action = ($row['status'] != TICKET_STATUS_CLOSED) ? 'resolve' : 'unresolve'; |
|
104 |
+ $new = shd_determine_status($action, $row['id_member_started'], $row['id_member_updated'], $row['num_replies']); |
|
105 |
+ |
|
106 |
+ shd_db_query('', ' |
|
107 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
108 |
+ SET status = {int:status}, |
|
109 |
+ id_member_assigned = {int:unassigned} |
|
110 |
+ WHERE id_ticket = {int:ticket}', |
|
111 |
+ array( |
|
112 |
+ 'status' => $new, |
|
113 |
+ 'unassigned' => 0, |
|
114 |
+ 'ticket' => $context['ticket_id'], |
|
115 |
+ ) |
|
116 |
+ ); |
|
117 |
+ |
|
118 |
+ shd_log_action($action, |
|
119 |
+ array( |
|
120 |
+ 'ticket' => $context['ticket_id'], |
|
121 |
+ 'subject' => $row['subject'], |
|
122 |
+ ) |
|
123 |
+ ); |
|
124 |
+ |
|
125 |
+ // Make sure we recalculate the number of tickets on next page load (here it will affect visibility) |
|
126 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
127 |
+ |
|
128 |
+ if ($context['shd_return_to'] == 'home') |
|
129 |
+ redirectexit('action=helpdesk;sa=main'); |
|
130 |
+ else |
|
131 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
132 |
+ } |
|
133 |
+ else |
|
134 |
+ fatal_lang_error('shd_no_ticket', false); |
|
135 |
+} |
|
136 |
+ |
|
137 |
+/** |
|
138 |
+ * Marks a ticket private/not private if the user isn't using Javascript. |
|
139 |
+ * |
|
140 |
+ * Assuming the user can see the ticket and has suitable permissions, the privacy flag will be inverted for the ticket and |
|
141 |
+ * updated, as well as updating the action log. If they cannot see the ticket, or do not have privacy-change permission, a fatal |
|
142 |
+ * error will be generated. |
|
143 |
+ * |
|
144 |
+ * Accessed through ?action=helpdesk;sa=privacychange;ticket=x;sessvar=sessid before directing back to the main helpdesk page. |
|
145 |
+ * |
|
146 |
+ * @since 1.0 |
|
147 |
+*/ |
|
148 |
+function shd_privacy_change_noajax() |
|
149 |
+{ |
|
150 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
151 |
+ |
|
152 |
+ checkSession('get'); |
|
153 |
+ |
|
154 |
+ // First, figure out the state of the ticket - is it private or not? Can we even see it? |
|
155 |
+ if (empty($context['ticket_id'])) |
|
156 |
+ fatal_lang_error('shd_no_ticket', false); |
|
157 |
+ |
|
158 |
+ $query = shd_db_query('', ' |
|
159 |
+ SELECT id_member_started, subject, private, status |
|
160 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
161 |
+ WHERE {query_see_ticket} |
|
162 |
+ AND id_ticket = {int:current_ticket}', |
|
163 |
+ array( |
|
164 |
+ 'current_ticket' => $context['ticket_id'], |
|
165 |
+ ) |
|
166 |
+ ); |
|
167 |
+ |
|
168 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
169 |
+ { |
|
170 |
+ if (in_array($row['status'], array(TICKET_STATUS_CLOSED, TICKET_STATUS_DELETED)) || !shd_allowed_to('shd_alter_privacy_any') && (!shd_allowed_to('shd_alter_privacy_own') || $row['id_member_started'] != $user_info['id'])) |
|
171 |
+ fatal_lang_error('shd_cannot_change_privacy', false); |
|
172 |
+ |
|
173 |
+ $smcFunc['db_free_result']($query); |
|
174 |
+ |
|
175 |
+ $new = empty($row['private']) ? 1 : 0; |
|
176 |
+ $action = empty($row['private']) ? 'markprivate' : 'marknotprivate'; |
|
177 |
+ |
|
178 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
179 |
+ $msgOptions = array(); |
|
180 |
+ $posterOptions = array(); |
|
181 |
+ $ticketOptions = array( |
|
182 |
+ 'id' => $context['ticket_id'], |
|
183 |
+ 'private' => empty($row['private']), |
|
184 |
+ ); |
|
185 |
+ |
|
186 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
187 |
+ |
|
188 |
+ shd_log_action($action, |
|
189 |
+ array( |
|
190 |
+ 'ticket' => $context['ticket_id'], |
|
191 |
+ 'subject' => $row['subject'], |
|
192 |
+ ) |
|
193 |
+ ); |
|
194 |
+ |
|
195 |
+ // Make sure we recalculate the number of tickets on next page load (here it may affect ticket visibility so we do it) |
|
196 |
+ shd_clear_active_tickets($row['id_member_started']); |
|
197 |
+ |
|
198 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
199 |
+ } |
|
200 |
+ else |
|
201 |
+ fatal_lang_error('shd_no_ticket', false); |
|
202 |
+} |
|
203 |
+ |
|
204 |
+/** |
|
205 |
+ * Updates a ticket's urgency up or down one level, if the user isn't using Javascript |
|
206 |
+ * |
|
207 |
+ * Assuming the user can see the ticket and has suitable permissions, the urgency of the ticket will be updated and an |
|
208 |
+ * action log entry added. If they cannot see the ticket, or do not have urgency-change permission (including higher |
|
209 |
+ * urgency permission if necessary), a fatal error will be generated. |
|
210 |
+ * |
|
211 |
+ * Accessed through ?action=helpdesk;sa=urgencychange;ticket=x;change=(increase|decrease);sessvar=sessid before directing back to the main helpdesk page. |
|
212 |
+ * |
|
213 |
+ * @see shd_can_alter_urgency() |
|
214 |
+ * |
|
215 |
+ * @since 1.0 |
|
216 |
+*/ |
|
217 |
+function shd_urgency_change_noajax() |
|
218 |
+{ |
|
219 |
+ global $smcFunc, $user_info, $context, $sourcedir; |
|
220 |
+ |
|
221 |
+ checkSession('get'); |
|
222 |
+ |
|
223 |
+ // First, figure out the state of the ticket - is it private or not? Can we even see it? Current urgency? |
|
224 |
+ if (empty($context['ticket_id'])) |
|
225 |
+ fatal_lang_error('shd_no_ticket', false); |
|
226 |
+ |
|
227 |
+ $query = shd_db_query('', ' |
|
228 |
+ SELECT id_member_started, subject, urgency, status |
|
229 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
230 |
+ WHERE {query_see_ticket} |
|
231 |
+ AND id_ticket = {int:current_ticket}', |
|
232 |
+ array( |
|
233 |
+ 'current_ticket' => $context['ticket_id'], |
|
234 |
+ ) |
|
235 |
+ ); |
|
236 |
+ |
|
237 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
238 |
+ { |
|
239 |
+ $can_urgency = shd_can_alter_urgency($row['urgency'], $row['id_member_started'], ($row['status'] == TICKET_STATUS_CLOSED), ($row['status'] == TICKET_STATUS_DELETED)); |
|
240 |
+ |
|
241 |
+ if (empty($_GET['change']) || empty($can_urgency[$_GET['change']])) |
|
242 |
+ fatal_lang_error('shd_cannot_change_urgency'); |
|
243 |
+ |
|
244 |
+ $new_urgency = $row['urgency'] + ($_GET['change'] == 'increase' ? 1 : -1); |
|
245 |
+ $action = 'urgency_' . $_GET['change']; |
|
246 |
+ |
|
247 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
248 |
+ $msgOptions = array(); |
|
249 |
+ $posterOptions = array(); |
|
250 |
+ $ticketOptions = array( |
|
251 |
+ 'id' => $context['ticket_id'], |
|
252 |
+ 'private' => empty($row['private']), |
|
253 |
+ ); |
|
254 |
+ |
|
255 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
256 |
+ |
|
257 |
+ shd_log_action($action, |
|
258 |
+ array( |
|
259 |
+ 'ticket' => $context['ticket_id'], |
|
260 |
+ 'subject' => $row['subject'], |
|
261 |
+ 'urgency' => $new_urgency, |
|
262 |
+ ) |
|
263 |
+ ); |
|
264 |
+ |
|
265 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
266 |
+ } |
|
267 |
+ else |
|
268 |
+ fatal_lang_error('shd_no_ticket', false); |
|
269 |
+} |
|
270 |
+?> |
|
0 | 271 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,1668 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-Post.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file is one of the cornerstones of SimpleDesk; it handles displaying the post form to users, both for tickets and replies, |
|
22 |
+ * handles editing of tickets/replies, attachments to tickets/replies and actually saving all that into the database. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @todo Finish documenting this file. |
|
26 |
+ * @since 1.0 |
|
27 |
+*/ |
|
28 |
+ |
|
29 |
+if (!defined('SMF')) |
|
30 |
+ die('Hacking attempt...'); |
|
31 |
+ |
|
32 |
+/** |
|
33 |
+ * Create a new ticket |
|
34 |
+*/ |
|
35 |
+function shd_post_ticket() |
|
36 |
+{ |
|
37 |
+ global $context, $user_info, $sourcedir, $txt, $scripturl, $reply_request, $smcFunc, $options, $memberContext; |
|
38 |
+ $context['tabindex'] = 1; |
|
39 |
+ |
|
40 |
+ $new_ticket = $_REQUEST['sa'] == 'newticket'; |
|
41 |
+ |
|
42 |
+ if ($new_ticket) |
|
43 |
+ shd_is_allowed_to('shd_new_ticket'); |
|
44 |
+ else |
|
45 |
+ { |
|
46 |
+ checkSession('get'); |
|
47 |
+ $ticketinfo = shd_load_ticket(); |
|
48 |
+ if (!shd_allowed_to('shd_edit_ticket_any') && (!shd_allowed_to('shd_edit_ticket_own') || !$ticketinfo['is_own'])) |
|
49 |
+ fatal_lang_error('cannot_shd_edit_ticket'); |
|
50 |
+ } |
|
51 |
+ |
|
52 |
+ // Things we need |
|
53 |
+ loadTemplate('SimpleDesk-Post'); |
|
54 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
55 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
56 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
57 |
+ |
|
58 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
59 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; |
|
60 |
+ |
|
61 |
+ $context['ticket_form'] = array( // yes, everything goes in here. |
|
62 |
+ 'form_title' => $new_ticket ? $txt['shd_create_ticket'] : $txt['shd_edit_ticket'], |
|
63 |
+ 'form_action' => $scripturl . '?action=helpdesk;sa=saveticket', |
|
64 |
+ 'first_msg' => $new_ticket ? 0 : $ticketinfo['id_first_msg'], |
|
65 |
+ 'message' => $new_ticket ? '' : $ticketinfo['body'], |
|
66 |
+ 'subject' => $new_ticket ? '' : $ticketinfo['subject'], |
|
67 |
+ 'ticket' => $new_ticket ? 0 : $context['ticket_id'], |
|
68 |
+ 'link' => $new_ticket ? '' : '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '">' . $ticketinfo['subject'] . '</a>', |
|
69 |
+ 'msg' => $new_ticket ? 0 : $ticketinfo['id_first_msg'], |
|
70 |
+ 'display_id' => $new_ticket ? '' : str_pad($context['ticket_id'], 5, '0', STR_PAD_LEFT), |
|
71 |
+ 'status' => $new_ticket ? TICKET_STATUS_NEW : $ticketinfo['status'], |
|
72 |
+ 'urgency' => array( |
|
73 |
+ 'setting' => $new_ticket ? TICKET_URGENCY_LOW : $ticketinfo['urgency'], |
|
74 |
+ ), |
|
75 |
+ 'private' => array( |
|
76 |
+ 'setting' => $new_ticket ? false : ($ticketinfo['private'] == 1), |
|
77 |
+ 'can_change' => shd_allowed_to('shd_alter_privacy_any') || (shd_allowed_to('shd_alter_privacy_own') && ($new_ticket || !empty($ticketinfo['is_own']))), |
|
78 |
+ 'options' => array( |
|
79 |
+ 0 => 'shd_ticket_notprivate', |
|
80 |
+ 1 => 'shd_ticket_private', |
|
81 |
+ ), |
|
82 |
+ ), |
|
83 |
+ 'errors' => array(), |
|
84 |
+ 'num_replies' => $new_ticket ? 0 : $ticketinfo['num_replies'], |
|
85 |
+ 'do_attach' => shd_allowed_to('shd_post_attachment'), |
|
86 |
+ 'num_allowed_attachments' => empty($modSettings['attachmentNumPerPostLimit']) || $modSettings['shd_attachments_mode'] == 'ticket' ? -1 : $modSettings['attachmentNumPerPostLimit'], |
|
87 |
+ 'return_to_ticket' => isset($_REQUEST['goback']), |
|
88 |
+ 'disable_smileys' => $new_ticket ? !empty($_REQUEST['no_smileys']) : ($ticketinfo['smileys_enabled'] == 0), |
|
89 |
+ ); |
|
90 |
+ |
|
91 |
+ // A few basic checks |
|
92 |
+ if ($context['ticket_form']['status'] == TICKET_STATUS_CLOSED) |
|
93 |
+ fatal_lang_error('shd_cannot_edit_closed', false); |
|
94 |
+ elseif ($context['ticket_form']['status'] == TICKET_STATUS_DELETED) |
|
95 |
+ fatal_lang_error('shd_cannon_edit_deleted', false); |
|
96 |
+ |
|
97 |
+ // Ticket privacy |
|
98 |
+ if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') |
|
99 |
+ $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any') || shd_allowed_to('shd_alter_privacy_own') || shd_allowed_to('shd_alter_privacy_any') || $context['ticket_form']['private']['setting']; |
|
100 |
+ else |
|
101 |
+ $context['display_private'] = true; |
|
102 |
+ |
|
103 |
+ if ($new_ticket) |
|
104 |
+ { |
|
105 |
+ $context['ticket_form'] += array( |
|
106 |
+ 'member' => array( |
|
107 |
+ 'name' => $context['user']['name'], |
|
108 |
+ 'id' => $context['user']['id'], |
|
109 |
+ 'link' => shd_profile_link($context['user']['name'], $context['user']['id']), |
|
110 |
+ ), |
|
111 |
+ 'assigned' => array( |
|
112 |
+ 'id' => 0, |
|
113 |
+ 'name' => $txt['shd_unassigned'], |
|
114 |
+ 'link' => '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
115 |
+ ), |
|
116 |
+ ); |
|
117 |
+ } |
|
118 |
+ else |
|
119 |
+ { |
|
120 |
+ $context['ticket_form'] += array( |
|
121 |
+ 'member' => array( |
|
122 |
+ 'name' => $ticketinfo['starter_name'], |
|
123 |
+ 'id' => $ticketinfo['starter_id'], |
|
124 |
+ 'link' => shd_profile_link($ticketinfo['starter_name'], $ticketinfo['starter_id']), |
|
125 |
+ ), |
|
126 |
+ 'assigned' => array( |
|
127 |
+ 'id' => $ticketinfo['assigned_id'], |
|
128 |
+ 'name' => !empty($ticketinfo['assigned_id']) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], |
|
129 |
+ 'link' => !empty($ticketinfo['assigned_id']) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
130 |
+ ), |
|
131 |
+ ); |
|
132 |
+ |
|
133 |
+ loadMemberData($ticketinfo['starter_id']); |
|
134 |
+ if (loadMemberContext($ticketinfo['starter_id'])) |
|
135 |
+ $context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar']; |
|
136 |
+ |
|
137 |
+ if (!$new_ticket && !empty($ticketinfo['modified_time'])) |
|
138 |
+ { |
|
139 |
+ $context['ticket_form'] += array( |
|
140 |
+ 'modified' => array( |
|
141 |
+ 'name' => $ticketinfo['modified_name'], |
|
142 |
+ 'id' => $ticketinfo['modified_id'], |
|
143 |
+ 'time' => timeformat($ticketinfo['modified_time']), |
|
144 |
+ 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id']), |
|
145 |
+ ), |
|
146 |
+ ); |
|
147 |
+ } |
|
148 |
+ |
|
149 |
+ // Some other setup stuff |
|
150 |
+ shd_load_attachments(); |
|
151 |
+ |
|
152 |
+ $context['ticket_form']['message'] = un_preparsecode($context['ticket_form']['message']); |
|
153 |
+ censorText($context['ticket_form']['subject']); |
|
154 |
+ censorText($context['ticket_form']['message']); |
|
155 |
+ } |
|
156 |
+ |
|
157 |
+ shd_get_urgency_options($new_ticket || $ticketinfo['is_own']); |
|
158 |
+ |
|
159 |
+ if ($context['ticket_form']['num_replies']) |
|
160 |
+ shd_setup_replies($ticketinfo['id_first_msg']); |
|
161 |
+ |
|
162 |
+ shd_check_attachments(); |
|
163 |
+ |
|
164 |
+ // Set up the fancy editor |
|
165 |
+ shd_postbox( |
|
166 |
+ 'shd_message', |
|
167 |
+ $context['ticket_form']['message'], |
|
168 |
+ array( |
|
169 |
+ 'post_button' => $context['ticket_form']['form_title'], |
|
170 |
+ ) |
|
171 |
+ ); |
|
172 |
+ |
|
173 |
+ // Build the link tree and navigation |
|
174 |
+ $context['linktree'][] = array( |
|
175 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
176 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
177 |
+ ); |
|
178 |
+ $context['linktree'][] = array( |
|
179 |
+ 'name' => $new_ticket ? $txt['shd_create_ticket'] : sprintf($txt['shd_edit_ticket_linktree'], $context['ticket_form']['link']), |
|
180 |
+ ); |
|
181 |
+ |
|
182 |
+ $context['page_title'] = $txt['shd_helpdesk']; |
|
183 |
+ $context['sub_template'] = 'ticket_post'; |
|
184 |
+ |
|
185 |
+ // Register this form in the session variables. |
|
186 |
+ checkSubmitOnce('register'); |
|
187 |
+} |
|
188 |
+ |
|
189 |
+// All the magically common posting stuff goes in here |
|
190 |
+function shd_save_post() |
|
191 |
+{ |
|
192 |
+ global $txt, $modSettings, $sourcedir, $context, $scripturl; |
|
193 |
+ global $user_info, $options, $smcFunc; |
|
194 |
+ |
|
195 |
+ // Oh no, robots! |
|
196 |
+ $context['robot_no_index'] = true; |
|
197 |
+ |
|
198 |
+ $context['shd_errors'] = array(); |
|
199 |
+ |
|
200 |
+ // We'll probably be needing these. |
|
201 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
202 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
203 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
204 |
+ loadTemplate('SimpleDesk-Post'); |
|
205 |
+ loadLanguage('Errors'); // for some of the errors we already have |
|
206 |
+ loadLanguage('Post'); // for some of the common post errors |
|
207 |
+ |
|
208 |
+ if (!empty($_REQUEST['shd_message_mode']) && isset($_REQUEST['shd_message'])) |
|
209 |
+ { |
|
210 |
+ // If we came from WYSIWYG, we need to convert from HTML to bbc, then unhtml it; then push to $_POST for everything else |
|
211 |
+ $_REQUEST['shd_message'] = un_htmlspecialchars(html_to_bbc($_REQUEST['shd_message'])); |
|
212 |
+ $_POST['shd_message'] = $_REQUEST['shd_message']; |
|
213 |
+ } |
|
214 |
+ |
|
215 |
+ // Check session and double-posting |
|
216 |
+ checkSubmitOnce('check'); |
|
217 |
+ if (checkSession('post', '', false) != '') |
|
218 |
+ $context['shd_errors'][] = 'session_timeout'; |
|
219 |
+ |
|
220 |
+ // Clean up the details |
|
221 |
+ if (!isset($_POST['shd_message']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['shd_message']), ENT_QUOTES) === '') |
|
222 |
+ { |
|
223 |
+ $context['shd_errors'][] = 'no_message'; |
|
224 |
+ $_POST['shd_message'] = ''; |
|
225 |
+ } |
|
226 |
+ else |
|
227 |
+ { |
|
228 |
+ // Pfft. |
|
229 |
+ if (isset($_POST['shd_message']) && strtolower($_POST['shd_message']) == 'this is simpledesk!') |
|
230 |
+ fatal_error('You are not King Leonidas...', false); |
|
231 |
+ $_POST['shd_message'] = $smcFunc['htmlspecialchars']($_POST['shd_message'], ENT_QUOTES); |
|
232 |
+ preparsecode($_POST['shd_message']); |
|
233 |
+ |
|
234 |
+ // Make sure there's something underneath all the tags |
|
235 |
+ if ($smcFunc['htmltrim'](strip_tags(shd_format_text($_POST['shd_message'], false), '<img>')) === '' && (!shd_allowed_to('admin_forum') || strpos($_POST['shd_message'], '[html]') === false)) |
|
236 |
+ $context['shd_errors'][] = 'no_message'; |
|
237 |
+ elseif (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_POST['shd_message']) > $modSettings['max_messageLength']) |
|
238 |
+ { |
|
239 |
+ $context['shd_errors'][] = 'long_message'; |
|
240 |
+ $txt['error_long_message'] = sprintf($txt['error_long_message'], $modSettings['max_messageLength']); |
|
241 |
+ } |
|
242 |
+ } |
|
243 |
+ |
|
244 |
+ // Now send them off to the specific areas, whether that's saving a ticket or a reply |
|
245 |
+ |
|
246 |
+ $actions = array( |
|
247 |
+ 'saveticket' => 'shd_save_ticket', |
|
248 |
+ 'savereply' => 'shd_save_reply', |
|
249 |
+ ); |
|
250 |
+ |
|
251 |
+ if (isset($actions[$_REQUEST['sa']])) |
|
252 |
+ $actions[$_REQUEST['sa']](); |
|
253 |
+} |
|
254 |
+ |
|
255 |
+function shd_save_ticket() |
|
256 |
+{ |
|
257 |
+ global $txt, $modSettings, $sourcedir, $context, $scripturl; |
|
258 |
+ global $user_info, $options, $smcFunc, $memberContext; |
|
259 |
+ |
|
260 |
+ // Ticket's gotta have a subject |
|
261 |
+ if (!isset($_POST['subject']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['subject'])) === '') |
|
262 |
+ { |
|
263 |
+ $context['shd_errors'][] = 'no_subject'; |
|
264 |
+ $_POST['subject'] = ''; |
|
265 |
+ } |
|
266 |
+ else |
|
267 |
+ $_POST['subject'] = strtr($smcFunc['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => '')); |
|
268 |
+ |
|
269 |
+ if (empty($context['ticket_id'])) |
|
270 |
+ { |
|
271 |
+ shd_is_allowed_to('shd_new_ticket'); |
|
272 |
+ |
|
273 |
+ // some healthy defaults |
|
274 |
+ $context['ticket_id'] = 0; |
|
275 |
+ $new_ticket = true; |
|
276 |
+ $msg = 0; |
|
277 |
+ $is_own = true; |
|
278 |
+ $new_status = TICKET_STATUS_NEW; |
|
279 |
+ $private = false; |
|
280 |
+ $urgency = TICKET_URGENCY_LOW; |
|
281 |
+ $assigned = array( |
|
282 |
+ 'id' => 0, |
|
283 |
+ 'name' => $txt['shd_unassigned'], |
|
284 |
+ 'link' => '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
285 |
+ ); |
|
286 |
+ $num_replies = 0; |
|
287 |
+ } |
|
288 |
+ else |
|
289 |
+ { |
|
290 |
+ // hmm, we're saving an update, let's get the existing ticket details and we can check permissions and stuff |
|
291 |
+ $new_ticket = false; |
|
292 |
+ |
|
293 |
+ $ticketinfo = shd_load_ticket(); |
|
294 |
+ |
|
295 |
+ // S'pose we'd better check the permissions here |
|
296 |
+ if (!shd_allowed_to('shd_edit_ticket_any') && (!shd_allowed_to('shd_edit_ticket_own') || !$ticketinfo['is_own'])) |
|
297 |
+ fatal_lang_error('cannot_shd_edit_ticket', false); |
|
298 |
+ |
|
299 |
+ $msg = $ticketinfo['id_first_msg']; |
|
300 |
+ $is_own = $ticketinfo['is_own']; |
|
301 |
+ $private = $ticketinfo['private']; |
|
302 |
+ $urgency = $ticketinfo['urgency']; |
|
303 |
+ $new_status = $ticketinfo['status']; |
|
304 |
+ $assigned = array( |
|
305 |
+ 'id' => $ticketinfo['assigned_id'], |
|
306 |
+ 'name' => !empty($ticketinfo['assigned_id']) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], |
|
307 |
+ 'link' => !empty($ticketinfo['assigned_id']) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
308 |
+ ); |
|
309 |
+ $num_replies = $ticketinfo['num_replies']; |
|
310 |
+ } |
|
311 |
+ |
|
312 |
+ $context['ticket_form'] = array( |
|
313 |
+ 'form_title' => $new_ticket ? $txt['shd_create_ticket'] : $txt['shd_edit_ticket'], |
|
314 |
+ 'form_action' => $scripturl . '?action=helpdesk;sa=saveticket', |
|
315 |
+ 'first_msg' => $new_ticket ? 0 : $ticketinfo['id_first_msg'], |
|
316 |
+ 'message' => $_POST['shd_message'], |
|
317 |
+ 'subject' => $_POST['subject'], |
|
318 |
+ 'ticket' => $context['ticket_id'], |
|
319 |
+ 'link' => $new_ticket ? '' : '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '">' . $ticketinfo['subject'] . '</a>', |
|
320 |
+ 'msg' => $msg, |
|
321 |
+ 'display_id' => empty($context['ticket_id']) ? '' : str_pad($context['ticket_id'], 5, '0', STR_PAD_LEFT), |
|
322 |
+ 'status' => $new_status, |
|
323 |
+ 'private' => array( |
|
324 |
+ 'setting' => $private, |
|
325 |
+ 'can_change' => (shd_allowed_to('shd_alter_privacy_any') || ($is_own && shd_allowed_to('shd_alter_privacy_own'))), |
|
326 |
+ 'options' => array( |
|
327 |
+ 0 => 'shd_ticket_notprivate', |
|
328 |
+ 1 => 'shd_ticket_private', |
|
329 |
+ ), |
|
330 |
+ ), |
|
331 |
+ 'assigned' => $assigned, |
|
332 |
+ 'num_replies' => $num_replies, |
|
333 |
+ 'do_attach' => shd_allowed_to('shd_post_attachment'), |
|
334 |
+ 'return_to_ticket' => isset($_REQUEST['goback']), |
|
335 |
+ 'disable_smileys' => !empty($_REQUEST['no_smileys']), |
|
336 |
+ ); |
|
337 |
+ |
|
338 |
+ // Ticket privacy |
|
339 |
+ if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') |
|
340 |
+ $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any') || shd_allowed_to('shd_alter_privacy_own') || shd_allowed_to('shd_alter_privacy_any') || $context['ticket_form']['private']['setting']; |
|
341 |
+ else |
|
342 |
+ $context['display_private'] = true; |
|
343 |
+ |
|
344 |
+ // Preview? |
|
345 |
+ if (isset($_REQUEST['preview'])) |
|
346 |
+ { |
|
347 |
+ $context['ticket_form']['preview'] = array( |
|
348 |
+ 'title' => $txt['shd_previewing_ticket'] . ': ' . (empty($_POST['subject']) ? '<em>' . $txt['no_subject'] . '</em>' : $_POST['subject']), |
|
349 |
+ 'body' => shd_format_text($_POST['shd_message']), |
|
350 |
+ ); |
|
351 |
+ } |
|
352 |
+ |
|
353 |
+ if (!$new_ticket && !empty($ticketinfo['modified_time'])) |
|
354 |
+ { |
|
355 |
+ $context['ticket_form'] += array( |
|
356 |
+ 'modified' => array( |
|
357 |
+ 'name' => $ticketinfo['modified_name'], |
|
358 |
+ 'id' => $ticketinfo['modified_id'], |
|
359 |
+ 'time' => timeformat($ticketinfo['modified_time']), |
|
360 |
+ 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id']), |
|
361 |
+ ), |
|
362 |
+ ); |
|
363 |
+ } |
|
364 |
+ |
|
365 |
+ if (!$new_ticket) |
|
366 |
+ { |
|
367 |
+ loadMemberData($ticketinfo['starter_id']); |
|
368 |
+ if (loadMemberContext($ticketinfo['starter_id'])) |
|
369 |
+ $context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar']; |
|
370 |
+ } |
|
371 |
+ |
|
372 |
+ shd_load_attachments(); |
|
373 |
+ |
|
374 |
+ // Ticket privacy, let's see if we can override our healthy default with the post value |
|
375 |
+ if ($context['ticket_form']['private']['can_change']) |
|
376 |
+ { |
|
377 |
+ $new_private = isset($_POST['shd_private']) ? (int) $_POST['shd_private'] : $private; |
|
378 |
+ $context['ticket_form']['private']['setting'] = isset($context['ticket_form']['private']['options'][$new_private]) ? (bool) $new_private : $private; |
|
379 |
+ } |
|
380 |
+ |
|
381 |
+ // Ticket urgency |
|
382 |
+ shd_get_urgency_options($is_own); |
|
383 |
+ if ($context['ticket_form']['urgency']['can_change']) |
|
384 |
+ { |
|
385 |
+ $new_urgency = isset($_POST['shd_urgency']) ? (int) $_POST['shd_urgency'] : $urgency; |
|
386 |
+ $context['ticket_form']['urgency']['setting'] = isset($context['ticket_form']['urgency']['options'][$new_urgency]) ? $new_urgency : $urgency; |
|
387 |
+ } |
|
388 |
+ else |
|
389 |
+ $context['ticket_form']['urgency']['setting'] = $urgency; |
|
390 |
+ |
|
391 |
+ // A few basic checks |
|
392 |
+ if ($context['ticket_form']['status'] == TICKET_STATUS_CLOSED) |
|
393 |
+ fatal_lang_error('shd_cannot_edit_closed', false); |
|
394 |
+ elseif ($context['ticket_form']['status'] == TICKET_STATUS_DELETED) |
|
395 |
+ fatal_lang_error('shd_cannon_edit_deleted', false); |
|
396 |
+ |
|
397 |
+ if (!empty($context['shd_errors']) || !empty($context['ticket_form']['preview'])) // Uh oh, something went wrong, or we're previewing |
|
398 |
+ { |
|
399 |
+ checkSubmitOnce('free'); |
|
400 |
+ |
|
401 |
+ // Anything else for redisplaying the form |
|
402 |
+ $context['page_title'] = $txt['shd_helpdesk']; |
|
403 |
+ $context['sub_template'] = 'ticket_post'; |
|
404 |
+ |
|
405 |
+ shd_check_attachments(); |
|
406 |
+ |
|
407 |
+ // Set up the fancy editor |
|
408 |
+ shd_postbox( |
|
409 |
+ 'shd_message', |
|
410 |
+ un_preparsecode($context['ticket_form']['message']), |
|
411 |
+ array( |
|
412 |
+ 'post_button' => $context['ticket_form']['form_title'], |
|
413 |
+ ) |
|
414 |
+ ); |
|
415 |
+ |
|
416 |
+ // Build the link tree and navigation |
|
417 |
+ $context['linktree'][] = array( |
|
418 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
419 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
420 |
+ ); |
|
421 |
+ $context['linktree'][] = array( |
|
422 |
+ 'name' => $new_ticket ? $txt['shd_create_ticket'] : sprintf($txt['shd_edit_ticket_linktree'], $context['ticket_form']['link']), |
|
423 |
+ ); |
|
424 |
+ |
|
425 |
+ checkSubmitOnce('register'); |
|
426 |
+ } |
|
427 |
+ else |
|
428 |
+ { |
|
429 |
+ // It all worked, w00t, so let's get ready to rumble |
|
430 |
+ $attachIDs = shd_handle_attachments(); |
|
431 |
+ |
|
432 |
+ if ($new_ticket) |
|
433 |
+ { |
|
434 |
+ // Now to add the ticket details |
|
435 |
+ $posterOptions = array( |
|
436 |
+ 'id' => $user_info['id'], |
|
437 |
+ ); |
|
438 |
+ |
|
439 |
+ $msgOptions = array( |
|
440 |
+ 'body' => $context['ticket_form']['message'], |
|
441 |
+ 'id' => $context['ticket_form']['msg'], |
|
442 |
+ 'smileys_enabled' => empty($context['ticket_form']['disable_smileys']), |
|
443 |
+ 'attachments' => $attachIDs, |
|
444 |
+ ); |
|
445 |
+ |
|
446 |
+ $ticketOptions = array( |
|
447 |
+ 'id' => $context['ticket_form']['ticket'], |
|
448 |
+ 'mark_as_read' => true, |
|
449 |
+ 'subject' => $context['ticket_form']['subject'], |
|
450 |
+ 'private' => $context['ticket_form']['private']['setting'], |
|
451 |
+ 'status' => $context['ticket_form']['status'], |
|
452 |
+ 'urgency' => $context['ticket_form']['urgency']['setting'], |
|
453 |
+ 'assigned' => $context['ticket_form']['assigned']['id'], |
|
454 |
+ ); |
|
455 |
+ shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
456 |
+ shd_clear_active_tickets(); |
|
457 |
+ |
|
458 |
+ // Update our nice ticket store with the ticket id |
|
459 |
+ $context['ticket_id'] = $ticketOptions['id']; |
|
460 |
+ $context['ticket_form']['ticket'] = $ticketOptions['id']; |
|
461 |
+ } |
|
462 |
+ else |
|
463 |
+ { |
|
464 |
+ // Only add what has actually changed |
|
465 |
+ // Now to add the ticket details |
|
466 |
+ $posterOptions = array(); |
|
467 |
+ |
|
468 |
+ $msgOptions = array( |
|
469 |
+ 'id' => $context['ticket_form']['msg'], |
|
470 |
+ 'attachments' => $attachIDs, |
|
471 |
+ ); |
|
472 |
+ |
|
473 |
+ $ticketOptions = array( |
|
474 |
+ 'id' => $context['ticket_form']['ticket'], |
|
475 |
+ ); |
|
476 |
+ |
|
477 |
+ if ((bool) $ticketinfo['smileys_enabled'] == $context['ticket_form']['disable_smileys']) // since one is enabled, one is 'now disable'... |
|
478 |
+ $msgOptions['smileys_enabled'] = !$context['ticket_form']['disable_smileys']; |
|
479 |
+ |
|
480 |
+ // This things don't trigger modified time |
|
481 |
+ if ($ticketinfo['private'] != $context['ticket_form']['private']['setting']) |
|
482 |
+ { |
|
483 |
+ $ticketOptions['private'] = $context['ticket_form']['private']['setting']; |
|
484 |
+ // log the change too |
|
485 |
+ $action = empty($context['ticket_form']['private']['setting']) ? 'marknotprivate' : 'markprivate'; // i.e. based on new setting |
|
486 |
+ shd_log_action($action, |
|
487 |
+ array( |
|
488 |
+ 'ticket' => $context['ticket_form']['ticket'], |
|
489 |
+ 'subject' => $context['ticket_form']['subject'], |
|
490 |
+ ) |
|
491 |
+ ); |
|
492 |
+ } |
|
493 |
+ if ($ticketinfo['urgency'] != $context['ticket_form']['urgency']['setting']) |
|
494 |
+ { |
|
495 |
+ $ticketOptions['urgency'] = $context['ticket_form']['urgency']['setting']; |
|
496 |
+ // log the change too |
|
497 |
+ $action = ($context['ticket_form']['urgency']['setting'] > $ticketinfo['urgency']) ? 'urgency_increase' : 'urgency_decrease'; |
|
498 |
+ shd_log_action($action, |
|
499 |
+ array( |
|
500 |
+ 'ticket' => $context['ticket_form']['ticket'], |
|
501 |
+ 'subject' => $context['ticket_form']['subject'], |
|
502 |
+ 'urgency' => $context['ticket_form']['urgency']['setting'], |
|
503 |
+ ) |
|
504 |
+ ); |
|
505 |
+ } |
|
506 |
+ |
|
507 |
+ // But these things do! |
|
508 |
+ if ($ticketinfo['subject'] != $context['ticket_form']['subject']) |
|
509 |
+ $ticketOptions['subject'] = $context['ticket_form']['subject']; |
|
510 |
+ if ($ticketinfo['body'] != $context['ticket_form']['message']) |
|
511 |
+ $msgOptions['body'] = $context['ticket_form']['message']; |
|
512 |
+ |
|
513 |
+ if (isset($ticketOptions['subject']) || isset($msgOptions['body'])) |
|
514 |
+ $msgOptions['modified'] = array( |
|
515 |
+ 'id' => $user_info['id'], |
|
516 |
+ 'name' => $user_info['name'], |
|
517 |
+ 'time' => time(), |
|
518 |
+ ); |
|
519 |
+ |
|
520 |
+ // DOOOOOOOO EEEEEEEEEEET NAO! |
|
521 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
522 |
+ shd_clear_active_tickets($ticketinfo['id_member_started']); |
|
523 |
+ } |
|
524 |
+ shd_done_posting(); |
|
525 |
+ } |
|
526 |
+} |
|
527 |
+ |
|
528 |
+function shd_post_reply() |
|
529 |
+{ |
|
530 |
+ global $context, $user_info, $sourcedir, $txt, $scripturl, $smcFunc, $reply_request, $modSettings, $settings, $options, $memberContext; |
|
531 |
+ |
|
532 |
+ checkSession('get'); |
|
533 |
+ |
|
534 |
+ $new_reply = $_REQUEST['sa'] == 'reply'; |
|
535 |
+ |
|
536 |
+ // Things we need |
|
537 |
+ loadTemplate('SimpleDesk-Post'); |
|
538 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
539 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
540 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
541 |
+ |
|
542 |
+ $ticketinfo = shd_load_ticket(); |
|
543 |
+ $reply = array(); |
|
544 |
+ |
|
545 |
+ // So, at this point, we can see it, but no guarantee we can reply to it. |
|
546 |
+ // Can we reply to any? If so, just go right along. If not, we need to do more work. |
|
547 |
+ if ($new_reply) |
|
548 |
+ { |
|
549 |
+ if (!shd_allowed_to('shd_reply_ticket_any')) |
|
550 |
+ { |
|
551 |
+ if (shd_allowed_to('shd_reply_ticket_own')) |
|
552 |
+ { |
|
553 |
+ if (!$ticketinfo['is_own']) |
|
554 |
+ fatal_lang_error('shd_cannot_reply_any_but_own', false); |
|
555 |
+ } |
|
556 |
+ else |
|
557 |
+ fatal_lang_error('shd_cannot_reply_any', false); // can't do nuthin' |
|
558 |
+ } |
|
559 |
+ } |
|
560 |
+ else |
|
561 |
+ { |
|
562 |
+ $_REQUEST['msg'] = !empty($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0; |
|
563 |
+ $query = shd_db_query('', ' |
|
564 |
+ SELECT id_msg, id_member, body, modified_time, modified_member, modified_name |
|
565 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
566 |
+ WHERE id_msg = {int:msg} |
|
567 |
+ AND id_ticket = {int:ticket}', |
|
568 |
+ array( |
|
569 |
+ 'msg' => $_REQUEST['msg'], |
|
570 |
+ 'ticket' => $context['ticket_id'], |
|
571 |
+ ) |
|
572 |
+ ); |
|
573 |
+ |
|
574 |
+ if ($smcFunc['db_num_rows']($query) == 0) |
|
575 |
+ { |
|
576 |
+ $smcFunc['db_free_result']($query); |
|
577 |
+ fatal_lang_error('shd_no_ticket', false); |
|
578 |
+ } |
|
579 |
+ |
|
580 |
+ $reply = $smcFunc['db_fetch_assoc']($query); |
|
581 |
+ |
|
582 |
+ if (!shd_allowed_to('shd_edit_reply_any')) |
|
583 |
+ { |
|
584 |
+ if (shd_allowed_to('shd_edit_reply_own')) |
|
585 |
+ { |
|
586 |
+ if ($reply['id_member'] != $user_info['id']) |
|
587 |
+ fatal_lang_error('shd_cannot_edit_reply_any_but_own', false); |
|
588 |
+ } |
|
589 |
+ else |
|
590 |
+ fatal_lang_error('shd_cannot_edit_reply_any', false); |
|
591 |
+ } |
|
592 |
+ |
|
593 |
+ // Fix the body up for later |
|
594 |
+ $reply['body'] = un_preparsecode($reply['body']); |
|
595 |
+ censorText($reply['body']); |
|
596 |
+ } |
|
597 |
+ |
|
598 |
+ // So it's either our ticket and we can reply to our own, or we can reply to any because we're awesome |
|
599 |
+ // or we're editing and we can haz such powarz |
|
600 |
+ $context['ticket_form'] = array( // yes, everything goes in here. |
|
601 |
+ 'form_title' => !empty($reply['id_msg']) ? $txt['shd_ticket_edit_reply'] : $txt['shd_reply_ticket'], |
|
602 |
+ 'form_action' => $scripturl . '?action=helpdesk;sa=savereply', |
|
603 |
+ 'first_msg' => $new_reply ? 0 : $ticketinfo['id_first_msg'], |
|
604 |
+ 'message' => shd_format_text($ticketinfo['body'], $ticketinfo['smileys_enabled'], 'shd_ticket_' . $context['ticket_id']), |
|
605 |
+ 'subject' => $ticketinfo['subject'], |
|
606 |
+ 'ticket' => $context['ticket_id'], |
|
607 |
+ 'msg' => !empty($reply['id_msg']) ? $reply['id_msg'] : 0, |
|
608 |
+ 'ticket_link' => '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '">' . $ticketinfo['subject'] . '</a>', |
|
609 |
+ 'reply_link' => $new_reply ? 0 : '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '.msg' . $reply['id_msg'] . '#msg' . $reply['id_msg'] . '">' . $txt['response_prefix'] . ' ' . $ticketinfo['subject'] . '</a>', |
|
610 |
+ 'display_id' => str_pad($context['ticket_id'], 5, '0', STR_PAD_LEFT), |
|
611 |
+ 'status' => $ticketinfo['status'], |
|
612 |
+ 'urgency' => array( |
|
613 |
+ 'setting' => $ticketinfo['urgency'], |
|
614 |
+ ), |
|
615 |
+ 'private' => array( |
|
616 |
+ 'setting' => $ticketinfo['private'], |
|
617 |
+ 'can_change' => false, |
|
618 |
+ 'options' => array( |
|
619 |
+ 0 => 'shd_ticket_notprivate', |
|
620 |
+ 1 => 'shd_ticket_private', |
|
621 |
+ ), |
|
622 |
+ ), |
|
623 |
+ 'errors' => array(), |
|
624 |
+ 'member' => array( |
|
625 |
+ 'name' => $ticketinfo['starter_name'], |
|
626 |
+ 'id' => $ticketinfo['starter_id'], |
|
627 |
+ 'link' => shd_profile_link($ticketinfo['starter_name'], $ticketinfo['starter_id']), |
|
628 |
+ ), |
|
629 |
+ 'assigned' => array( |
|
630 |
+ 'id' => $ticketinfo['assigned_id'], |
|
631 |
+ 'name' => !empty($ticketinfo['assigned_id']) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], |
|
632 |
+ 'link' => !empty($ticketinfo['assigned_id']) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
633 |
+ ), |
|
634 |
+ 'num_replies' => !empty($ticketinfo['num_replies']) ? $ticketinfo['num_replies'] : 0, |
|
635 |
+ 'do_attach' => shd_allowed_to('shd_post_attachment'), |
|
636 |
+ 'reply' => !empty($reply['body']) ? $reply['body'] : '', |
|
637 |
+ 'return_to_ticket' => isset($_REQUEST['goback']), |
|
638 |
+ 'disable_smileys' => !$new_reply ? !empty($_REQUEST['no_smileys']) : ($ticketinfo['smileys_enabled'] == 0), |
|
639 |
+ ); |
|
640 |
+ |
|
641 |
+ // Ticket privacy |
|
642 |
+ if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') |
|
643 |
+ $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any') || shd_allowed_to('shd_alter_privacy_own') || shd_allowed_to('shd_alter_privacy_any') || $context['ticket_form']['private']['setting']; |
|
644 |
+ else |
|
645 |
+ $context['display_private'] = true; |
|
646 |
+ |
|
647 |
+ loadMemberData($ticketinfo['starter_id']); |
|
648 |
+ if (loadMemberContext($ticketinfo['starter_id'])) |
|
649 |
+ $context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar']; |
|
650 |
+ |
|
651 |
+ if (!empty($ticketinfo['modified_time'])) |
|
652 |
+ { |
|
653 |
+ $context['ticket_form'] += array( |
|
654 |
+ 'modified' => array( |
|
655 |
+ 'name' => $ticketinfo['modified_name'], |
|
656 |
+ 'id' => $ticketinfo['modified_id'], |
|
657 |
+ 'time' => timeformat($ticketinfo['modified_time']), |
|
658 |
+ 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id']), |
|
659 |
+ ), |
|
660 |
+ ); |
|
661 |
+ } |
|
662 |
+ |
|
663 |
+ shd_get_urgency_options($ticketinfo['is_own']); |
|
664 |
+ $context['ticket_form']['urgency']['can_change'] = false; |
|
665 |
+ |
|
666 |
+ if (!empty($ticketinfo['num_replies'])) |
|
667 |
+ shd_setup_replies($ticketinfo['id_first_msg']); |
|
668 |
+ |
|
669 |
+ // A few basic checks |
|
670 |
+ if ($context['ticket_form']['status'] == TICKET_STATUS_CLOSED) |
|
671 |
+ fatal_lang_error('shd_cannot_reply_closed', false); |
|
672 |
+ elseif ($context['ticket_form']['status'] == TICKET_STATUS_DELETED) |
|
673 |
+ fatal_lang_error('shd_cannon_reply_deleted', false); |
|
674 |
+ |
|
675 |
+ shd_load_attachments(); |
|
676 |
+ shd_check_attachments(); |
|
677 |
+ |
|
678 |
+ if (empty($options['no_new_reply_warning']) && isset($_REQUEST['num_replies'])) |
|
679 |
+ { |
|
680 |
+ $_REQUEST['num_replies'] = (int) $_REQUEST['num_replies']; |
|
681 |
+ $newReplies = $context['ticket_form']['num_replies'] > $_REQUEST['num_replies'] ? $context['ticket_form']['num_replies'] - $_REQUEST['num_replies'] : 0; |
|
682 |
+ |
|
683 |
+ if (!empty($newReplies)) |
|
684 |
+ { |
|
685 |
+ loadLanguage('Post'); |
|
686 |
+ if ($newReplies > 1) |
|
687 |
+ $txt['error_new_replies_reading'] = sprintf($txt['error_new_replies_reading'], $newReplies); |
|
688 |
+ |
|
689 |
+ $context['shd_errors'][] = $newReplies == 1 ? 'new_reply_reading' : 'new_replies_reading'; |
|
690 |
+ } |
|
691 |
+ } |
|
692 |
+ |
|
693 |
+ // Are we quoting something? Let's see if we do; we already know we can see the ticket |
|
694 |
+ $_REQUEST['quote'] = !empty($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : 0; |
|
695 |
+ if (!empty($_REQUEST['quote'])) |
|
696 |
+ { |
|
697 |
+ $query = shd_db_query('', ' |
|
698 |
+ SELECT hdtr.body, IFNULL(mem.real_name, hdtr.poster_name) AS poster_name, hdtr.poster_time |
|
699 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
700 |
+ LEFT JOIN {db_prefix}members AS mem ON (hdtr.id_member = mem.id_member) |
|
701 |
+ WHERE id_msg = {int:msg} |
|
702 |
+ AND id_ticket = {int:ticket}', |
|
703 |
+ array( |
|
704 |
+ 'msg' => $_REQUEST['quote'], |
|
705 |
+ 'ticket' => $context['ticket_id'], // make sure it's actually in this ticket! |
|
706 |
+ ) |
|
707 |
+ ); |
|
708 |
+ |
|
709 |
+ if ($row = $smcFunc['db_fetch_assoc']($query)) |
|
710 |
+ { |
|
711 |
+ $smcFunc['db_free_result']($query); |
|
712 |
+ |
|
713 |
+ $row['body'] = un_preparsecode($row['body']); |
|
714 |
+ |
|
715 |
+ // Censor the message! |
|
716 |
+ censorText($row['body']); |
|
717 |
+ $row['body'] = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']); |
|
718 |
+ |
|
719 |
+ if (strpos($row['poster_name'], '[') !== false || strpos($row['poster_name'], ']') !== false) |
|
720 |
+ $row['poster_name'] = '"' . $row['poster_name'] . '"'; |
|
721 |
+ |
|
722 |
+ // Make the body HTML if need be. |
|
723 |
+ if (!empty($_REQUEST['mode'])) |
|
724 |
+ { |
|
725 |
+ require_once($sourcedir . '/Subs-Editor.php'); |
|
726 |
+ $row['body'] = strtr($row['body'], array('<' => '#smlt#', '>' => '#smgt#', '&' => '#smamp#')); |
|
727 |
+ $row['body'] = bbc_to_html($row['body']); |
|
728 |
+ $lb = '<br />'; |
|
729 |
+ } |
|
730 |
+ else |
|
731 |
+ $lb = "\n"; |
|
732 |
+ |
|
733 |
+ $message = '[quote author=' . $row['poster_name'] . ' link=action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']; |
|
734 |
+ if ($ticketinfo['id_first_msg'] != $_REQUEST['quote']) // don't add the msg if we're quoting the ticket itself |
|
735 |
+ $message .= '.msg' . $_REQUEST['quote'] . '#msg' . $_REQUEST['quote']; |
|
736 |
+ |
|
737 |
+ $message .= ' date=' . $row['poster_time'] . ']' . $lb . $row['body'] . $lb . '[/quote]'; |
|
738 |
+ $context['ticket_form']['reply'] = $message; |
|
739 |
+ } |
|
740 |
+ } |
|
741 |
+ |
|
742 |
+ // Set up the awesomeness that is the rich editor |
|
743 |
+ shd_postbox( |
|
744 |
+ 'shd_message', |
|
745 |
+ $context['ticket_form']['reply'], |
|
746 |
+ array( |
|
747 |
+ 'post_button' => !empty($reply['id_msg']) ? $txt['shd_ticket_edit_reply'] : $txt['shd_reply_ticket'], |
|
748 |
+ ) |
|
749 |
+ ); |
|
750 |
+ |
|
751 |
+ // Build the link tree and navigation |
|
752 |
+ $context['linktree'][] = array( |
|
753 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
754 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
755 |
+ ); |
|
756 |
+ $context['linktree'][] = array( |
|
757 |
+ 'name' => $new_reply ? sprintf($txt['shd_reply_ticket_linktree'], $context['ticket_form']['ticket_link']) : sprintf($txt['shd_edit_reply_linktree'], $context['ticket_form']['reply_link']), |
|
758 |
+ ); |
|
759 |
+ |
|
760 |
+ $context['page_title'] = $txt['shd_helpdesk']; |
|
761 |
+ $context['sub_template'] = 'reply_post'; |
|
762 |
+ |
|
763 |
+ // Register this form in the session variables. |
|
764 |
+ checkSubmitOnce('register'); |
|
765 |
+} |
|
766 |
+ |
|
767 |
+function shd_save_reply() |
|
768 |
+{ |
|
769 |
+ global $txt, $modSettings, $sourcedir, $context, $scripturl; |
|
770 |
+ global $user_info, $options, $smcFunc, $memberContext; |
|
771 |
+ |
|
772 |
+ $_REQUEST['msg'] = !empty($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0; |
|
773 |
+ |
|
774 |
+ // We're replying so there must be an existing ticket or sumthin's WRONG. |
|
775 |
+ $ticketinfo = shd_load_ticket(); |
|
776 |
+ $reply = array(); |
|
777 |
+ $new_reply = $_REQUEST['msg'] == 0; |
|
778 |
+ |
|
779 |
+ // So, at this point, we can see it, but no guarantee we can reply to it. |
|
780 |
+ // Can we reply to any? If so, just go right along. If not, we need to do more work. |
|
781 |
+ if ($new_reply) |
|
782 |
+ { |
|
783 |
+ if (!shd_allowed_to('shd_reply_ticket_any')) |
|
784 |
+ { |
|
785 |
+ if (shd_allowed_to('shd_reply_ticket_own')) |
|
786 |
+ { |
|
787 |
+ if (!$ticketinfo['is_own']) |
|
788 |
+ fatal_lang_error('shd_cannot_reply_any_but_own', false); |
|
789 |
+ } |
|
790 |
+ else |
|
791 |
+ fatal_lang_error('shd_cannot_reply_any', false); // can't do nuthin' |
|
792 |
+ } |
|
793 |
+ } |
|
794 |
+ else |
|
795 |
+ { |
|
796 |
+ $query = shd_db_query('', ' |
|
797 |
+ SELECT id_msg, id_member, body, modified_time, modified_member, modified_name |
|
798 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
799 |
+ WHERE id_msg = {int:msg} |
|
800 |
+ AND id_ticket = {int:ticket}', |
|
801 |
+ array( |
|
802 |
+ 'msg' => $_REQUEST['msg'], |
|
803 |
+ 'ticket' => $context['ticket_id'], |
|
804 |
+ ) |
|
805 |
+ ); |
|
806 |
+ |
|
807 |
+ if ($smcFunc['db_num_rows']($query) == 0) |
|
808 |
+ { |
|
809 |
+ $smcFunc['db_free_result']($query); |
|
810 |
+ fatal_lang_error('shd_no_ticket', false); |
|
811 |
+ } |
|
812 |
+ |
|
813 |
+ $reply = $smcFunc['db_fetch_assoc']($query); |
|
814 |
+ |
|
815 |
+ if (!shd_allowed_to('shd_edit_reply_any')) |
|
816 |
+ { |
|
817 |
+ if (shd_allowed_to('shd_edit_reply_own')) |
|
818 |
+ { |
|
819 |
+ if ($reply['id_member'] != $user_info['id']) |
|
820 |
+ fatal_lang_error('shd_cannot_edit_reply_any_but_own', false); |
|
821 |
+ } |
|
822 |
+ else |
|
823 |
+ fatal_lang_error('shd_cannot_edit_reply_any', false); |
|
824 |
+ } |
|
825 |
+ } |
|
826 |
+ |
|
827 |
+ $context['ticket_form'] = array( |
|
828 |
+ 'form_title' => $new_reply ? $txt['shd_reply_ticket'] : $txt['shd_ticket_edit_reply'], |
|
829 |
+ 'form_action' => $scripturl . '?action=helpdesk;sa=savereply', |
|
830 |
+ 'first_msg' => $new_reply ? 0 : $ticketinfo['id_first_msg'], |
|
831 |
+ 'message' => shd_format_text($ticketinfo['body'], $ticketinfo['smileys_enabled'], 'shd_ticket_' . $context['ticket_id']), |
|
832 |
+ 'subject' => $ticketinfo['subject'], |
|
833 |
+ 'ticket' => $context['ticket_id'], |
|
834 |
+ 'msg' => $_REQUEST['msg'], |
|
835 |
+ 'display_id' => str_pad($context['ticket_id'], 5, '0', STR_PAD_LEFT), |
|
836 |
+ 'urgency' => array( |
|
837 |
+ 'setting' => $ticketinfo['urgency'], |
|
838 |
+ ), |
|
839 |
+ 'private' => array( |
|
840 |
+ 'setting' => $ticketinfo['private'], |
|
841 |
+ 'can_change' => false, |
|
842 |
+ 'options' => array( |
|
843 |
+ 0 => 'shd_ticket_notprivate', |
|
844 |
+ 1 => 'shd_ticket_private', |
|
845 |
+ ), |
|
846 |
+ ), |
|
847 |
+ 'status' => $ticketinfo['status'], // reuse existing status for now |
|
848 |
+ 'assigned' => array( |
|
849 |
+ 'id' => $ticketinfo['assigned_id'], |
|
850 |
+ 'name' => !empty($ticketinfo['assigned_id']) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], |
|
851 |
+ 'link' => !empty($ticketinfo['assigned_id']) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>', |
|
852 |
+ ), |
|
853 |
+ 'num_replies' => $ticketinfo['num_replies'], |
|
854 |
+ 'do_attach' => shd_allowed_to('shd_post_attachment'), |
|
855 |
+ 'reply' => $_POST['shd_message'], |
|
856 |
+ 'return_to_ticket' => isset($_REQUEST['goback']), |
|
857 |
+ 'disable_smileys' => !empty($_REQUEST['no_smileys']), |
|
858 |
+ ); |
|
859 |
+ |
|
860 |
+ // Ticket privacy |
|
861 |
+ if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') |
|
862 |
+ $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any') || shd_allowed_to('shd_alter_privacy_own') || shd_allowed_to('shd_alter_privacy_any') || $context['ticket_form']['private']['setting']; |
|
863 |
+ else |
|
864 |
+ $context['display_private'] = true; |
|
865 |
+ |
|
866 |
+ loadMemberData($ticketinfo['starter_id']); |
|
867 |
+ if (loadMemberContext($ticketinfo['starter_id'])) |
|
868 |
+ $context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar']; |
|
869 |
+ |
|
870 |
+ if (!empty($ticketinfo['modified_time'])) |
|
871 |
+ { |
|
872 |
+ $context['ticket_form'] += array( |
|
873 |
+ 'modified' => array( |
|
874 |
+ 'name' => $ticketinfo['modified_name'], |
|
875 |
+ 'id' => $ticketinfo['modified_id'], |
|
876 |
+ 'time' => timeformat($ticketinfo['modified_time']), |
|
877 |
+ 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id']), |
|
878 |
+ ), |
|
879 |
+ ); |
|
880 |
+ } |
|
881 |
+ |
|
882 |
+ if (isset($_REQUEST['preview'])) |
|
883 |
+ { |
|
884 |
+ $context['ticket_form']['preview'] = array( |
|
885 |
+ 'title' => $txt['shd_previewing_reply'] . ': ' . (empty($context['ticket_form']['subject']) ? '<em>' . $txt['no_subject'] . '</em>' : $context['ticket_form']['subject']), |
|
886 |
+ 'body' => shd_format_text($_POST['shd_message']), |
|
887 |
+ ); |
|
888 |
+ } |
|
889 |
+ |
|
890 |
+ shd_load_attachments(); |
|
891 |
+ |
|
892 |
+ shd_get_urgency_options($ticketinfo['is_own']); |
|
893 |
+ $context['ticket_form']['urgency']['can_change'] = false; |
|
894 |
+ |
|
895 |
+ if (!empty($ticketinfo['num_replies'])) |
|
896 |
+ shd_setup_replies($ticketinfo['id_first_msg']); |
|
897 |
+ |
|
898 |
+ // A few basic checks |
|
899 |
+ if ($context['ticket_form']['status'] == TICKET_STATUS_CLOSED) |
|
900 |
+ fatal_lang_error('shd_cannot_edit_closed', false); |
|
901 |
+ elseif ($context['ticket_form']['status'] == TICKET_STATUS_DELETED) |
|
902 |
+ fatal_lang_error('shd_cannon_edit_deleted', false); |
|
903 |
+ |
|
904 |
+ // Have there been any new replies that we missed? |
|
905 |
+ if (empty($options['no_new_reply_warning']) && isset($_REQUEST['num_replies'])) |
|
906 |
+ { |
|
907 |
+ $_REQUEST['num_replies'] = (int) $_REQUEST['num_replies']; |
|
908 |
+ $newReplies = $context['ticket_form']['num_replies'] > $_REQUEST['num_replies'] ? $context['ticket_form']['num_replies'] - $_REQUEST['num_replies'] : 0; |
|
909 |
+ |
|
910 |
+ if (!empty($newReplies)) |
|
911 |
+ { |
|
912 |
+ loadLanguage('Post'); |
|
913 |
+ if ($newReplies > 1) |
|
914 |
+ $txt['error_new_replies'] = sprintf($txt['error_new_replies'], $newReplies); |
|
915 |
+ |
|
916 |
+ $context['shd_errors'][] = $newReplies == 1 ? 'new_reply' : 'new_replies'; |
|
917 |
+ } |
|
918 |
+ } |
|
919 |
+ |
|
920 |
+ if (!empty($context['shd_errors']) || !empty($context['ticket_form']['preview'])) // Uh oh, something went wrong, or we're previewing |
|
921 |
+ { |
|
922 |
+ checkSubmitOnce('free'); |
|
923 |
+ |
|
924 |
+ // Anything else for redisplaying the form |
|
925 |
+ $context['page_title'] = $txt['shd_helpdesk']; |
|
926 |
+ $context['sub_template'] = 'reply_post'; |
|
927 |
+ |
|
928 |
+ shd_check_attachments(); |
|
929 |
+ |
|
930 |
+ // Set up the fancy editor |
|
931 |
+ shd_postbox( |
|
932 |
+ 'shd_message', |
|
933 |
+ un_preparsecode($_POST['shd_message']), |
|
934 |
+ array( |
|
935 |
+ 'post_button' => $new_reply ? $txt['shd_reply_ticket'] : $txt['shd_ticket_edit_reply'], |
|
936 |
+ ) |
|
937 |
+ ); |
|
938 |
+ |
|
939 |
+ // Build the link tree and navigation |
|
940 |
+ $context['linktree'][] = array( |
|
941 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
942 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
943 |
+ ); |
|
944 |
+ $context['linktree'][] = array( |
|
945 |
+ 'name' => $txt['shd_reply_ticket'], |
|
946 |
+ ); |
|
947 |
+ |
|
948 |
+ checkSubmitOnce('register'); |
|
949 |
+ } |
|
950 |
+ else |
|
951 |
+ { |
|
952 |
+ // It all worked, w00t, so let's get ready to rumble |
|
953 |
+ $attachIDs = shd_handle_attachments(); |
|
954 |
+ shd_clear_active_tickets($ticketinfo['id_member_started']); |
|
955 |
+ |
|
956 |
+ if ($new_reply) |
|
957 |
+ { |
|
958 |
+ // So... what is the new status? |
|
959 |
+ $new_status = shd_determine_status('reply', $ticketinfo['starter_id'], $user_info['id']); |
|
960 |
+ |
|
961 |
+ // Now to add the ticket details |
|
962 |
+ $posterOptions = array( |
|
963 |
+ 'id' => $user_info['id'], |
|
964 |
+ ); |
|
965 |
+ |
|
966 |
+ $msgOptions = array( |
|
967 |
+ 'body' => $_POST['shd_message'], |
|
968 |
+ 'id' => $context['ticket_form']['msg'], |
|
969 |
+ 'smileys_enabled' => empty($context['ticket_form']['disable_smileys']), |
|
970 |
+ 'attachments' => $attachIDs, |
|
971 |
+ ); |
|
972 |
+ |
|
973 |
+ $ticketOptions = array( |
|
974 |
+ 'id' => $context['ticket_form']['ticket'], |
|
975 |
+ 'mark_as_read' => true, |
|
976 |
+ 'status' => $new_status, |
|
977 |
+ ); |
|
978 |
+ shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
979 |
+ } |
|
980 |
+ else |
|
981 |
+ { |
|
982 |
+ // Only add what has actually changed |
|
983 |
+ // Now to add the ticket details |
|
984 |
+ $posterOptions = array(); |
|
985 |
+ |
|
986 |
+ $msgOptions = array( |
|
987 |
+ 'id' => $context['ticket_form']['msg'], |
|
988 |
+ 'attachments' => $attachIDs, |
|
989 |
+ ); |
|
990 |
+ |
|
991 |
+ $ticketOptions = array( |
|
992 |
+ 'id' => $context['ticket_form']['ticket'], |
|
993 |
+ ); |
|
994 |
+ |
|
995 |
+ if ((bool) $ticketinfo['smileys_enabled'] == $context['ticket_form']['disable_smileys']) // since one is enabled, one is 'now disable'... |
|
996 |
+ $msgOptions['smileys_enabled'] = !$context['ticket_form']['disable_smileys']; |
|
997 |
+ |
|
998 |
+ if ($reply['body'] != $context['ticket_form']['reply']) |
|
999 |
+ $msgOptions['body'] = $context['ticket_form']['reply']; |
|
1000 |
+ |
|
1001 |
+ if (isset($msgOptions['body'])) |
|
1002 |
+ $msgOptions['modified'] = array( |
|
1003 |
+ 'id' => $user_info['id'], |
|
1004 |
+ 'name' => $user_info['name'], |
|
1005 |
+ 'time' => time(), |
|
1006 |
+ ); |
|
1007 |
+ |
|
1008 |
+ // DOOOOOOOO EEEEEEEEEEET NAO! |
|
1009 |
+ shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
1010 |
+ } |
|
1011 |
+ |
|
1012 |
+ shd_done_posting(); |
|
1013 |
+ } |
|
1014 |
+} |
|
1015 |
+ |
|
1016 |
+/** |
|
1017 |
+ * Redirects the user once a ticket has been posted or replied to. |
|
1018 |
+ * |
|
1019 |
+ * Directs the user based on where they were and what was selected: |
|
1020 |
+ * - if 'return to ticket' was not selected, return to the front page |
|
1021 |
+ * - if it was, and we edited a reply, return to the reply |
|
1022 |
+ * - if it was select, but it was a new topic/reply, return just to the topic itself |
|
1023 |
+ * |
|
1024 |
+ * @since 1.0 |
|
1025 |
+*/ |
|
1026 |
+function shd_done_posting() |
|
1027 |
+{ |
|
1028 |
+ global $context; |
|
1029 |
+ if (empty($_REQUEST['goback'])) |
|
1030 |
+ redirectexit('action=helpdesk;sa=main'); |
|
1031 |
+ elseif (!empty($context['ticket_form']['msg'])) |
|
1032 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '.msg' . $context['ticket_form']['msg'] . '#msg' . $context['ticket_form']['msg'], $context['browser']['is_ie']); |
|
1033 |
+ else |
|
1034 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
1035 |
+} |
|
1036 |
+ |
|
1037 |
+function shd_setup_replies($first_msg) |
|
1038 |
+{ |
|
1039 |
+ global $reply_request, $context, $smcFunc, $sourcedir, $modSettings, $settings; |
|
1040 |
+ |
|
1041 |
+ $context['ticket_form']['do_replies'] = false; |
|
1042 |
+ $context['can_quote'] = false; |
|
1043 |
+ |
|
1044 |
+ // OK, we're done with the ticket's own data. Now for replies. |
|
1045 |
+ $context['get_replies'] = 'shd_prepare_reply_context'; |
|
1046 |
+ $query = shd_db_query('', ' |
|
1047 |
+ SELECT id_msg, id_member, modified_member |
|
1048 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
1049 |
+ WHERE id_ticket = {int:ticket} |
|
1050 |
+ AND message_status = {int:msg_normal} |
|
1051 |
+ AND id_msg > {int:first_msg}' . ((empty($context['ticket_form']['msg']) || $context['ticket_form']['msg'] == $context['ticket_form']['first_msg']) ? '' : ' |
|
1052 |
+ AND id_msg < {int:reply_msg}') . ' |
|
1053 |
+ ORDER BY id_msg DESC |
|
1054 |
+ LIMIT 10', |
|
1055 |
+ array( |
|
1056 |
+ 'ticket' => $context['ticket_id'], |
|
1057 |
+ 'msg_normal' => MSG_STATUS_NORMAL, |
|
1058 |
+ 'first_msg' => $first_msg, |
|
1059 |
+ 'reply_msg' => !empty($context['ticket_form']['msg']) ? $context['ticket_form']['msg'] : 0, |
|
1060 |
+ ) |
|
1061 |
+ ); |
|
1062 |
+ |
|
1063 |
+ $messages = array(); |
|
1064 |
+ $posters = array(); |
|
1065 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
1066 |
+ { |
|
1067 |
+ if (!empty($row['id_member'])) |
|
1068 |
+ $posters[] = $row['id_member']; |
|
1069 |
+ |
|
1070 |
+ if (!empty($row['modified_member'])) |
|
1071 |
+ $posters[] = $row['modified_member']; |
|
1072 |
+ |
|
1073 |
+ $messages[] = $row['id_msg']; |
|
1074 |
+ } |
|
1075 |
+ $smcFunc['db_free_result']($query); |
|
1076 |
+ |
|
1077 |
+ $posters = array_unique($posters); |
|
1078 |
+ |
|
1079 |
+ $context['is_team'] = array(); |
|
1080 |
+ |
|
1081 |
+ if (!empty($messages)) |
|
1082 |
+ { |
|
1083 |
+ $context['ticket_form']['do_replies'] = true; |
|
1084 |
+ |
|
1085 |
+ // Get the poster data |
|
1086 |
+ if (!empty($posters)) |
|
1087 |
+ { |
|
1088 |
+ loadMemberData($posters); |
|
1089 |
+ |
|
1090 |
+ // Are they current team members? |
|
1091 |
+ $team = array_intersect($posters, shd_members_allowed_to('shd_staff')); |
|
1092 |
+ |
|
1093 |
+ foreach ($team as $member) |
|
1094 |
+ $context['is_team'][$member] = true; |
|
1095 |
+ } |
|
1096 |
+ |
|
1097 |
+ $reply_request = shd_db_query('', ' |
|
1098 |
+ SELECT |
|
1099 |
+ id_msg, poster_time, poster_ip, id_member, modified_time, modified_name, modified_member, body, |
|
1100 |
+ smileys_enabled, poster_name, poster_email |
|
1101 |
+ FROM {db_prefix}helpdesk_ticket_replies |
|
1102 |
+ WHERE id_msg IN ({array_int:message_list}) |
|
1103 |
+ ORDER BY id_msg DESC', |
|
1104 |
+ array( |
|
1105 |
+ 'message_list' => $messages, |
|
1106 |
+ ) |
|
1107 |
+ ); |
|
1108 |
+ |
|
1109 |
+ // Can we have a quote button in the replies? If so, we also need the relevant JS instantiation |
|
1110 |
+ if (!empty($modSettings['shd_allow_ticket_bbc'])) |
|
1111 |
+ { |
|
1112 |
+ $context['can_quote'] = true; |
|
1113 |
+ $context['html_headers'] .= ' |
|
1114 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
1115 |
+ var oQuickReply = new QuickReply({ |
|
1116 |
+ bDefaultCollapsed: false, |
|
1117 |
+ iTicketId: ' . $context['ticket_id'] . ', |
|
1118 |
+ iStart: ' . $context['start'] . ', |
|
1119 |
+ sScriptUrl: smf_scripturl, |
|
1120 |
+ sImagesUrl: "' . $settings['images_url'] . '", |
|
1121 |
+ sContainerId: "quickReplyOptions", |
|
1122 |
+ sImageId: "quickReplyExpand", |
|
1123 |
+ sImageCollapsed: "collapse.gif", |
|
1124 |
+ sImageExpanded: "expand.gif", |
|
1125 |
+ sJumpAnchor: "quickreply", |
|
1126 |
+ sHeaderId: "quickreplyheader", |
|
1127 |
+ sFooterId: "quickreplyfooter" |
|
1128 |
+ }); |
|
1129 |
+ // ]' . ']></script>'; |
|
1130 |
+ } |
|
1131 |
+ } |
|
1132 |
+ else |
|
1133 |
+ { |
|
1134 |
+ $reply_request = false; |
|
1135 |
+ $context['first_message'] = 0; |
|
1136 |
+ $context['first_new_message'] = false; |
|
1137 |
+ } |
|
1138 |
+} |
|
1139 |
+ |
|
1140 |
+function shd_postbox($id, $message, $buttons, $width = '70%') |
|
1141 |
+{ |
|
1142 |
+ global $context, $txt, $modSettings; |
|
1143 |
+ $editorOptions = array( |
|
1144 |
+ 'id' => $id, |
|
1145 |
+ 'value' => $message, |
|
1146 |
+ 'labels' => $buttons, |
|
1147 |
+ 'preview_type' => 0, |
|
1148 |
+ 'width' => $width, |
|
1149 |
+ 'disable_smiley_box' => empty($modSettings['shd_allow_ticket_bbc']) || $context['ticket_form']['disable_smileys'], |
|
1150 |
+ ); |
|
1151 |
+ if (empty($modSettings['shd_allow_ticket_bbc'])) |
|
1152 |
+ $modSettings['disable_wysiwyg'] = 1; |
|
1153 |
+ |
|
1154 |
+ // Hide any disabled tags. |
|
1155 |
+ if (!empty($modSettings['shd_enabled_bbc'])) |
|
1156 |
+ { |
|
1157 |
+ $enabled_tags = explode(',', $modSettings['shd_enabled_bbc']); |
|
1158 |
+ $disabled_tags = array(); |
|
1159 |
+ |
|
1160 |
+ // Loop through all the tags there are in this forum, and and each disabled tag to our 'hide-list'. |
|
1161 |
+ foreach (parse_bbc(false) AS $tag) |
|
1162 |
+ { |
|
1163 |
+ if (!in_array($tag['tag'], $enabled_tags) || $modSettings['shd_enabled_bbc'] == 'shd_all_tags_disabled') |
|
1164 |
+ $disabled_tags[] = $tag['tag']; |
|
1165 |
+ } |
|
1166 |
+ |
|
1167 |
+ // Add them to the editors hide var. |
|
1168 |
+ $modSettings['disabledBBC'] = implode(',', $disabled_tags); |
|
1169 |
+ } |
|
1170 |
+ |
|
1171 |
+ create_control_richedit($editorOptions); |
|
1172 |
+ $context['post_box_name'] = $editorOptions['id']; |
|
1173 |
+ |
|
1174 |
+ // Are there any restrictions on uploading attachments? |
|
1175 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
1176 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; // just in case we never actually go to the admin page!! |
|
1177 |
+ |
|
1178 |
+ $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', ')); |
|
1179 |
+ $context['attachment_restrictions'] = array(); |
|
1180 |
+ |
|
1181 |
+ if (!empty($modSettings['attachmentNumPerPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') |
|
1182 |
+ $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentNumPerPostLimit'], $modSettings['attachmentNumPerPostLimit']); |
|
1183 |
+ |
|
1184 |
+ if (!empty($modSettings['attachmentPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') |
|
1185 |
+ $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentPostLimit'], $modSettings['attachmentPostLimit']); |
|
1186 |
+ |
|
1187 |
+ if (!empty($modSettings['attachmentSizeLimit'])) |
|
1188 |
+ $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentSizeLimit'], $modSettings['attachmentSizeLimit']); |
|
1189 |
+} |
|
1190 |
+ |
|
1191 |
+function shd_prepare_reply_context() |
|
1192 |
+{ |
|
1193 |
+ global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc; |
|
1194 |
+ global $memberContext, $context, $reply_request; |
|
1195 |
+ |
|
1196 |
+ if (empty($reply_request)) |
|
1197 |
+ return false; |
|
1198 |
+ |
|
1199 |
+ $message = $smcFunc['db_fetch_assoc']($reply_request); |
|
1200 |
+ if (!$message) |
|
1201 |
+ { |
|
1202 |
+ $smcFunc['db_free_result']($reply_request); |
|
1203 |
+ return false; |
|
1204 |
+ } |
|
1205 |
+ |
|
1206 |
+ if (!loadMemberContext($message['id_member'], true)) |
|
1207 |
+ { |
|
1208 |
+ // Notice this information isn't used anywhere else.... |
|
1209 |
+ $memberContext[$message['id_member']]['name'] = $message['poster_name']; |
|
1210 |
+ $memberContext[$message['id_member']]['id'] = 0; |
|
1211 |
+ $memberContext[$message['id_member']]['group'] = $txt['guest_title']; |
|
1212 |
+ $memberContext[$message['id_member']]['link'] = $message['poster_name']; |
|
1213 |
+ $memberContext[$message['id_member']]['email'] = $message['poster_email']; |
|
1214 |
+ $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0); |
|
1215 |
+ $memberContext[$message['id_member']]['is_guest'] = true; |
|
1216 |
+ $memberContext[$message['id_member']]['group_stars'] = ''; |
|
1217 |
+ } |
|
1218 |
+ $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; |
|
1219 |
+ |
|
1220 |
+ censorText($message['body']); |
|
1221 |
+ $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']); |
|
1222 |
+ |
|
1223 |
+ $output = array( |
|
1224 |
+ 'id' => $message['id_msg'], |
|
1225 |
+ 'member' => &$memberContext[$message['id_member']], |
|
1226 |
+ 'time' => timeformat($message['poster_time']), |
|
1227 |
+ 'timestamp' => forum_time(true, $message['poster_time']), |
|
1228 |
+ 'body' => $message['body'], |
|
1229 |
+ 'is_team' => !empty($context['is_team'][$message['id_member']]), |
|
1230 |
+ 'can_edit' => shd_allowed_to('shd_edit_reply_any') || ($message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own')), |
|
1231 |
+ ); |
|
1232 |
+ |
|
1233 |
+ if (!empty($message['modified_time'])) |
|
1234 |
+ { |
|
1235 |
+ $output['modified'] = array( |
|
1236 |
+ 'time' => timeformat($message['modified_time']), |
|
1237 |
+ 'timestamp' => forum_time(true, $message['modified_time']), |
|
1238 |
+ 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, |
|
1239 |
+ 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name'], |
|
1240 |
+ ); |
|
1241 |
+ $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']); |
|
1242 |
+ } |
|
1243 |
+ |
|
1244 |
+ return $output; |
|
1245 |
+} |
|
1246 |
+ |
|
1247 |
+function shd_load_attachments() |
|
1248 |
+{ |
|
1249 |
+ global $smcFunc, $context, $modSettings; |
|
1250 |
+ |
|
1251 |
+ if (empty($context['current_attachments'])) |
|
1252 |
+ $context['current_attachments'] = array(); |
|
1253 |
+ |
|
1254 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
1255 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; // just in case we never actually go to the admin page!! |
|
1256 |
+ |
|
1257 |
+ $context['ticket_attach'][$modSettings['shd_attachments_mode']] = array(); |
|
1258 |
+ |
|
1259 |
+ // Get existing attachments |
|
1260 |
+ $query = shd_db_query('', ' |
|
1261 |
+ SELECT a.id_attach, a.filename |
|
1262 |
+ FROM {db_prefix}attachments AS a |
|
1263 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
1264 |
+ WHERE ' . ($modSettings['shd_attachments_mode'] == 'ticket' ? 'hda.id_ticket = {int:ticket}' : 'hda.id_msg = {int:msg}') . ' |
|
1265 |
+ AND a.attachment_type != {int:thumb} |
|
1266 |
+ ORDER BY hda.id_attach', |
|
1267 |
+ array( |
|
1268 |
+ 'msg' => $context['ticket_form']['msg'], |
|
1269 |
+ 'ticket' => $context['ticket_id'], |
|
1270 |
+ 'thumb' => 3, |
|
1271 |
+ ) |
|
1272 |
+ ); |
|
1273 |
+ |
|
1274 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
1275 |
+ $context['current_attachments'][] = array( |
|
1276 |
+ 'id' => $row['id_attach'], |
|
1277 |
+ 'name' => preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'])), |
|
1278 |
+ ); |
|
1279 |
+ |
|
1280 |
+ $smcFunc['db_free_result']($query); |
|
1281 |
+} |
|
1282 |
+ |
|
1283 |
+function shd_check_attachments() |
|
1284 |
+{ |
|
1285 |
+ global $modSettings, $smcFunc, $context, $user_info, $txt; |
|
1286 |
+ |
|
1287 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
1288 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; // just in case we never actually go to the admin page!! |
|
1289 |
+ |
|
1290 |
+ if (empty($context['current_attachments'])) |
|
1291 |
+ $context['current_attachments'] = array(); |
|
1292 |
+ |
|
1293 |
+ if (shd_allowed_to('shd_post_attachment')) |
|
1294 |
+ { |
|
1295 |
+ if (empty($_SESSION['temp_attachments'])) |
|
1296 |
+ $_SESSION['temp_attachments'] = array(); |
|
1297 |
+ |
|
1298 |
+ if (!empty($modSettings['currentAttachmentUploadDir'])) |
|
1299 |
+ { |
|
1300 |
+ if (!is_array($modSettings['attachmentUploadDir'])) |
|
1301 |
+ $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']); |
|
1302 |
+ |
|
1303 |
+ // Just use the current path for temp files. |
|
1304 |
+ $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; |
|
1305 |
+ } |
|
1306 |
+ else |
|
1307 |
+ $current_attach_dir = $modSettings['attachmentUploadDir']; |
|
1308 |
+ |
|
1309 |
+ // If this isn't a new post, check the current attachments. |
|
1310 |
+ if (($modSettings['shd_attachments_mode'] == 'ticket' && !empty($context['ticket_id'])) || isset($context['ticket_form']['msg'])) |
|
1311 |
+ { |
|
1312 |
+ $request = shd_db_query('', ' |
|
1313 |
+ SELECT COUNT(*), SUM(size) |
|
1314 |
+ FROM {db_prefix}attachments AS a |
|
1315 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
1316 |
+ WHERE ' . ($modSettings['shd_attachments_mode'] == 'ticket' ? 'hda.id_ticket = {int:ticket}' : 'hda.id_msg = {int:msg}') . ' |
|
1317 |
+ AND attachment_type = {int:attachment_type}', |
|
1318 |
+ array( |
|
1319 |
+ 'msg' => $context['ticket_form']['msg'], |
|
1320 |
+ 'ticket' => empty($context['ticket_id']) ? 0 : $context['ticket_id'], |
|
1321 |
+ 'attachment_type' => 0, |
|
1322 |
+ ) |
|
1323 |
+ ); |
|
1324 |
+ list ($quantity, $total_size) = $smcFunc['db_fetch_row']($request); |
|
1325 |
+ $smcFunc['db_free_result']($request); |
|
1326 |
+ } |
|
1327 |
+ else |
|
1328 |
+ { |
|
1329 |
+ $quantity = 0; |
|
1330 |
+ $total_size = 0; |
|
1331 |
+ } |
|
1332 |
+ |
|
1333 |
+ $temp_start = 0; |
|
1334 |
+ |
|
1335 |
+ if (!empty($_SESSION['temp_attachments'])) |
|
1336 |
+ foreach ($_SESSION['temp_attachments'] as $attachID => $name) |
|
1337 |
+ { |
|
1338 |
+ $temp_start++; |
|
1339 |
+ |
|
1340 |
+ if (preg_match('~^post_tmp_' . $user_info['id'] . '_\d+$~', $attachID) == 0) |
|
1341 |
+ { |
|
1342 |
+ unset($_SESSION['temp_attachments'][$attachID]); |
|
1343 |
+ continue; |
|
1344 |
+ } |
|
1345 |
+ |
|
1346 |
+ if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) |
|
1347 |
+ { |
|
1348 |
+ $deleted_attachments = true; |
|
1349 |
+ unset($_SESSION['temp_attachments'][$attachID]); |
|
1350 |
+ @unlink($current_attach_dir . '/' . $attachID); |
|
1351 |
+ continue; |
|
1352 |
+ } |
|
1353 |
+ |
|
1354 |
+ $quantity++; |
|
1355 |
+ $total_size += filesize($current_attach_dir . '/' . $attachID); |
|
1356 |
+ |
|
1357 |
+ $context['current_attachments'][] = array( |
|
1358 |
+ 'name' => $name, |
|
1359 |
+ 'id' => $attachID, |
|
1360 |
+ ); |
|
1361 |
+ } |
|
1362 |
+ |
|
1363 |
+ if (!empty($_POST['attach_del'])) |
|
1364 |
+ { |
|
1365 |
+ $del_temp = array(); |
|
1366 |
+ foreach ($_POST['attach_del'] as $i => $dummy) |
|
1367 |
+ $del_temp[$i] = (int) $dummy; |
|
1368 |
+ |
|
1369 |
+ foreach ($context['current_attachments'] as $k => $dummy) |
|
1370 |
+ if (!in_array($dummy['id'], $del_temp)) |
|
1371 |
+ { |
|
1372 |
+ $context['current_attachments'][$k]['unchecked'] = true; |
|
1373 |
+ $deleted_attachments = !isset($deleted_attachments) || is_bool($deleted_attachments) ? 1 : $deleted_attachments + 1; |
|
1374 |
+ $quantity--; |
|
1375 |
+ } |
|
1376 |
+ } |
|
1377 |
+ |
|
1378 |
+ if (!empty($_FILES)) |
|
1379 |
+ { |
|
1380 |
+ $_FILES = array_reverse($_FILES); |
|
1381 |
+ foreach ($_FILES as $uplfile) |
|
1382 |
+ { |
|
1383 |
+ if ($uplfile['name'] == '') |
|
1384 |
+ continue; |
|
1385 |
+ |
|
1386 |
+ if (!is_uploaded_file($uplfile['tmp_name']) || (@ini_get('open_basedir') == '' && !file_exists($uplfile['tmp_name']))) |
|
1387 |
+ { |
|
1388 |
+ checkSubmitOnce('free'); |
|
1389 |
+ fatal_lang_error('attach_timeout', 'critical'); |
|
1390 |
+ } |
|
1391 |
+ |
|
1392 |
+ if (!empty($modSettings['attachmentSizeLimit']) && $uplfile['size'] > $modSettings['attachmentSizeLimit'] * 1024) |
|
1393 |
+ { |
|
1394 |
+ checkSubmitOnce('free'); |
|
1395 |
+ fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit'])); |
|
1396 |
+ } |
|
1397 |
+ |
|
1398 |
+ $quantity++; |
|
1399 |
+ if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit'] && $modSettings['shd_attachments_mode'] != 'ticket') |
|
1400 |
+ { |
|
1401 |
+ checkSubmitOnce('free'); |
|
1402 |
+ fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit'])); |
|
1403 |
+ } |
|
1404 |
+ |
|
1405 |
+ $total_size += $uplfile['size']; |
|
1406 |
+ if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) |
|
1407 |
+ { |
|
1408 |
+ checkSubmitOnce('free'); |
|
1409 |
+ fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit'])); |
|
1410 |
+ } |
|
1411 |
+ |
|
1412 |
+ if (!empty($modSettings['attachmentCheckExtensions'])) |
|
1413 |
+ { |
|
1414 |
+ if (!in_array(strtolower(substr(strrchr($uplfile['name'], '.'), 1)), explode(',', strtolower($modSettings['attachmentExtensions'])))) |
|
1415 |
+ { |
|
1416 |
+ checkSubmitOnce('free'); |
|
1417 |
+ fatal_error($uplfile['name'] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false); |
|
1418 |
+ } |
|
1419 |
+ } |
|
1420 |
+ |
|
1421 |
+ if (!empty($modSettings['attachmentDirSizeLimit'])) |
|
1422 |
+ { |
|
1423 |
+ // Make sure the directory isn't full. |
|
1424 |
+ $dirSize = 0; |
|
1425 |
+ $dir = @opendir($current_attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical'); |
|
1426 |
+ while ($file = readdir($dir)) |
|
1427 |
+ { |
|
1428 |
+ if ($file == '.' || $file == '..') |
|
1429 |
+ continue; |
|
1430 |
+ |
|
1431 |
+ if (preg_match('~^post_tmp_\d+_\d+$~', $file) != 0) |
|
1432 |
+ { |
|
1433 |
+ // Temp file is more than 5 hours old! |
|
1434 |
+ if (filemtime($current_attach_dir . '/' . $file) < time() - 18000) |
|
1435 |
+ @unlink($current_attach_dir . '/' . $file); |
|
1436 |
+ continue; |
|
1437 |
+ } |
|
1438 |
+ |
|
1439 |
+ $dirSize += filesize($current_attach_dir . '/' . $file); |
|
1440 |
+ } |
|
1441 |
+ closedir($dir); |
|
1442 |
+ |
|
1443 |
+ // Too big! Maybe you could zip it or something... |
|
1444 |
+ if ($uplfile['size'] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) |
|
1445 |
+ fatal_lang_error('ran_out_of_space'); |
|
1446 |
+ } |
|
1447 |
+ |
|
1448 |
+ if (!is_writable($current_attach_dir)) |
|
1449 |
+ fatal_lang_error('attachments_no_write', 'critical'); |
|
1450 |
+ |
|
1451 |
+ $attachID = 'post_tmp_' . $user_info['id'] . '_' . $temp_start++; |
|
1452 |
+ $_SESSION['temp_attachments'][$attachID] = basename($uplfile['name']); |
|
1453 |
+ $context['current_attachments'][] = array( |
|
1454 |
+ 'name' => basename($uplfile['name']), |
|
1455 |
+ 'id' => $attachID, |
|
1456 |
+ 'approved' => 1, |
|
1457 |
+ ); |
|
1458 |
+ |
|
1459 |
+ $destName = $current_attach_dir . '/' . $attachID; |
|
1460 |
+ |
|
1461 |
+ if (!move_uploaded_file($uplfile['tmp_name'], $destName)) |
|
1462 |
+ fatal_lang_error('attach_timeout', 'critical'); |
|
1463 |
+ @chmod($destName, 0644); |
|
1464 |
+ } |
|
1465 |
+ } |
|
1466 |
+ } |
|
1467 |
+ |
|
1468 |
+ // So, while we're here, how many attachments can we have? |
|
1469 |
+ $context['ticket_form']['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) || $modSettings['shd_attachments_mode'] == 'ticket' ? -1 : $modSettings['attachmentNumPerPostLimit']; |
|
1470 |
+} |
|
1471 |
+ |
|
1472 |
+function shd_handle_attachments() |
|
1473 |
+{ |
|
1474 |
+ global $modSettings, $smcFunc, $context, $user_info, $sourcedir, $txt; |
|
1475 |
+ |
|
1476 |
+ if (!shd_allowed_to('shd_post_attachment')) |
|
1477 |
+ return; |
|
1478 |
+ |
|
1479 |
+ if (empty($modSettings['shd_attachments_mode'])) |
|
1480 |
+ $modSettings['shd_attachments_mode'] = 'ticket'; // just in case we never actually go to the admin page!! |
|
1481 |
+ |
|
1482 |
+ $attachIDs = array(); |
|
1483 |
+ |
|
1484 |
+ // Check if they are trying to delete any current attachments.... |
|
1485 |
+ if (isset($_POST['attach_del'])) |
|
1486 |
+ { |
|
1487 |
+ $del_temp = array(); |
|
1488 |
+ foreach ($_POST['attach_del'] as $i => $dummy) |
|
1489 |
+ $del_temp[$i] = (int) $dummy; |
|
1490 |
+ |
|
1491 |
+ // First, get them from the other table |
|
1492 |
+ $query = shd_db_query('', ' |
|
1493 |
+ SELECT a.id_attach |
|
1494 |
+ FROM {db_prefix}attachments AS a |
|
1495 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (hda.id_attach = a.id_attach) |
|
1496 |
+ WHERE ' . ($modSettings['shd_attachments_mode'] == 'ticket' ? 'hda.id_ticket = {int:ticket}' : 'hda.id_msg = {int:msg}'), |
|
1497 |
+ array( |
|
1498 |
+ 'msg' => $context['ticket_form']['msg'], |
|
1499 |
+ 'ticket' => $context['ticket_id'], |
|
1500 |
+ ) |
|
1501 |
+ ); |
|
1502 |
+ |
|
1503 |
+ $attachments = array(); |
|
1504 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
1505 |
+ $attachments[] = $row['id_attach']; |
|
1506 |
+ |
|
1507 |
+ $smcFunc['db_free_result']($query); |
|
1508 |
+ |
|
1509 |
+ // OK, so attachments = full list of attachments on this post, del_temp is list of ones to keep, so look for the ones that aren't in both lists |
|
1510 |
+ $del_temp = array_diff($attachments, $del_temp); |
|
1511 |
+ |
|
1512 |
+ if (!empty($del_temp)) |
|
1513 |
+ { |
|
1514 |
+ require_once($sourcedir . '/ManageAttachments.php'); |
|
1515 |
+ $attachmentQuery = array( |
|
1516 |
+ 'attachment_type' => 0, |
|
1517 |
+ 'id_msg' => 0, |
|
1518 |
+ 'id_attach' => $del_temp, |
|
1519 |
+ ); |
|
1520 |
+ removeAttachments($attachmentQuery); |
|
1521 |
+ } |
|
1522 |
+ } |
|
1523 |
+ |
|
1524 |
+ // ...or attach a new file... |
|
1525 |
+ if (!empty($_FILES) || !empty($_SESSION['temp_attachments'])) |
|
1526 |
+ { |
|
1527 |
+ if (!empty($FILES)) |
|
1528 |
+ $_FILES = array_reverse($_FILES); |
|
1529 |
+ |
|
1530 |
+ shd_is_allowed_to('shd_post_attachment'); |
|
1531 |
+ |
|
1532 |
+ // Make sure we're uploading to the right place. |
|
1533 |
+ if (!empty($modSettings['currentAttachmentUploadDir'])) |
|
1534 |
+ { |
|
1535 |
+ if (!is_array($modSettings['attachmentUploadDir'])) |
|
1536 |
+ $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']); |
|
1537 |
+ |
|
1538 |
+ // The current directory, of course! |
|
1539 |
+ $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; |
|
1540 |
+ } |
|
1541 |
+ else |
|
1542 |
+ $current_attach_dir = $modSettings['attachmentUploadDir']; |
|
1543 |
+ |
|
1544 |
+ // If this isn't a new post, check the current attachments. |
|
1545 |
+ if (isset($_REQUEST['msg']) || !empty($context['ticket_id'])) |
|
1546 |
+ { |
|
1547 |
+ $request = shd_db_query('', ' |
|
1548 |
+ SELECT COUNT(*), SUM(size) |
|
1549 |
+ FROM {db_prefix}attachments AS a |
|
1550 |
+ INNER JOIN {db_prefix}helpdesk_attachments AS hda ON (a.id_attach = hda.id_attach) |
|
1551 |
+ WHERE ' . ($modSettings['shd_attachments_mode'] == 'ticket' ? 'hda.id_ticket = {int:ticket}' : 'hda.id_msg = {int:msg}') . ' |
|
1552 |
+ AND attachment_type = {int:attachment_type}', |
|
1553 |
+ array( |
|
1554 |
+ 'msg' => $context['ticket_form']['msg'], |
|
1555 |
+ 'ticket' => $context['ticket_id'], |
|
1556 |
+ 'attachment_type' => 0, |
|
1557 |
+ ) |
|
1558 |
+ ); |
|
1559 |
+ list ($quantity, $total_size) = $smcFunc['db_fetch_row']($request); |
|
1560 |
+ $smcFunc['db_free_result']($request); |
|
1561 |
+ } |
|
1562 |
+ else |
|
1563 |
+ { |
|
1564 |
+ $quantity = 0; |
|
1565 |
+ $total_size = 0; |
|
1566 |
+ } |
|
1567 |
+ |
|
1568 |
+ if (!empty($_SESSION['temp_attachments'])) |
|
1569 |
+ foreach ($_SESSION['temp_attachments'] as $attachID => $name) |
|
1570 |
+ { |
|
1571 |
+ if (preg_match('~^post_tmp_' . $user_info['id'] . '_\d+$~', $attachID) == 0) |
|
1572 |
+ continue; |
|
1573 |
+ |
|
1574 |
+ if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) |
|
1575 |
+ { |
|
1576 |
+ unset($_SESSION['temp_attachments'][$attachID]); |
|
1577 |
+ @unlink($current_attach_dir . '/' . $attachID); |
|
1578 |
+ continue; |
|
1579 |
+ } |
|
1580 |
+ |
|
1581 |
+ $_FILES['attachment' . $attachID]['tmp_name'] = $attachID; |
|
1582 |
+ $_FILES['attachment' . $attachID]['name'] = $name; |
|
1583 |
+ $_FILES['attachment' . $attachID]['size'] = filesize($current_attach_dir . '/' . $attachID); |
|
1584 |
+ list ($_FILES['attachment' . $attachID]['width'], $_FILES['attachment' . $attachID]['height']) = @getimagesize($current_attach_dir . '/' . $attachID); |
|
1585 |
+ |
|
1586 |
+ unset($_SESSION['temp_attachments'][$attachID]); |
|
1587 |
+ } |
|
1588 |
+ |
|
1589 |
+ foreach ($_FILES as $uplfile) |
|
1590 |
+ { |
|
1591 |
+ if ($uplfile['name'] == '') |
|
1592 |
+ continue; |
|
1593 |
+ |
|
1594 |
+ // Have we reached the maximum number of files we are allowed? |
|
1595 |
+ $quantity++; |
|
1596 |
+ |
|
1597 |
+ $file_limit = (!empty($modSettings['attachmentNumPerPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') ? $modSettings['attachmentNumPerPostLimit'] : $quantity + 1; |
|
1598 |
+ |
|
1599 |
+ if ($quantity > $file_limit) |
|
1600 |
+ { |
|
1601 |
+ checkSubmitOnce('free'); |
|
1602 |
+ fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit'])); |
|
1603 |
+ } |
|
1604 |
+ |
|
1605 |
+ // Check the total upload size for this post... |
|
1606 |
+ $total_size += $uplfile['size']; |
|
1607 |
+ $size_limit = (!empty($modSettings['attachmentPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') ? $modSettings['attachmentPostLimit'] * 1024 : $total_size + 1024; |
|
1608 |
+ |
|
1609 |
+ if ($total_size > $size_limit) |
|
1610 |
+ { |
|
1611 |
+ checkSubmitOnce('free'); |
|
1612 |
+ fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit'])); |
|
1613 |
+ } |
|
1614 |
+ |
|
1615 |
+ $attachmentOptions = array( |
|
1616 |
+ 'post' => 0, |
|
1617 |
+ 'poster' => $user_info['id'], |
|
1618 |
+ 'name' => $uplfile['name'], |
|
1619 |
+ 'tmp_name' => $uplfile['tmp_name'], |
|
1620 |
+ 'size' => $uplfile['size'], |
|
1621 |
+ ); |
|
1622 |
+ |
|
1623 |
+ if (createAttachment($attachmentOptions)) |
|
1624 |
+ { |
|
1625 |
+ $attachIDs[] = $attachmentOptions['id']; |
|
1626 |
+ if (!empty($attachmentOptions['thumb'])) |
|
1627 |
+ $attachIDs[] = $attachmentOptions['thumb']; |
|
1628 |
+ } |
|
1629 |
+ else |
|
1630 |
+ { |
|
1631 |
+ if (in_array('could_not_upload', $attachmentOptions['errors'])) |
|
1632 |
+ { |
|
1633 |
+ checkSubmitOnce('free'); |
|
1634 |
+ fatal_lang_error('attach_timeout', 'critical'); |
|
1635 |
+ } |
|
1636 |
+ if (in_array('too_large', $attachmentOptions['errors'])) |
|
1637 |
+ { |
|
1638 |
+ checkSubmitOnce('free'); |
|
1639 |
+ fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit'])); |
|
1640 |
+ } |
|
1641 |
+ if (in_array('bad_extension', $attachmentOptions['errors'])) |
|
1642 |
+ { |
|
1643 |
+ checkSubmitOnce('free'); |
|
1644 |
+ fatal_error($attachmentOptions['name'] . '.<br />' . $txt['cant_upload_type'] . ' ' . strtr($modSettings['attachmentExtensions'], array(',' => ', ')) . '.', false); |
|
1645 |
+ } |
|
1646 |
+ if (in_array('directory_full', $attachmentOptions['errors'])) |
|
1647 |
+ { |
|
1648 |
+ checkSubmitOnce('free'); |
|
1649 |
+ fatal_lang_error('ran_out_of_space', 'critical'); |
|
1650 |
+ } |
|
1651 |
+ if (in_array('bad_filename', $attachmentOptions['errors'])) |
|
1652 |
+ { |
|
1653 |
+ checkSubmitOnce('free'); |
|
1654 |
+ fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['restricted_filename'] . '.', 'critical'); |
|
1655 |
+ } |
|
1656 |
+ if (in_array('taken_filename', $attachmentOptions['errors'])) |
|
1657 |
+ { |
|
1658 |
+ checkSubmitOnce('free'); |
|
1659 |
+ fatal_lang_error('filename_exists'); |
|
1660 |
+ } |
|
1661 |
+ } |
|
1662 |
+ } |
|
1663 |
+ } |
|
1664 |
+ |
|
1665 |
+ return $attachIDs; |
|
1666 |
+} |
|
1667 |
+ |
|
1668 |
+?> |
|
0 | 1669 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,872 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk-TopicTicketMove.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles displaying the user options for, and subsequently enacting, tickets being moved |
|
22 |
+ * to/from the helpdesk, from/to forum threads. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @since 1.0 |
|
26 |
+*/ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Load the form up for asking users what board they want to go to. |
|
33 |
+ * |
|
34 |
+ * Validates the user permission and session, then displays a list of boards the user can create new topics in. |
|
35 |
+ * |
|
36 |
+ * Accessed through action=helpdesk;sa=tickettotopic;ticket=x;sessvar=sessid |
|
37 |
+ * |
|
38 |
+ * @see shd_tickettotopic2() |
|
39 |
+ * @since 1.0 |
|
40 |
+*/ |
|
41 |
+function shd_tickettotopic() |
|
42 |
+{ |
|
43 |
+ global $smcFunc, $context, $user_info, $sourcedir, $txt, $modSettings, $scripturl; |
|
44 |
+ |
|
45 |
+ checkSession('get'); |
|
46 |
+ |
|
47 |
+ if (!shd_allowed_to('shd_ticket_to_topic') || !empty($modSettings['shd_helpdesk_only'])) |
|
48 |
+ fatal_lang_error('shd_cannot_move_ticket', false); |
|
49 |
+ |
|
50 |
+ if (empty($context['ticket_id'])) |
|
51 |
+ fatal_lang_error('shd_no_ticket'); |
|
52 |
+ |
|
53 |
+ // Get ticket details - and kick it out if they shouldn't be able to see it. |
|
54 |
+ $query = shd_db_query('', ' |
|
55 |
+ SELECT id_member_started, id_member_assigned, private, subject, deleted_replies |
|
56 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
57 |
+ WHERE {query_see_ticket} AND id_ticket = {int:ticket}', |
|
58 |
+ array( |
|
59 |
+ 'ticket' => $context['ticket_id'], |
|
60 |
+ ) |
|
61 |
+ ); |
|
62 |
+ |
|
63 |
+ if ($row = $smcFunc['db_fetch_row']($query)) |
|
64 |
+ { |
|
65 |
+ list($ticket_starter, $ticket_owner, $private, $subject, $deleted_replies) = $row; |
|
66 |
+ $smcFunc['db_free_result']($query); |
|
67 |
+ } |
|
68 |
+ else |
|
69 |
+ { |
|
70 |
+ $smcFunc['db_free_result']($query); |
|
71 |
+ fatal_lang_error('shd_no_ticket'); |
|
72 |
+ } |
|
73 |
+ |
|
74 |
+ // Hang on... are there any deleted replies? |
|
75 |
+ if ($deleted_replies > 0) |
|
76 |
+ { |
|
77 |
+ if (shd_allowed_to('shd_access_recyclebin')) |
|
78 |
+ $context['deleted_prompt'] = true; |
|
79 |
+ else |
|
80 |
+ fatal_lang_error('shd_cannot_move_ticket_with_deleted'); |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ // Build the linktree |
|
84 |
+ $context['linktree'][] = array( |
|
85 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
86 |
+ 'name' => $txt['shd_linktree_move_ticket'], |
|
87 |
+ ); |
|
88 |
+ $context['linktree'][] = array( |
|
89 |
+ 'url' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'], |
|
90 |
+ 'name' => $subject, |
|
91 |
+ ); |
|
92 |
+ |
|
93 |
+ // They should only be able to move it to boards they are allowed to post in. |
|
94 |
+ $allowedboards = boardsAllowedTo('post_new'); |
|
95 |
+ if ($allowedboards[0] == 0) |
|
96 |
+ $allowedboards = ''; // They can access everything. |
|
97 |
+ |
|
98 |
+ // All good, now figure out what board(s) they can move it to. (MoveTopic.php style 0-:D) |
|
99 |
+ $request = shd_db_query('order_by_board_order', ' |
|
100 |
+ SELECT b.id_board, b.name, b.child_level, c.name AS cat_name, c.id_cat |
|
101 |
+ FROM {db_prefix}boards AS b |
|
102 |
+ LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) |
|
103 |
+ WHERE {query_see_board} |
|
104 |
+ AND b.redirect = {string:blank_redirect} |
|
105 |
+ ' . (!empty($allowedboards) ? 'AND id_board IN({array_int:allowed_boards})' : ''), |
|
106 |
+ array( |
|
107 |
+ 'blank_redirect' => '', |
|
108 |
+ 'allowed_boards' => $allowedboards, |
|
109 |
+ ) |
|
110 |
+ ); |
|
111 |
+ $context['boards'] = array(); |
|
112 |
+ |
|
113 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
114 |
+ { |
|
115 |
+ if (!isset($context['categories'][$row['id_cat']])) |
|
116 |
+ $context['categories'][$row['id_cat']] = array ( |
|
117 |
+ 'name' => strip_tags($row['cat_name']), |
|
118 |
+ 'boards' => array(), |
|
119 |
+ ); |
|
120 |
+ |
|
121 |
+ $context['categories'][$row['id_cat']]['boards'][] = array( |
|
122 |
+ 'id' => $row['id_board'], |
|
123 |
+ 'name' => strip_tags($row['name']), |
|
124 |
+ 'category' => strip_tags($row['cat_name']), |
|
125 |
+ 'child_level' => $row['child_level'], |
|
126 |
+ 'selected' => !empty($_SESSION['move_to_topic']) && $_SESSION['move_to_topic'] == $row['id_board'] && $row['id_board'] != $board, |
|
127 |
+ ); |
|
128 |
+ } |
|
129 |
+ |
|
130 |
+ $smcFunc['db_free_result']($request); |
|
131 |
+ |
|
132 |
+ if (empty($context['categories'])) |
|
133 |
+ fatal_lang_error('shd_moveticket_noboards', false); |
|
134 |
+ |
|
135 |
+ loadTemplate('SimpleDesk-TicketTopicMove'); |
|
136 |
+ $context['sub_template'] = 'shd_tickettotopic'; |
|
137 |
+ $context['page_title'] = $txt['shd_move_ticket_to_topic']; |
|
138 |
+ checkSubmitOnce('register'); |
|
139 |
+} |
|
140 |
+ |
|
141 |
+/** |
|
142 |
+ * Receives the form for moving tickets to topics, and actually handles the move. |
|
143 |
+ * |
|
144 |
+ * After checking permissions, and so on, begin to actually move posts. |
|
145 |
+ * |
|
146 |
+ * This is done by invoking SMF's createPost function to make the new thread and repost all the ticket's posts as new thread posts |
|
147 |
+ * using defaults for some settings. |
|
148 |
+ * |
|
149 |
+ * Operations: |
|
150 |
+ * - check the user can see the board they are linking to |
|
151 |
+ * - move the ticket's text as the opening post |
|
152 |
+ * - update the ticket row if the post was modified before |
|
153 |
+ * - get the rest of the replies |
|
154 |
+ * - step through and post, updating for modified details |
|
155 |
+ * - send the notification PM if we're doing that |
|
156 |
+ * - update the attachments table |
|
157 |
+ * - update the action log |
|
158 |
+ * - remove the ticket from the DB |
|
159 |
+ * |
|
160 |
+ * @see shd_tickettotopic() |
|
161 |
+ * @since 1.0 |
|
162 |
+*/ |
|
163 |
+function shd_tickettotopic2() |
|
164 |
+{ |
|
165 |
+ global $smcFunc, $context, $txt, $modSettings, $scripturl, $sourcedir; |
|
166 |
+ |
|
167 |
+ checkSession(); |
|
168 |
+ checkSubmitOnce('check'); |
|
169 |
+ |
|
170 |
+ if (!shd_allowed_to('shd_ticket_to_topic') || !empty($modSettings['shd_helpdesk_only'])) |
|
171 |
+ fatal_lang_error('shd_cannot_move_ticket', false); |
|
172 |
+ |
|
173 |
+ if (empty($context['ticket_id'])) |
|
174 |
+ fatal_lang_error('shd_no_ticket'); |
|
175 |
+ |
|
176 |
+ if (isset($_POST['send_pm']) && (!isset($_POST['pm_content']) || trim($_POST['pm_content']) == '')) |
|
177 |
+ fatal_lang_error('shd_move_no_pm', false); |
|
178 |
+ |
|
179 |
+ // Just in case, are they cancelling? |
|
180 |
+ if (isset($_REQUEST['cancel'])) |
|
181 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']); |
|
182 |
+ |
|
183 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
184 |
+ |
|
185 |
+ // The destination board must be numeric. |
|
186 |
+ $_POST['toboard'] = (int) $_POST['toboard']; |
|
187 |
+ |
|
188 |
+ $msg_assoc = array(); |
|
189 |
+ |
|
190 |
+ // This is complex, very complex. Hopefully 5 minutes will be enough... |
|
191 |
+ @set_time_limit(300); |
|
192 |
+ |
|
193 |
+ // Make sure they can see the board they are trying to move to (and get whether posts count in the target board). |
|
194 |
+ $request = shd_db_query('', ' |
|
195 |
+ SELECT b.count_posts, b.name, hdt.subject, hdt.id_member_started, hdtr.body, hdt.id_first_msg, hdtr.smileys_enabled, |
|
196 |
+ hdtr.modified_time, hdtr.modified_name, hdtr.poster_time, hdtr.id_msg, hdt.deleted_replies |
|
197 |
+ FROM {db_prefix}boards AS b |
|
198 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdt.id_ticket = {int:ticket}) |
|
199 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdtr.id_msg = hdt.id_first_msg) |
|
200 |
+ WHERE {query_see_board} |
|
201 |
+ AND {query_see_ticket} |
|
202 |
+ AND b.id_board = {int:to_board} |
|
203 |
+ AND b.redirect = {string:blank_redirect} |
|
204 |
+ LIMIT 1', |
|
205 |
+ array( |
|
206 |
+ 'ticket' => $context['ticket_id'], |
|
207 |
+ 'to_board' => $_POST['toboard'], |
|
208 |
+ 'blank_redirect' => '', |
|
209 |
+ ) |
|
210 |
+ ); |
|
211 |
+ if ($smcFunc['db_num_rows']($request) == 0) |
|
212 |
+ fatal_lang_error('no_board'); |
|
213 |
+ else |
|
214 |
+ list ($pcounter, $board_name, $subject, $owner, $body, $firstmsg, $smileys_enabled, $modified_time, $modified_name, $time, $shd_id_msg, $deleted_replies) = $smcFunc['db_fetch_row']($request); |
|
215 |
+ |
|
216 |
+ $smcFunc['db_free_result']($request); |
|
217 |
+ |
|
218 |
+ $context['deleted_prompt'] = false; |
|
219 |
+ // Hang on... are there any deleted replies? |
|
220 |
+ if ($deleted_replies > 0) |
|
221 |
+ { |
|
222 |
+ if (shd_allowed_to('shd_access_recyclebin')) |
|
223 |
+ { |
|
224 |
+ $dr_opts = array('abort', 'delete', 'undelete'); |
|
225 |
+ |
|
226 |
+ $context['deleted_prompt'] = isset($_REQUEST['deleted_replies']) && in_array($_REQUEST['deleted_replies'], $dr_opts) ? $_REQUEST['deleted_replies'] : 'abort'; |
|
227 |
+ } |
|
228 |
+ else |
|
229 |
+ fatal_lang_error('shd_cannot_move_ticket_with_deleted'); |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ if (!empty($context['deleted_prompt']) && $context['deleted_prompt'] == 'abort') |
|
233 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . ';recycle'); |
|
234 |
+ |
|
235 |
+ // All okay, it seems. Let's go create the topic. |
|
236 |
+ $msgOptions = array( |
|
237 |
+ 'subject' => '[' . $txt['shd_ticket'] . '] ' . $subject, |
|
238 |
+ 'body' => $body, |
|
239 |
+ 'icon' => 'xx', |
|
240 |
+ 'smileys_enabled' => !empty($smileys_enabled) ? 1 : 0, |
|
241 |
+ ); |
|
242 |
+ $topicOptions = array( |
|
243 |
+ 'board' => $_POST['toboard'], |
|
244 |
+ 'lock_mode' => 0, |
|
245 |
+ 'mark_as_read' => false, |
|
246 |
+ ); |
|
247 |
+ $posterOptions = array( |
|
248 |
+ 'id' => $owner, |
|
249 |
+ 'update_post_count' => empty($pcounter), |
|
250 |
+ ); |
|
251 |
+ createPost($msgOptions, $topicOptions, $posterOptions); |
|
252 |
+ |
|
253 |
+ // Keep track of SHD msg id to SMF msg id |
|
254 |
+ $msg_assoc[$shd_id_msg] = $msgOptions['id']; |
|
255 |
+ |
|
256 |
+ // createPost() doesn't handle modified time and name, so we'll fix that here, along with the poster time. |
|
257 |
+ if (!empty($modified_time)) |
|
258 |
+ { |
|
259 |
+ shd_db_query('', ' |
|
260 |
+ UPDATE {db_prefix}messages |
|
261 |
+ SET |
|
262 |
+ modified_time = {int:modified_time}, |
|
263 |
+ modified_name = {string:modified_name}, |
|
264 |
+ poster_time = {int:poster_time} |
|
265 |
+ WHERE id_msg = {int:id_msg}', |
|
266 |
+ array( |
|
267 |
+ 'id_msg' => $firstmsg, |
|
268 |
+ 'modified_time' => $modified_time, |
|
269 |
+ 'modified_name' => $modified_name, |
|
270 |
+ 'poster_time' => $time, |
|
271 |
+ ) |
|
272 |
+ ); |
|
273 |
+ } |
|
274 |
+ |
|
275 |
+ // Topic created, let's dig out the replies and post them in the topic, if there are any. |
|
276 |
+ if (isset($topicOptions['id'])) |
|
277 |
+ { |
|
278 |
+ $request = shd_db_query('', ' |
|
279 |
+ SELECT body, id_member, poster_time, poster_name, poster_email, poster_ip, smileys_enabled, |
|
280 |
+ modified_time, modified_member, modified_name, poster_time, id_msg, message_status |
|
281 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
282 |
+ WHERE id_ticket = {int:ticket} |
|
283 |
+ AND id_msg > {int:ticket_msg}', |
|
284 |
+ array( |
|
285 |
+ 'ticket' => $context['ticket_id'], |
|
286 |
+ 'ticket_msg' => $firstmsg, |
|
287 |
+ ) |
|
288 |
+ ); |
|
289 |
+ |
|
290 |
+ // The ID of the topic we created |
|
291 |
+ $topic = $topicOptions['id']; |
|
292 |
+ |
|
293 |
+ if ($smcFunc['db_num_rows']($request) != 0) |
|
294 |
+ { |
|
295 |
+ // Now loop through each reply and post it. Hopefully there aren't too many. *looks at clock* |
|
296 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
297 |
+ { |
|
298 |
+ if ($row['message_status'] == MSG_STATUS_DELETED && !empty($context['deleted_prompt']) && $context['deleted_prompt'] == 'delete') // we don't want these replies! |
|
299 |
+ continue; |
|
300 |
+ |
|
301 |
+ $msgOptions = array( |
|
302 |
+ 'subject' => $txt['response_prefix'] . $subject, |
|
303 |
+ 'body' => $row['body'], |
|
304 |
+ 'icon' => 'xx', |
|
305 |
+ 'smileys_enabled' => !empty($row['smileys_enabled']) ? 1 : 0, |
|
306 |
+ ); |
|
307 |
+ $topicOptions = array( |
|
308 |
+ 'id' => $topic, |
|
309 |
+ 'board' => $_POST['toboard'], |
|
310 |
+ 'lock_mode' => 0, |
|
311 |
+ 'mark_as_read' => false, |
|
312 |
+ ); |
|
313 |
+ $posterOptions = array( |
|
314 |
+ 'id' => $row['id_member'], |
|
315 |
+ 'name' => !empty($row['poster_name']) ? $row['poster_name'] : '', |
|
316 |
+ 'email' => !empty($row['poster_email']) ? $row['poster_email'] : '', |
|
317 |
+ 'ip' => !empty($row['poster_ip']) ? $row['poster_ip'] : '', |
|
318 |
+ 'update_post_count' => empty($pcounter), |
|
319 |
+ ); |
|
320 |
+ createPost($msgOptions, $topicOptions, $posterOptions); |
|
321 |
+ |
|
322 |
+ // Don't forget to note what id |
|
323 |
+ $msg_assoc[$row['id_msg']] = $msgOptions['id']; |
|
324 |
+ |
|
325 |
+ // Meh, createPost() doesn't have any hooks for modified time and user. Let's fix that now. |
|
326 |
+ if (!empty($row['modified_time'])) |
|
327 |
+ { |
|
328 |
+ shd_db_query('', ' |
|
329 |
+ UPDATE {db_prefix}messages |
|
330 |
+ SET |
|
331 |
+ modified_time = {int:modified_time}, |
|
332 |
+ modified_name = {string:modified_name}, |
|
333 |
+ poster_time = {int:poster_time} |
|
334 |
+ WHERE id_msg = {int:id_msg}', |
|
335 |
+ array( |
|
336 |
+ 'id_msg' => $msgOptions['id'], |
|
337 |
+ 'modified_time' => $row['modified_time'], |
|
338 |
+ 'modified_name' => $row['modified_name'], |
|
339 |
+ 'poster_time' => $row['poster_time'], |
|
340 |
+ ) |
|
341 |
+ ); |
|
342 |
+ } |
|
343 |
+ } |
|
344 |
+ } |
|
345 |
+ |
|
346 |
+ // Topic: check; Replies: check; Notfiy the ticket starter, if desired. |
|
347 |
+ if (isset($_POST['send_pm'])) |
|
348 |
+ { |
|
349 |
+ $request = shd_db_query('pm_find_username', ' |
|
350 |
+ SELECT id_member, real_name |
|
351 |
+ FROM {db_prefix}members |
|
352 |
+ WHERE id_member = {int:user} |
|
353 |
+ LIMIT 1', |
|
354 |
+ array( |
|
355 |
+ 'user' => $owner, |
|
356 |
+ ) |
|
357 |
+ ); |
|
358 |
+ list ($userid,$username) = $smcFunc['db_fetch_row']($request); |
|
359 |
+ $smcFunc['db_free_result']($request); |
|
360 |
+ |
|
361 |
+ // Fix the content |
|
362 |
+ $replacements = array( |
|
363 |
+ '{user}' => $username, |
|
364 |
+ '{subject}' => $subject, |
|
365 |
+ '{board}' => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]', |
|
366 |
+ '{link}' => $scripturl . '?topic=' . $topic . '.0', |
|
367 |
+ ); |
|
368 |
+ $message = str_replace(array_keys($replacements), array_values($replacements),$_POST['pm_content']); |
|
369 |
+ |
|
370 |
+ $recipients = array( |
|
371 |
+ 'to' => array($owner), |
|
372 |
+ 'bcc' => array() |
|
373 |
+ ); |
|
374 |
+ |
|
375 |
+ sendpm($recipients,$txt['shd_ticket_moved_subject'],$message); |
|
376 |
+ } |
|
377 |
+ |
|
378 |
+ // Right, time to do all the attachment fussing too |
|
379 |
+ if (!empty($msg_assoc)) |
|
380 |
+ { |
|
381 |
+ $attachIDs = array(); |
|
382 |
+ $query = shd_db_query('', ' |
|
383 |
+ SELECT id_attach, id_msg |
|
384 |
+ FROM {db_prefix}helpdesk_attachments |
|
385 |
+ WHERE id_msg IN ({array_int:msgs})', |
|
386 |
+ array( |
|
387 |
+ 'msgs' => array_keys($msg_assoc), |
|
388 |
+ ) |
|
389 |
+ ); |
|
390 |
+ |
|
391 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
392 |
+ $attachIDs[] = $row; |
|
393 |
+ |
|
394 |
+ $smcFunc['db_free_result']($query); |
|
395 |
+ |
|
396 |
+ if (!empty($attachIDs)) |
|
397 |
+ { |
|
398 |
+ // 1. Update all the attachments in the master table; this is the bit that hurts since it can't be done without |
|
399 |
+ // a query per row :( |
|
400 |
+ foreach ($attachIDs as $attach) |
|
401 |
+ { |
|
402 |
+ shd_db_query('', ' |
|
403 |
+ UPDATE {db_prefix}attachments |
|
404 |
+ SET id_msg = {int:new_msg} |
|
405 |
+ WHERE id_attach = {int:attach}', |
|
406 |
+ array( |
|
407 |
+ 'attach' => $attach['id_attach'], |
|
408 |
+ 'new_msg' => $msg_assoc[$attach['id_msg']], |
|
409 |
+ ) |
|
410 |
+ ); |
|
411 |
+ } |
|
412 |
+ |
|
413 |
+ // 2. Remove the entries from the SD table since we don't need them no more |
|
414 |
+ shd_db_query('', ' |
|
415 |
+ DELETE FROM {db_prefix}helpdesk_attachments |
|
416 |
+ WHERE id_msg IN ({array_int:msgs})', |
|
417 |
+ array( |
|
418 |
+ 'msgs' => array_keys($msg_assoc), |
|
419 |
+ ) |
|
420 |
+ ); |
|
421 |
+ } |
|
422 |
+ } |
|
423 |
+ |
|
424 |
+ // Well, it's possible there are some phantom attachments on deleted replies that need to disappear |
|
425 |
+ if (!empty($context['deleted_replies']) && $context['deleted_replies'] == 'delete') |
|
426 |
+ { |
|
427 |
+ $query = shd_db_query('', ' |
|
428 |
+ SELECT id_msg |
|
429 |
+ FROM {db_prefix}helpdesk_attachments AS hda |
|
430 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hda.id_msg = hdtr.id_msg) |
|
431 |
+ WHERE id_ticket = {int:ticket} |
|
432 |
+ AND hdtr.message_status = {int:deleted}', |
|
433 |
+ array( |
|
434 |
+ 'ticket' => $context['ticket_id'], |
|
435 |
+ 'deleted' => MSG_STATUS_DELETED, |
|
436 |
+ ) |
|
437 |
+ ); |
|
438 |
+ |
|
439 |
+ if ($smcFunc['db_num_rows']($query) > 0) |
|
440 |
+ { |
|
441 |
+ $msgs = array(); |
|
442 |
+ while ($row = $smcFunc['db_fetch_row']($query)) |
|
443 |
+ $msgs[] = $row[0]; |
|
444 |
+ |
|
445 |
+ if (!empty($msgs)) |
|
446 |
+ { |
|
447 |
+ // Get rid of the parents |
|
448 |
+ require_once($sourcedir . '/ManageAttachments.php'); |
|
449 |
+ $attachmentQuery = array( |
|
450 |
+ 'attachment_type' => 0, |
|
451 |
+ 'id_msg' => 0, |
|
452 |
+ 'id_attach' => $msgs, |
|
453 |
+ ); |
|
454 |
+ removeAttachments($attachmentQuery); |
|
455 |
+ |
|
456 |
+ // Get rid of the remainder in hda table |
|
457 |
+ shd_db_query('', ' |
|
458 |
+ DELETE FROM {db_prefix}helpdesk_attachments |
|
459 |
+ WHERE id_ticket = {int:ticket}', |
|
460 |
+ array( |
|
461 |
+ 'ticket' => $context['ticket_id'], |
|
462 |
+ ) |
|
463 |
+ ); |
|
464 |
+ } |
|
465 |
+ } |
|
466 |
+ |
|
467 |
+ $smcFunc['db_free_result']($query); |
|
468 |
+ } |
|
469 |
+ |
|
470 |
+ // Now we'll add this to the log. |
|
471 |
+ $log_params = array( |
|
472 |
+ 'subject' => $subject, |
|
473 |
+ 'board_id' => $_POST['toboard'], |
|
474 |
+ 'board_name' => $board_name, |
|
475 |
+ 'ticket' => $topic, |
|
476 |
+ ); |
|
477 |
+ shd_log_action('tickettotopic', $log_params); |
|
478 |
+ |
|
479 |
+ // Lastly, delete the ticket from the database. |
|
480 |
+ shd_db_query('', ' |
|
481 |
+ DELETE FROM {db_prefix}helpdesk_tickets |
|
482 |
+ WHERE id_ticket = {int:ticket} |
|
483 |
+ LIMIT 1', |
|
484 |
+ array( |
|
485 |
+ 'ticket' => $context['ticket_id'], |
|
486 |
+ ) |
|
487 |
+ ); |
|
488 |
+ // And the replies, too. |
|
489 |
+ shd_db_query('', ' |
|
490 |
+ DELETE FROM {db_prefix}helpdesk_ticket_replies |
|
491 |
+ WHERE id_ticket = {int:ticket}', |
|
492 |
+ array( |
|
493 |
+ 'ticket' => $context['ticket_id'], |
|
494 |
+ ) |
|
495 |
+ ); |
|
496 |
+ |
|
497 |
+ } |
|
498 |
+ else |
|
499 |
+ fatal_lang_error('shd_move_topic_not_created',false); |
|
500 |
+ |
|
501 |
+ // Clear our cache |
|
502 |
+ shd_clear_active_tickets($owner); |
|
503 |
+ |
|
504 |
+ // Send them to the topic. |
|
505 |
+ redirectexit('topic=' . $topic . '.0'); |
|
506 |
+ |
|
507 |
+} |
|
508 |
+ |
|
509 |
+/** |
|
510 |
+ * Load the form up for asking users whether to send a personal message (and what message) to the topic/ticket starter or not. Most of the rest of this function is about loading the data to make the page well-rounded (like the subject for breadcrumbs) |
|
511 |
+ * |
|
512 |
+ * Validates the user permission and session, of course. |
|
513 |
+ * |
|
514 |
+ * Accessed through action=helpdesk;sa=topictoticket;topic=x;sessvar=sessid |
|
515 |
+ * |
|
516 |
+ * @see shd_topictoticket2() |
|
517 |
+ * @since 1.0 |
|
518 |
+*/ |
|
519 |
+function shd_topictoticket() |
|
520 |
+{ |
|
521 |
+ global $smcFunc, $context, $user_info, $sourcedir, $txt, $modSettings, $scripturl; |
|
522 |
+ |
|
523 |
+ checkSession('get'); |
|
524 |
+ |
|
525 |
+ if (!shd_allowed_to('shd_topic_to_ticket') || !empty($modSettings['shd_helpdesk_only'])) |
|
526 |
+ fatal_lang_error('shd_cannot_move_topic', false); |
|
527 |
+ |
|
528 |
+ if (empty($_REQUEST['topic'])) |
|
529 |
+ fatal_lang_error('shd_no_topic'); |
|
530 |
+ |
|
531 |
+ $context['topic_id'] = (int) $_REQUEST['topic']; |
|
532 |
+ |
|
533 |
+ // Get topic details |
|
534 |
+ $query = shd_db_query('', ' |
|
535 |
+ SELECT m.subject |
|
536 |
+ FROM {db_prefix}topics AS t |
|
537 |
+ INNER JOIN {db_prefix}messages AS m ON (m.id_topic = {int:topic}) |
|
538 |
+ INNER JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board) |
|
539 |
+ WHERE {query_see_board} AND t.id_topic = {int:topic}', |
|
540 |
+ array( |
|
541 |
+ 'topic' => $context['topic_id'], |
|
542 |
+ ) |
|
543 |
+ ); |
|
544 |
+ |
|
545 |
+ if ($row = $smcFunc['db_fetch_row']($query)) |
|
546 |
+ { |
|
547 |
+ list($subject) = $row; |
|
548 |
+ $smcFunc['db_free_result']($query); |
|
549 |
+ } |
|
550 |
+ else |
|
551 |
+ { |
|
552 |
+ $smcFunc['db_free_result']($query); |
|
553 |
+ fatal_lang_error('shd_no_topic'); |
|
554 |
+ } |
|
555 |
+ |
|
556 |
+ // Build the linktree |
|
557 |
+ $context['linktree'][] = array( |
|
558 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
559 |
+ 'name' => $txt['shd_linktree_move_topic'], |
|
560 |
+ ); |
|
561 |
+ $context['linktree'][] = array( |
|
562 |
+ 'url' => $scripturl . '?topic=' . $context['topic_id'] . '.0', |
|
563 |
+ 'name' => $subject, |
|
564 |
+ ); |
|
565 |
+ |
|
566 |
+ loadTemplate('SimpleDesk-TicketTopicMove'); |
|
567 |
+ $context['sub_template'] = 'shd_topictoticket'; |
|
568 |
+ $context['page_title'] = $txt['shd_move_topic_to_ticket']; |
|
569 |
+ checkSubmitOnce('register'); |
|
570 |
+} |
|
571 |
+ |
|
572 |
+/** |
|
573 |
+ * Handles moving a topic into the helpdesk. |
|
574 |
+ * |
|
575 |
+ * After checking permissions, and so on, begin to actually move posts. |
|
576 |
+ * |
|
577 |
+ * Broadly this is done using {@link shd_create_ticket_post()}, which has hooks specifically to deal with post modification times (written in specifically to ease this function's workload) |
|
578 |
+ * |
|
579 |
+ * Operations: |
|
580 |
+ * - get the topic information (and checking topic access permission in the process) |
|
581 |
+ * - identify the status of the topic (new/with staff/with user) |
|
582 |
+ * - create the new ticket from these details |
|
583 |
+ * - assuming there are replies, query for them |
|
584 |
+ * - step through and repost |
|
585 |
+ * - send the notification PM if we're doing that |
|
586 |
+ * - update the attachments table |
|
587 |
+ * - update the action log |
|
588 |
+ * - remove the topic from the forum |
|
589 |
+ * |
|
590 |
+ * @see shd_topictoticket() |
|
591 |
+ * @since 1.0 |
|
592 |
+*/ |
|
593 |
+function shd_topictoticket2() |
|
594 |
+{ |
|
595 |
+ global $smcFunc, $context, $txt, $modSettings, $scripturl, $sourcedir; |
|
596 |
+ |
|
597 |
+ checkSession(); |
|
598 |
+ checkSubmitOnce('check'); |
|
599 |
+ |
|
600 |
+ if (!shd_allowed_to('shd_topic_to_ticket') || !empty($modSettings['shd_helpdesk_only'])) |
|
601 |
+ fatal_lang_error('shd_cannot_move_topic', false); |
|
602 |
+ |
|
603 |
+ if (empty($_REQUEST['topic'])) |
|
604 |
+ fatal_lang_error('shd_no_topic'); |
|
605 |
+ |
|
606 |
+ $context['topic_id'] = (int) $_REQUEST['topic']; |
|
607 |
+ |
|
608 |
+ // Just in case, are they cancelling? |
|
609 |
+ if (isset($_REQUEST['cancel'])) |
|
610 |
+ redirectexit('topic=' . $context['topic_id']); |
|
611 |
+ |
|
612 |
+ if (isset($_POST['send_pm']) && (!isset($_POST['pm_content']) || trim($_POST['pm_content']) == '')) |
|
613 |
+ fatal_lang_error('shd_move_no_pm_topic', false); |
|
614 |
+ |
|
615 |
+ require_once($sourcedir . '/Subs-SimpleDeskPost.php'); |
|
616 |
+ |
|
617 |
+ // Fetch the topic information. |
|
618 |
+ $request = shd_db_query('', ' |
|
619 |
+ SELECT m.subject, t.id_board, t.id_member_started, m.body, t.id_first_msg, m.smileys_enabled, t.id_member_updated, t.num_replies, |
|
620 |
+ m.poster_email, m.poster_name, m.poster_ip, m.poster_time, m.modified_time, m.modified_name, m.id_msg |
|
621 |
+ FROM {db_prefix}topics AS t |
|
622 |
+ INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) |
|
623 |
+ INNER JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board) |
|
624 |
+ WHERE {query_see_board} AND t.id_topic = {int:topic} |
|
625 |
+ LIMIT 1', |
|
626 |
+ array( |
|
627 |
+ 'topic' => $context['topic_id'], |
|
628 |
+ ) |
|
629 |
+ ); |
|
630 |
+ if ($smcFunc['db_num_rows']($request) == 0) |
|
631 |
+ fatal_lang_error('shd_move_ticket_not_created'); |
|
632 |
+ else |
|
633 |
+ list ($subject, $board, $owner, $body, $firstmsg, $smileys_enabled, $memberupdated, $numreplies, $postername, $posteremail, $posterip, $postertime, $modified_time, $modified_name, $smf_id_msg) = $smcFunc['db_fetch_row']($request); |
|
634 |
+ |
|
635 |
+ $smcFunc['db_free_result']($request); |
|
636 |
+ |
|
637 |
+ // Figure out what the status of the ticket should be. |
|
638 |
+ $status = shd_determine_status('topictoticket', $owner, $memberupdated, $numreplies); |
|
639 |
+ |
|
640 |
+ // All okay, it seems. Let's go create the ticket. |
|
641 |
+ $msg_assoc = array(); |
|
642 |
+ |
|
643 |
+ $msgOptions = array( |
|
644 |
+ 'body' => $body, |
|
645 |
+ 'smileys_enabled' => !empty($smileys_enabled) ? 1 : 0, |
|
646 |
+ 'modified' => array( |
|
647 |
+ 'time' => $modified_time, |
|
648 |
+ 'name' => $modified_name, |
|
649 |
+ ), |
|
650 |
+ 'time' => $postertime, |
|
651 |
+ ); |
|
652 |
+ $ticketOptions = array( |
|
653 |
+ 'subject' => $subject, |
|
654 |
+ 'mark_as_read' => false, |
|
655 |
+ 'private' => false, |
|
656 |
+ 'status' => $status, |
|
657 |
+ 'urgency' => 0, |
|
658 |
+ 'assigned' => 0, |
|
659 |
+ ); |
|
660 |
+ $posterOptions = array( |
|
661 |
+ 'id' => $owner, |
|
662 |
+ 'name' => $postername, |
|
663 |
+ 'email' => $posteremail, |
|
664 |
+ 'ip' => $posterip, |
|
665 |
+ ); |
|
666 |
+ shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
667 |
+ $msg_assoc[$smf_id_msg] = $msgOptions['id']; |
|
668 |
+ |
|
669 |
+ // Ticket created, let's dig out the replies and post them in the ticket, if there are any. |
|
670 |
+ if (isset($ticketOptions['id'])) |
|
671 |
+ { |
|
672 |
+ $request = shd_db_query('', ' |
|
673 |
+ SELECT body, id_member, poster_time, poster_name, poster_email, poster_ip, smileys_enabled, id_msg |
|
674 |
+ FROM {db_prefix}messages |
|
675 |
+ WHERE id_topic = {int:topic} |
|
676 |
+ AND id_msg != {int:topic_msg}', |
|
677 |
+ array( |
|
678 |
+ 'topic' => $context['topic_id'], |
|
679 |
+ 'topic_msg' => $firstmsg, |
|
680 |
+ ) |
|
681 |
+ ); |
|
682 |
+ |
|
683 |
+ $num_replies = $smcFunc['db_num_rows']($request) + 1; // Plus one since we want to count the main ticket post as well. |
|
684 |
+ |
|
685 |
+ // The ID of the ticket we created |
|
686 |
+ $ticket = $ticketOptions['id']; |
|
687 |
+ |
|
688 |
+ if ($smcFunc['db_num_rows']($request) != 0) |
|
689 |
+ { |
|
690 |
+ // Now loop through each reply and post it. Hopefully there aren't too many. *looks at clock* |
|
691 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
692 |
+ { |
|
693 |
+ $msgOptions = array( |
|
694 |
+ 'body' => $row['body'], |
|
695 |
+ 'smileys_enabled' => !empty($row['smileys_enabled']) ? 1 : 0, |
|
696 |
+ ); |
|
697 |
+ $ticketOptions = array( |
|
698 |
+ 'id' => $ticket, |
|
699 |
+ 'mark_as_read' => false, |
|
700 |
+ ); |
|
701 |
+ $posterOptions = array( |
|
702 |
+ 'id' => $row['id_member'], |
|
703 |
+ 'name' => !empty($row['poster_name']) ? $row['poster_name'] : '', |
|
704 |
+ 'email' => !empty($row['poster_email']) ? $row['poster_email'] : '', |
|
705 |
+ 'ip' => !empty($row['poster_ip']) ? $row['poster_ip'] : '', |
|
706 |
+ ); |
|
707 |
+ shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions); |
|
708 |
+ $msg_assoc[$row['id_msg']] = $msgOptions['id']; |
|
709 |
+ } |
|
710 |
+ } |
|
711 |
+ |
|
712 |
+ // Ticket: check; Replies: check; Notfiy the topic starter, if desired. |
|
713 |
+ if (isset($_POST['send_pm'])) |
|
714 |
+ { |
|
715 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
716 |
+ |
|
717 |
+ $request = shd_db_query('pm_find_username', ' |
|
718 |
+ SELECT id_member, real_name |
|
719 |
+ FROM {db_prefix}members |
|
720 |
+ WHERE id_member = {int:user} |
|
721 |
+ LIMIT 1', |
|
722 |
+ array( |
|
723 |
+ 'user' => $owner, |
|
724 |
+ ) |
|
725 |
+ ); |
|
726 |
+ list ($userid,$username) = $smcFunc['db_fetch_row']($request); |
|
727 |
+ $smcFunc['db_free_result']($request); |
|
728 |
+ |
|
729 |
+ // Fix the content |
|
730 |
+ $replacements = array( |
|
731 |
+ '{user}' => $username, |
|
732 |
+ '{subject}' => $subject, |
|
733 |
+ '{link}' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $ticket, |
|
734 |
+ ); |
|
735 |
+ $message = str_replace(array_keys($replacements), array_values($replacements),$_POST['pm_content']); |
|
736 |
+ |
|
737 |
+ $recipients = array( |
|
738 |
+ 'to' => array($owner), |
|
739 |
+ 'bcc' => array() |
|
740 |
+ ); |
|
741 |
+ |
|
742 |
+ sendpm($recipients,$txt['shd_ticket_moved_subject_topic'],$message); |
|
743 |
+ } |
|
744 |
+ |
|
745 |
+ // And now for something completely different: attachments |
|
746 |
+ |
|
747 |
+ if (!empty($msg_assoc)) |
|
748 |
+ { |
|
749 |
+ // 1. Get all the attachments for these messages from the attachments table |
|
750 |
+ $attachIDs = array(); |
|
751 |
+ $query = shd_db_query('', ' |
|
752 |
+ SELECT id_attach, id_msg |
|
753 |
+ FROM {db_prefix}attachments |
|
754 |
+ WHERE id_msg IN ({array_int:smf_msgs})', |
|
755 |
+ array( |
|
756 |
+ 'smf_msgs' => array_keys($msg_assoc), |
|
757 |
+ ) |
|
758 |
+ ); |
|
759 |
+ |
|
760 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
761 |
+ $attachIDs[] = $row; |
|
762 |
+ $smcFunc['db_free_result']($query); |
|
763 |
+ |
|
764 |
+ if (!empty($attachIDs)) |
|
765 |
+ { |
|
766 |
+ // 2. Do the switch |
|
767 |
+ // 2.1. Add them to SD's tables |
|
768 |
+ $array = array(); |
|
769 |
+ foreach ($attachIDs as $attach) |
|
770 |
+ $array[] = array($attach['id_attach'], $ticket, $msg_assoc[$attach['id_msg']]); |
|
771 |
+ |
|
772 |
+ $smcFunc['db_insert']('replace', |
|
773 |
+ '{db_prefix}helpdesk_attachments', |
|
774 |
+ array( |
|
775 |
+ 'id_attach' => 'int', 'id_ticket' => 'int', 'id_msg' => 'int', |
|
776 |
+ ), |
|
777 |
+ $array, |
|
778 |
+ array( |
|
779 |
+ 'id_attach', |
|
780 |
+ ) |
|
781 |
+ ); |
|
782 |
+ |
|
783 |
+ // 2.2. "Remove" them from SMF's table |
|
784 |
+ shd_db_query('', ' |
|
785 |
+ UPDATE {db_prefix}attachments |
|
786 |
+ SET id_msg = 0 |
|
787 |
+ WHERE id_msg IN ({array_int:smf_msgs})', |
|
788 |
+ array( |
|
789 |
+ 'smf_msgs' => array_keys($msg_assoc), |
|
790 |
+ ) |
|
791 |
+ ); |
|
792 |
+ } |
|
793 |
+ } |
|
794 |
+ |
|
795 |
+ // Now we'll add this to the log. |
|
796 |
+ $log_params = array( |
|
797 |
+ 'subject' => $subject, |
|
798 |
+ 'ticket' => $ticket, |
|
799 |
+ ); |
|
800 |
+ shd_log_action('topictoticket', $log_params); |
|
801 |
+ |
|
802 |
+ // Update post counts. |
|
803 |
+ $request = shd_db_query('', ' |
|
804 |
+ SELECT id_member |
|
805 |
+ FROM {db_prefix}messages |
|
806 |
+ WHERE id_topic = {int:topic}', |
|
807 |
+ array( |
|
808 |
+ 'topic' => $context['topic_id'], |
|
809 |
+ ) |
|
810 |
+ ); |
|
811 |
+ $posters = array(); |
|
812 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
813 |
+ { |
|
814 |
+ if (!isset($posters[$row['id_member']])) |
|
815 |
+ $posters[$row['id_member']] = 0; |
|
816 |
+ |
|
817 |
+ $posters[$row['id_member']]++; |
|
818 |
+ } |
|
819 |
+ $smcFunc['db_free_result']($request); |
|
820 |
+ |
|
821 |
+ foreach ($posters as $id_member => $posts) |
|
822 |
+ { |
|
823 |
+ updateMemberData($id_member, array('posts' => 'posts - ' . $posts)); |
|
824 |
+ } |
|
825 |
+ |
|
826 |
+ // Lastly, delete the topic from the database. |
|
827 |
+ shd_db_query('', ' |
|
828 |
+ DELETE FROM {db_prefix}topics |
|
829 |
+ WHERE id_topic = {int:topic} |
|
830 |
+ LIMIT 1', |
|
831 |
+ array( |
|
832 |
+ 'topic' => $context['topic_id'], |
|
833 |
+ ) |
|
834 |
+ ); |
|
835 |
+ // And the replies, too. |
|
836 |
+ shd_db_query('', ' |
|
837 |
+ DELETE FROM {db_prefix}messages |
|
838 |
+ WHERE id_topic = {int:topic}', |
|
839 |
+ array( |
|
840 |
+ 'topic' => $context['topic_id'], |
|
841 |
+ ) |
|
842 |
+ ); |
|
843 |
+ |
|
844 |
+ // Update the stats. |
|
845 |
+ require_once($sourcedir . '/Subs-Post.php'); |
|
846 |
+ updateStats('message'); |
|
847 |
+ updateStats('topic'); |
|
848 |
+ updateLastMessages($board); |
|
849 |
+ |
|
850 |
+ // Update board post counts. |
|
851 |
+ shd_db_query('', ' |
|
852 |
+ UPDATE {db_prefix}boards |
|
853 |
+ SET num_topics = num_topics - 1, |
|
854 |
+ num_posts = num_posts - {int:num_posts} |
|
855 |
+ WHERE id_board = {int:board}', |
|
856 |
+ array( |
|
857 |
+ 'board' => $board, |
|
858 |
+ 'num_posts' => $num_replies, |
|
859 |
+ ) |
|
860 |
+ ); |
|
861 |
+ } |
|
862 |
+ else |
|
863 |
+ fatal_lang_error('shd_move_ticket_not_created',false); |
|
864 |
+ |
|
865 |
+ // Clear our cache |
|
866 |
+ shd_clear_active_tickets($owner); |
|
867 |
+ |
|
868 |
+ // Send them to the ticket. |
|
869 |
+ redirectexit('action=helpdesk;sa=ticket;ticket=' . $ticket); |
|
870 |
+} |
|
871 |
+ |
|
872 |
+?> |
|
0 | 873 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,957 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: SimpleDesk.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file serves as the entry point for SimpleDesk generally, as well as the home of the ticket listing |
|
22 |
+ * code, for open, closed and deleted tickets. |
|
23 |
+ * |
|
24 |
+ * @package source |
|
25 |
+ * @since 1.0 |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Begins SimpleDesk general processing. |
|
33 |
+ * |
|
34 |
+ * Several things are done here, the results of which are unilaterally assumed by all other SimpleDesk functions. |
|
35 |
+ * <ul> |
|
36 |
+ * <li>define standard constants for ticket status and urgency</li> |
|
37 |
+ * <li>set up general navigation</li> |
|
38 |
+ * <li>see if the URL or POST data contains a ticket, if so sanitise and store that value</li> |
|
39 |
+ * <li>see if a msg was specified in the URL, if so identify the relevant ticket</li> |
|
40 |
+ * <li>add in the helpdesk CSS file</li> |
|
41 |
+ * <li>identify the sub action to direct them to, then send them on their way.</li> |
|
42 |
+ * </ul> |
|
43 |
+ * |
|
44 |
+ * @since 1.0 |
|
45 |
+*/ |
|
46 |
+function shd_main() |
|
47 |
+{ |
|
48 |
+ global $context, $txt, $settings, $sourcedir, $modSettings, $scripturl, $user_profile, $user_info, $smcFunc; |
|
49 |
+ |
|
50 |
+ // This isn't the SMF way. But for something like this, it's way way more logical and readable. |
|
51 |
+ define('TICKET_STATUS_NEW', 0); |
|
52 |
+ define('TICKET_STATUS_PENDING_STAFF', 1); |
|
53 |
+ define('TICKET_STATUS_PENDING_USER', 2); |
|
54 |
+ define('TICKET_STATUS_CLOSED', 3); |
|
55 |
+ define('TICKET_STATUS_WITH_SUPERVISOR', 4); |
|
56 |
+ define('TICKET_STATUS_ESCALATED', 5); |
|
57 |
+ define('TICKET_STATUS_DELETED', 6); |
|
58 |
+ |
|
59 |
+ define('TICKET_URGENCY_LOW', 0); |
|
60 |
+ define('TICKET_URGENCY_MEDIUM', 1); |
|
61 |
+ define('TICKET_URGENCY_HIGH', 2); |
|
62 |
+ define('TICKET_URGENCY_VHIGH', 3); |
|
63 |
+ define('TICKET_URGENCY_SEVERE', 4); |
|
64 |
+ define('TICKET_URGENCY_CRITICAL', 5); |
|
65 |
+ |
|
66 |
+ define('MSG_STATUS_NORMAL', 0); |
|
67 |
+ define('MSG_STATUS_DELETED', 1); |
|
68 |
+ |
|
69 |
+ loadTemplate('SimpleDesk'); |
|
70 |
+ |
|
71 |
+ // Basic sanity stuff |
|
72 |
+ if (!$modSettings['helpdesk_active']) |
|
73 |
+ fatal_lang_error('shd_inactive', false); |
|
74 |
+ |
|
75 |
+ shd_is_allowed_to('access_helpdesk'); |
|
76 |
+ |
|
77 |
+ // List of sub actions. |
|
78 |
+ $subactions = array( |
|
79 |
+ 'main' => array(null, 'shd_main_helpdesk'), |
|
80 |
+ 'viewblock' => array(null, 'shd_view_block'), |
|
81 |
+ 'ticket' => array('SimpleDesk-Display.php', 'shd_view_ticket'), |
|
82 |
+ 'newticket' => array('SimpleDesk-Post.php', 'shd_post_ticket'), |
|
83 |
+ 'editticket' => array('SimpleDesk-Post.php', 'shd_post_ticket'), |
|
84 |
+ 'saveticket' => array('SimpleDesk-Post.php', 'shd_save_post'), // this is the equivalent of post2 |
|
85 |
+ 'reply' => array('SimpleDesk-Post.php', 'shd_post_reply'), |
|
86 |
+ 'savereply' => array('SimpleDesk-Post.php', 'shd_save_post'), |
|
87 |
+ 'editreply' => array('SimpleDesk-Post.php', 'shd_post_reply'), |
|
88 |
+ 'markunread' => array('SimpleDesk-MiscActions.php', 'shd_ticket_unread'), |
|
89 |
+ 'assign' => array('SimpleDesk-Assign.php', 'shd_assign'), |
|
90 |
+ 'assign2' => array('SimpleDesk-Assign.php', 'shd_assign2'), |
|
91 |
+ 'resolveticket' => array('SimpleDesk-MiscActions.php', 'shd_ticket_resolve'), |
|
92 |
+ 'ajax' => array('SimpleDesk-AjaxHandler.php', 'shd_ajax'), |
|
93 |
+ 'privacychange' => array('SimpleDesk-MiscActions.php', 'shd_privacy_change_noajax'), |
|
94 |
+ 'urgencychange' => array('SimpleDesk-MiscActions.php', 'shd_urgency_change_noajax'), |
|
95 |
+ 'closedtickets' => array(null, 'shd_closed_tickets'), |
|
96 |
+ 'recyclebin' => array(null, 'shd_recycle_bin'), |
|
97 |
+ 'tickettotopic' => array('SimpleDesk-TicketTopicMove.php', 'shd_tickettotopic'), |
|
98 |
+ 'tickettotopic2' => array('SimpleDesk-TicketTopicMove.php', 'shd_tickettotopic2'), |
|
99 |
+ 'topictoticket' => array('SimpleDesk-TicketTopicMove.php', 'shd_topictoticket'), |
|
100 |
+ 'topictoticket2' => array('SimpleDesk-TicketTopicMove.php', 'shd_topictoticket2'), |
|
101 |
+ 'permadelete' => array('SimpleDesk-Delete.php', 'shd_perma_delete'), |
|
102 |
+ 'deleteticket' => array('SimpleDesk-Delete.php', 'shd_ticket_delete'), |
|
103 |
+ 'deletereply' => array('SimpleDesk-Delete.php', 'shd_reply_delete'), |
|
104 |
+ 'restoreticket' => array('SimpleDesk-Delete.php', 'shd_ticket_restore'), |
|
105 |
+ 'restorereply' => array('SimpleDesk-Delete.php', 'shd_reply_restore'), |
|
106 |
+ ); |
|
107 |
+ |
|
108 |
+ // What are we doing? |
|
109 |
+ $_REQUEST['sa'] = (!empty($_REQUEST['sa']) && isset($subactions[$_REQUEST['sa']])) ? $_REQUEST['sa'] : 'main'; |
|
110 |
+ $context['sub_action'] = $subactions[$_REQUEST['sa']]; |
|
111 |
+ |
|
112 |
+ $context['can_new_ticket'] = shd_allowed_to('shd_new_ticket'); |
|
113 |
+ $context['can_view_closed'] = shd_allowed_to('shd_resolve_ticket_own') || shd_allowed_to('shd_resolve_ticket_any'); |
|
114 |
+ $context['can_view_recycle'] = shd_allowed_to('shd_access_recyclebin'); |
|
115 |
+ $context['display_back_to_hd'] = !in_array($_REQUEST['sa'], array('main', 'viewblock', 'recyclebin', 'closedtickets')); |
|
116 |
+ |
|
117 |
+ // Navigation menu |
|
118 |
+ $context['navigation'] = array( |
|
119 |
+ 'main' => array( |
|
120 |
+ 'text' => 'shd_home', |
|
121 |
+ 'lang' => true, |
|
122 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
123 |
+ ), |
|
124 |
+ 'newticket' => array( |
|
125 |
+ 'text' => 'shd_new_ticket', |
|
126 |
+ 'test' => 'can_new_ticket', |
|
127 |
+ 'lang' => true, |
|
128 |
+ 'url' => $scripturl . '?action=helpdesk;sa=newticket', |
|
129 |
+ ), |
|
130 |
+ 'closedtickets' => array( |
|
131 |
+ 'text' => 'shd_tickets_closed', |
|
132 |
+ 'test' => 'can_view_closed', |
|
133 |
+ 'lang' => true, |
|
134 |
+ 'url' => $scripturl . '?action=helpdesk;sa=closedtickets', |
|
135 |
+ ), |
|
136 |
+ 'recyclebin' => array( |
|
137 |
+ 'text' => 'shd_recycle_bin', |
|
138 |
+ 'test' => 'can_view_recycle', |
|
139 |
+ 'lang' => true, |
|
140 |
+ 'url' => $scripturl . '?action=helpdesk;sa=recyclebin', |
|
141 |
+ ), |
|
142 |
+ // Only for certain sub areas. |
|
143 |
+ 'back' => array( |
|
144 |
+ 'text' => 'shd_back_to_hd', |
|
145 |
+ 'test' => 'display_back_to_hd', |
|
146 |
+ 'lang' => true, |
|
147 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
148 |
+ ), |
|
149 |
+ ); |
|
150 |
+ |
|
151 |
+ // Highlight the correct button. |
|
152 |
+ if (isset($context['navigation'][$_REQUEST['sa']])) |
|
153 |
+ $context['navigation'][$_REQUEST['sa']]['active'] = true; |
|
154 |
+ |
|
155 |
+ // Build the link tree. |
|
156 |
+ $context['linktree'][] = array( |
|
157 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
158 |
+ 'name' => $txt['shd_helpdesk'], |
|
159 |
+ ); |
|
160 |
+ |
|
161 |
+ // See if a ticket has been specified, like $topic can be. |
|
162 |
+ if (!empty($_REQUEST['ticket'])) |
|
163 |
+ { |
|
164 |
+ if (strpos($_REQUEST['ticket'], '.') === false) |
|
165 |
+ { |
|
166 |
+ $context['ticket_id'] = (int) $_REQUEST['ticket']; |
|
167 |
+ $context['ticket_start'] = 0; |
|
168 |
+ } |
|
169 |
+ else |
|
170 |
+ { |
|
171 |
+ list ($context['ticket_id'], $context['ticket_start']) = explode('.', $_REQUEST['ticket']); |
|
172 |
+ $context['ticket_id'] = (int) $context['ticket_id']; |
|
173 |
+ if (!is_numeric($context['ticket_start'])) |
|
174 |
+ { |
|
175 |
+ if (substr($context['ticket_start'], 0, 3) == 'msg') |
|
176 |
+ { |
|
177 |
+ $virtual_msg = (int) substr($context['ticket_start'], 3); |
|
178 |
+ $query = shd_db_query('', ' |
|
179 |
+ SELECT COUNT(hdtr.id_msg) |
|
180 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
181 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
182 |
+ WHERE {query_see_ticket} |
|
183 |
+ AND hdtr.id_ticket = {int:ticket} |
|
184 |
+ AND hdtr.id_msg > hdt.id_first_msg |
|
185 |
+ AND hdtr.id_msg < {int:virtual_msg}', |
|
186 |
+ array( |
|
187 |
+ 'ticket' => $context['ticket_id'], |
|
188 |
+ 'virtual_msg' => $virtual_msg, |
|
189 |
+ ) |
|
190 |
+ ); |
|
191 |
+ list ($context['ticket_start']) = $smcFunc['db_fetch_row']($query); |
|
192 |
+ $smcFunc['db_free_result']($query); |
|
193 |
+ } |
|
194 |
+ } |
|
195 |
+ else |
|
196 |
+ $context['ticket_start'] = (int) $context['ticket_start']; // it IS numeric but let's make sure it's the right kind of number |
|
197 |
+ } |
|
198 |
+ } |
|
199 |
+ |
|
200 |
+ // Do we have just a message id? We can get the ticket from that - but only if we don't already have a ticket id! |
|
201 |
+ $_REQUEST['msg'] = !empty($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0; |
|
202 |
+ if (!empty($_REQUEST['msg']) && empty($context['ticket_id'])) |
|
203 |
+ { |
|
204 |
+ $query = shd_db_query('', ' |
|
205 |
+ SELECT hdt.id_ticket, hdtr.id_msg |
|
206 |
+ FROM {db_prefix}helpdesk_ticket_replies AS hdtr |
|
207 |
+ INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket) |
|
208 |
+ WHERE {query_see_ticket} |
|
209 |
+ AND hdtr.id_msg = {int:msg}', |
|
210 |
+ array( |
|
211 |
+ 'msg' => $_REQUEST['msg'], |
|
212 |
+ ) |
|
213 |
+ ); |
|
214 |
+ |
|
215 |
+ if ($row = $smcFunc['db_fetch_row']($query)) |
|
216 |
+ $context['ticket_id'] = (int) $row[0]; |
|
217 |
+ |
|
218 |
+ $smcFunc['db_free_result']($query); |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ $context['items_per_page'] = 10; |
|
222 |
+ $context['start'] = isset($_REQUEST['start']) ? $_REQUEST['start'] : 0; |
|
223 |
+ |
|
224 |
+ // Load the custom CSS. |
|
225 |
+ if (empty($context['html_headers'])) |
|
226 |
+ $context['html_headers'] = ''; |
|
227 |
+ |
|
228 |
+ $context['html_headers'] .= ' |
|
229 |
+ <link rel="stylesheet" type="text/css" href="' . (file_exists($settings['theme_dir'] . '/css/helpdesk.css') ? $settings['theme_url'] . '/css/helpdesk.css' : $settings['default_theme_url'] . '/css/helpdesk.css') . '" /> |
|
230 |
+ <script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/helpdesk.js?rc2"></script>'; |
|
231 |
+ |
|
232 |
+ // Darn IE6. Die, already :( |
|
233 |
+ if ($context['browser']['is_ie6']) |
|
234 |
+ $context['html_headers'] .= ' |
|
235 |
+ <!-- Fall back, dark force, for we shall thou evil powers not endorse --> |
|
236 |
+ <link rel="stylesheet" type="text/css" href="' . $settings['default_theme_url'] . '/css/helpdesk_ie6.css" />'; |
|
237 |
+ |
|
238 |
+ // Send them away. |
|
239 |
+ if ($context['sub_action'][0] !== null) |
|
240 |
+ require ($sourcedir . '/' . $context['sub_action'][0]); |
|
241 |
+ |
|
242 |
+ $context['sub_action'][1](); |
|
243 |
+} |
|
244 |
+ |
|
245 |
+/** |
|
246 |
+ * Display the main front page, showing tickets waiting for staff, waiting for user feedback and so on. |
|
247 |
+ * |
|
248 |
+ * This function sets up multiple blocks to be shown to users, defines what columns these blocks should have and states |
|
249 |
+ * the rules to be used in getting the data. |
|
250 |
+ * |
|
251 |
+ * Each block has multiple parameters, and is stated in $context['ticket_blocks']: |
|
252 |
+ * <ul> |
|
253 |
+ * <li>block_icon: which image to use in Themes/default/images/simpledesk for denoting the type of block; filename plus extension</li> |
|
254 |
+ * <li>title: the text string to use as the block's heading</li> |
|
255 |
+ * <li>where: an SQL clause denoting the rule for obtaining the items in this block</li> |
|
256 |
+ * <li>display: whether the block should be processed and prepared for display</li> |
|
257 |
+ * <li>count: the number of items in this block, for pagination; generally should be a call to {@link shd_count_helpdesk_tickets()}</li> |
|
258 |
+ * <li>columns: an array of columns to display in this block, in the order they should be displayed, using the following options, derived from {@link shd_get_block_columns()}: |
|
259 |
+ * <ul> |
|
260 |
+ * <li>ticket_id: the ticket's read status, privacy icon, and id</li> |
|
261 |
+ * <li>ticket_name: name/link to the ticket</li> |
|
262 |
+ * <li>starting_user: profile link to the user who opened the ticket</li> |
|
263 |
+ * <li>replies: number of (visible) replies in the ticket</li> |
|
264 |
+ * <li>allreplies: number of (all) replies in the ticket (includes deleted replies, which 'replies' does not)</li> |
|
265 |
+ * <li>last_reply: the user who last replied</li> |
|
266 |
+ * <li>status: the current ticket's status</li> |
|
267 |
+ * <li>assigned: link to the profile of the user the ticket is assigned to, or 'Unassigned' if not assigned</li> |
|
268 |
+ * <li>urgency: the current ticket's urgency</li> |
|
269 |
+ * <li>updated: time of the last reply in the ticket; states Never if no replies</li> |
|
270 |
+ * <li>actions: icons that may or may not relate to a given ticket; buttons for recycle, delete, unresolve live in this column</li> |
|
271 |
+ * </ul> |
|
272 |
+ * <li>required: whether the block is required to be displayed even if empty</li> |
|
273 |
+ * <li>collapsed: whether the block should be compressed to a header with count of tickets or not (mostly for {@link shd_view_block()}'s benefit)</li> |
|
274 |
+ * </ul> |
|
275 |
+ * |
|
276 |
+ * This function declares the following blocks: |
|
277 |
+ * <ul> |
|
278 |
+ * <li>Assigned to me (staff only)</li> |
|
279 |
+ * <li>New tickets (staff only)</li> |
|
280 |
+ * <li>Pending with staff (for staff, this is just tickets with that status, for regular users this is both pending staff and new unreplied to tickets)</li> |
|
281 |
+ * <li>Pending with user (both)</li> |
|
282 |
+ * </ul> |
|
283 |
+ * |
|
284 |
+ * @see shd_count_helpdesk_tickets() |
|
285 |
+ * @since 1.0 |
|
286 |
+*/ |
|
287 |
+function shd_main_helpdesk() |
|
288 |
+{ |
|
289 |
+ global $context, $txt, $smcFunc, $user_profile, $scripturl, $user_info; |
|
290 |
+ |
|
291 |
+ $is_staff = shd_allowed_to('shd_staff'); |
|
292 |
+ // Stuff we need to add to $context, page title etc etc |
|
293 |
+ $context += array( |
|
294 |
+ 'page_title' => $txt['shd_helpdesk'], |
|
295 |
+ 'sub_template' => 'main', |
|
296 |
+ 'ticket_blocks' => array( // the numbers tie back to the master status idents |
|
297 |
+ 'assigned' => array( |
|
298 |
+ 'block_icon' => 'assign.png', |
|
299 |
+ 'title' => $txt['shd_status_assigned_heading'], |
|
300 |
+ 'where' => 'hdt.id_member_assigned = ' . $user_info['id'] . ' AND hdt.status NOT IN (' . TICKET_STATUS_CLOSED . ',' . TICKET_STATUS_DELETED . ')', |
|
301 |
+ 'display' => $is_staff, |
|
302 |
+ 'count' => shd_count_helpdesk_tickets('assigned'), |
|
303 |
+ 'columns' => shd_get_block_columns('assigned'), |
|
304 |
+ 'required' => $is_staff, |
|
305 |
+ 'collapsed' => false, |
|
306 |
+ ), |
|
307 |
+ 'new' => array( |
|
308 |
+ 'block_icon' => 'status.png', |
|
309 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'], |
|
310 |
+ 'where' => 'hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_NEW, |
|
311 |
+ 'display' => $is_staff, |
|
312 |
+ 'count' => shd_count_helpdesk_tickets('new'), |
|
313 |
+ 'columns' => shd_get_block_columns('new'), |
|
314 |
+ 'required' => false, |
|
315 |
+ 'collapsed' => false, |
|
316 |
+ ), |
|
317 |
+ 'staff' => array( |
|
318 |
+ 'block_icon' => 'staff.png', |
|
319 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'], |
|
320 |
+ 'where' => $is_staff ? ('hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_PENDING_STAFF) : ('hdt.status IN (' . TICKET_STATUS_NEW . ',' . TICKET_STATUS_PENDING_STAFF . ')'), // put new and with staff together in 'waiting for staff' for end user |
|
321 |
+ 'display' => true, |
|
322 |
+ 'count' => shd_count_helpdesk_tickets('staff', $is_staff), |
|
323 |
+ 'columns' => shd_get_block_columns('staff'), |
|
324 |
+ 'required' => true, |
|
325 |
+ 'collapsed' => false, |
|
326 |
+ ), |
|
327 |
+ 'user' => array( |
|
328 |
+ 'block_icon' => 'user.png', |
|
329 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'], |
|
330 |
+ 'where' => $is_staff ? ('hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_PENDING_USER) : ('hdt.status = ' . TICKET_STATUS_PENDING_USER), |
|
331 |
+ 'display' => true, |
|
332 |
+ 'count' => shd_count_helpdesk_tickets('with_user'), |
|
333 |
+ 'columns' => shd_get_block_columns($is_staff ? 'user_staff' : 'user_user'), |
|
334 |
+ 'required' => true, |
|
335 |
+ 'collapsed' => false, |
|
336 |
+ ), |
|
337 |
+ ), |
|
338 |
+ 'shd_home_view' => shd_allowed_to('shd_staff') ? 'staff' : 'user', |
|
339 |
+ ); |
|
340 |
+ |
|
341 |
+ shd_helpdesk_listing(); |
|
342 |
+} |
|
343 |
+ |
|
344 |
+/** |
|
345 |
+ * Sets up viewing of a single block without any pagination. |
|
346 |
+ * |
|
347 |
+ * This provides the ability to see all of a given type of ticket at once without paging through them, which are all sortable. |
|
348 |
+ * |
|
349 |
+ * @see shd_main_helpdesk() |
|
350 |
+ * @since 1.0 |
|
351 |
+*/ |
|
352 |
+function shd_view_block() |
|
353 |
+{ |
|
354 |
+ global $context, $txt, $smcFunc, $user_profile, $scripturl, $user_info; |
|
355 |
+ |
|
356 |
+ $is_staff = shd_allowed_to('shd_staff'); |
|
357 |
+ // Stuff we need to add to $context, page title etc etc |
|
358 |
+ $context += array( |
|
359 |
+ 'page_title' => $txt['shd_helpdesk'], |
|
360 |
+ 'sub_template' => 'main', |
|
361 |
+ 'ticket_blocks' => array( // the numbers tie back to the master status idents |
|
362 |
+ 'assigned' => array( |
|
363 |
+ 'block_icon' => 'assign.png', |
|
364 |
+ 'title' => $txt['shd_status_assigned_heading'], |
|
365 |
+ 'where' => 'hdt.id_member_assigned = ' . $user_info['id'] . ' AND hdt.status NOT IN (' . TICKET_STATUS_CLOSED . ',' . TICKET_STATUS_DELETED . ')', |
|
366 |
+ 'display' => $is_staff, |
|
367 |
+ 'count' => shd_count_helpdesk_tickets('assigned'), |
|
368 |
+ 'columns' => shd_get_block_columns('assigned'), |
|
369 |
+ 'required' => $is_staff, |
|
370 |
+ 'collapsed' => false, |
|
371 |
+ ), |
|
372 |
+ 'new' => array( |
|
373 |
+ 'block_icon' => 'status.png', |
|
374 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'], |
|
375 |
+ 'where' => 'hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_NEW, |
|
376 |
+ 'display' => $is_staff, |
|
377 |
+ 'count' => shd_count_helpdesk_tickets('new'), |
|
378 |
+ 'columns' => shd_get_block_columns('new'), |
|
379 |
+ 'required' => false, |
|
380 |
+ 'collapsed' => false, |
|
381 |
+ ), |
|
382 |
+ 'staff' => array( |
|
383 |
+ 'block_icon' => 'staff.png', |
|
384 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'], |
|
385 |
+ 'where' => $is_staff ? ('hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_PENDING_STAFF) : ('hdt.status IN (' . TICKET_STATUS_NEW . ',' . TICKET_STATUS_PENDING_STAFF . ')'), // put new and with staff together in 'waiting for staff' for end user |
|
386 |
+ 'display' => true, |
|
387 |
+ 'count' => shd_count_helpdesk_tickets('staff', $is_staff), |
|
388 |
+ 'columns' => shd_get_block_columns('staff'), |
|
389 |
+ 'required' => true, |
|
390 |
+ 'collapsed' => false, |
|
391 |
+ ), |
|
392 |
+ 'user' => array( |
|
393 |
+ 'block_icon' => 'user.png', |
|
394 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'], |
|
395 |
+ 'where' => $is_staff ? ('hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_PENDING_USER) : ('hdt.status = ' . TICKET_STATUS_PENDING_USER), |
|
396 |
+ 'display' => true, |
|
397 |
+ 'count' => shd_count_helpdesk_tickets('with_user'), |
|
398 |
+ 'columns' => shd_get_block_columns($is_staff ? 'user_staff' : 'user_user'), |
|
399 |
+ 'required' => true, |
|
400 |
+ 'collapsed' => false, |
|
401 |
+ ), |
|
402 |
+ ), |
|
403 |
+ 'shd_home_view' => shd_allowed_to('shd_staff') ? 'staff' : 'user', |
|
404 |
+ ); |
|
405 |
+ |
|
406 |
+ if (empty($_REQUEST['block']) || empty($context['ticket_blocks'][$_REQUEST['block']]) || empty($context['ticket_blocks'][$_REQUEST['block']]['count'])) |
|
407 |
+ redirectexit('action=helpdesk;sa=main'); |
|
408 |
+ |
|
409 |
+ $context['items_per_page'] = 10; |
|
410 |
+ foreach ($context['ticket_blocks'] as $block => $details) |
|
411 |
+ { |
|
412 |
+ if ($block == $_REQUEST['block']) |
|
413 |
+ $context['items_per_page'] = $details['count']; |
|
414 |
+ else |
|
415 |
+ $context['ticket_blocks'][$block]['collapsed'] = true; |
|
416 |
+ } |
|
417 |
+ |
|
418 |
+ shd_helpdesk_listing(); |
|
419 |
+} |
|
420 |
+ |
|
421 |
+/** |
|
422 |
+ * Set up the paginated lists of closed tickets. |
|
423 |
+ * |
|
424 |
+ * Much like the main helpdesk, this function prepares a list of all the closed/resolved tickets, with a more specific |
|
425 |
+ * list of columns that is better suited to resolved tickets. |
|
426 |
+ * |
|
427 |
+ * @see shd_main_helpdesk() |
|
428 |
+ * @since 1.0 |
|
429 |
+*/ |
|
430 |
+function shd_closed_tickets() |
|
431 |
+{ |
|
432 |
+ global $context, $txt, $smcFunc, $user_profile, $scripturl, $settings, $user_info; |
|
433 |
+ |
|
434 |
+ if (!shd_allowed_to('shd_resolve_ticket_own') && shd_allowed_to('shd_resolve_ticket_any')) |
|
435 |
+ fatal_lang_error('shd_cannot_view_resolved', false); |
|
436 |
+ |
|
437 |
+ // Stuff we need to add to $context, the permission we want to use, page title etc etc |
|
438 |
+ $context += array( |
|
439 |
+ 'page_title' => $txt['shd_helpdesk'], |
|
440 |
+ 'sub_template' => 'closedtickets', |
|
441 |
+ 'ticket_blocks' => array( |
|
442 |
+ 'closed' => array( |
|
443 |
+ 'block_icon' => 'resolved.png', |
|
444 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_CLOSED . '_heading'], |
|
445 |
+ 'where' => 'hdt.status = ' . TICKET_STATUS_CLOSED, |
|
446 |
+ 'display' => true, |
|
447 |
+ 'count' => shd_count_helpdesk_tickets('closed'), |
|
448 |
+ 'columns' => shd_get_block_columns('closed'), |
|
449 |
+ 'required' => true, |
|
450 |
+ 'collapsed' => false, |
|
451 |
+ ), |
|
452 |
+ ), |
|
453 |
+ 'shd_home_view' => shd_allowed_to('shd_staff') ? 'staff' : 'user', // This might be removed in the future. We do this here to be able to re-use template_ticket_block() in the template. |
|
454 |
+ ); |
|
455 |
+ |
|
456 |
+ // Build the link tree. |
|
457 |
+ $context['linktree'][] = array( |
|
458 |
+ 'url' => $scripturl . '?action=helpdesk;sa=main', |
|
459 |
+ 'name' => $txt['shd_linktree_tickets'], |
|
460 |
+ ); |
|
461 |
+ $context['linktree'][] = array( |
|
462 |
+ 'url' => $scripturl . '?action=helpdesk;sa=closedtickets', |
|
463 |
+ 'name' => $txt['shd_tickets_closed'], |
|
464 |
+ ); |
|
465 |
+ |
|
466 |
+ shd_helpdesk_listing(); |
|
467 |
+} |
|
468 |
+ |
|
469 |
+/** |
|
470 |
+ * Set up the paginated lists of deleted/recyclebin tickets. |
|
471 |
+ * |
|
472 |
+ * Much like the main helpdesk, this function prepares a list of all the deleted tickets, with a more specific |
|
473 |
+ * list of columns that is better suited to recyclable or permadeletable tickets. |
|
474 |
+ * |
|
475 |
+ * @see shd_main_helpdesk() |
|
476 |
+ * @since 1.0 |
|
477 |
+*/ |
|
478 |
+function shd_recycle_bin() |
|
479 |
+{ |
|
480 |
+ global $context, $txt, $smcFunc, $user_profile, $scripturl, $settings, $user_info; |
|
481 |
+ |
|
482 |
+ // Stuff we need to add to $context, the permission we want to use, page title etc etc |
|
483 |
+ $context += array( |
|
484 |
+ 'shd_permission' => 'shd_access_recyclebin', |
|
485 |
+ 'page_title' => $txt['shd_helpdesk'], |
|
486 |
+ 'sub_template' => 'recyclebin', |
|
487 |
+ 'ticket_blocks' => array( |
|
488 |
+ 'recycle' => array( |
|
489 |
+ 'block_icon' => 'recycle.png', |
|
490 |
+ 'title' => $txt['shd_status_' . TICKET_STATUS_DELETED . '_heading'], |
|
491 |
+ 'tickets' => array(), |
|
492 |
+ 'where' => 'hdt.status = ' . TICKET_STATUS_DELETED, |
|
493 |
+ 'display' => true, |
|
494 |
+ 'count' => shd_count_helpdesk_tickets('recycled'), |
|
495 |
+ 'columns' => shd_get_block_columns('recycled'), |
|
496 |
+ 'required' => true, |
|
497 |
+ 'collapsed' => false, |
|
498 |
+ ), |
|
499 |
+ 'withdeleted' => array( |
|
500 |
+ 'block_icon' => 'recycle.png', |
|
501 |
+ 'title' => $txt['shd_status_withdeleted_heading'], |
|
502 |
+ 'tickets' => array(), |
|
503 |
+ 'where' => 'hdt.status != ' . TICKET_STATUS_DELETED . ' AND hdt.deleted_replies > 0', |
|
504 |
+ 'display' => true, |
|
505 |
+ 'count' => shd_count_helpdesk_tickets('withdeleted'), |
|
506 |
+ 'columns' => shd_get_block_columns('withdeleted'), |
|
507 |
+ 'required' => true, |
|
508 |
+ 'collapsed' => false, |
|
509 |
+ ), |
|
510 |
+ ), |
|
511 |
+ ); |
|
512 |
+ |
|
513 |
+ // Build the link tree. |
|
514 |
+ $context['linktree'][] = array( |
|
515 |
+ 'url' => $scripturl . '?action=helpdesk;sa=recyclebin', |
|
516 |
+ 'name' => $txt['shd_recycle_bin'], |
|
517 |
+ ); |
|
518 |
+ |
|
519 |
+ shd_helpdesk_listing(); |
|
520 |
+} |
|
521 |
+ |
|
522 |
+/** |
|
523 |
+ * Gather the data and prepare to display the ticket blocks. |
|
524 |
+ * |
|
525 |
+ * Actually performs the queries to get data for each block, subject to the parameters specified by the calling functions. |
|
526 |
+ * |
|
527 |
+ * It also sets up per-block pagination links, collects a variety of data (enough to populate all the columns as listed in shd_main_helpdesk, |
|
528 |
+ * even if not entirely applicable, and populates it all into $context['ticket_blocks']['tickets'], extending the array that was |
|
529 |
+ * already there. |
|
530 |
+ * |
|
531 |
+ * @see shd_main_helpdesk() |
|
532 |
+ * @see shd_closed_tickets() |
|
533 |
+ * @see shd_recycle_bin() |
|
534 |
+ * @since 1.0 |
|
535 |
+*/ |
|
536 |
+function shd_helpdesk_listing() |
|
537 |
+{ |
|
538 |
+ global $context, $txt, $smcFunc, $user_profile, $scripturl, $settings, $user_info, $modSettings; |
|
539 |
+ |
|
540 |
+ if (!empty($context['shd_permission'])) |
|
541 |
+ shd_is_allowed_to($context['shd_permission']); |
|
542 |
+ |
|
543 |
+ $num_per_page = $context['items_per_page']; |
|
544 |
+ $block_list = array_keys($context['ticket_blocks']); |
|
545 |
+ $primary_url = '?action=helpdesk;sa=' . $_REQUEST['sa']; |
|
546 |
+ |
|
547 |
+ // First figure out the start positions of each item and sanitise them |
|
548 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
549 |
+ { |
|
550 |
+ $start = empty($_REQUEST['st_' . $block_key]) ? 0 : (int) $_REQUEST['st_' . $block_key]; |
|
551 |
+ $max_value = $block['count']; // easier to read |
|
552 |
+ |
|
553 |
+ if ($start < 0) |
|
554 |
+ $start = 0; |
|
555 |
+ elseif ($start >= $max_value) |
|
556 |
+ $start = max(0, (int) $max_value - (((int) $max_value % (int) $num_per_page) == 0 ? $num_per_page : ((int) $max_value % (int) $num_per_page))); |
|
557 |
+ else |
|
558 |
+ $start = max(0, (int) $start - ((int) $start % (int) $num_per_page)); |
|
559 |
+ |
|
560 |
+ $context['ticket_blocks'][$block_key]['start'] = $start; |
|
561 |
+ if ($start != 0) |
|
562 |
+ $_REQUEST['st_' . $block_key] = $start; // sanitise! |
|
563 |
+ elseif (isset($_REQUEST['st_' . $block_key])) |
|
564 |
+ unset($_REQUEST['st_' . $block_key]); |
|
565 |
+ } |
|
566 |
+ |
|
567 |
+ // Now ordering the columns, separate loop for breaking the two processes apart |
|
568 |
+ $sort_methods = array( |
|
569 |
+ 'ticketid' => array( |
|
570 |
+ 'sql' => 'hdt.id_ticket', |
|
571 |
+ ), |
|
572 |
+ 'ticketname' => array( |
|
573 |
+ 'sql' => 'hdt.subject', |
|
574 |
+ ), |
|
575 |
+ 'replies' => array( |
|
576 |
+ 'sql' => 'hdt.num_replies', |
|
577 |
+ ), |
|
578 |
+ 'allreplies' => array( |
|
579 |
+ 'sql' => '(hdt.num_replies + hdt.deleted_replies)', |
|
580 |
+ ), |
|
581 |
+ 'urgency' => array( |
|
582 |
+ 'sql' => 'hdt.urgency', |
|
583 |
+ ), |
|
584 |
+ 'updated' => array( |
|
585 |
+ 'sql' => 'hdt.id_last_msg', |
|
586 |
+ ), |
|
587 |
+ 'assigned' => array( |
|
588 |
+ 'sql' => 'assigned_name', |
|
589 |
+ 'sql_select' => 'IFNULL(mem.real_name, 0) AS assigned_name', |
|
590 |
+ 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_assigned = mem.id_member)', |
|
591 |
+ ), |
|
592 |
+ 'status' => array( |
|
593 |
+ 'sql' => 'hdt.status', |
|
594 |
+ ), |
|
595 |
+ 'starter' => array( |
|
596 |
+ 'sql' => 'starter_name', |
|
597 |
+ 'sql_select' => 'IFNULL(mem.real_name, 0) AS starter_name', |
|
598 |
+ 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member)', |
|
599 |
+ ), |
|
600 |
+ 'lastreply' => array( |
|
601 |
+ 'sql' => 'last_reply', |
|
602 |
+ 'sql_select' => 'IFNULL(mem.real_name, 0) AS last_reply', |
|
603 |
+ 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdtr_last.id_member = mem.id_member)', |
|
604 |
+ ), |
|
605 |
+ ); |
|
606 |
+ |
|
607 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
608 |
+ { |
|
609 |
+ $sort = isset($_REQUEST['so_' . $block_key]) ? $_REQUEST['so_' . $block_key] : ''; |
|
610 |
+ |
|
611 |
+ if (strpos($sort, '_') > 0 && substr_count($sort, '_') == 1) |
|
612 |
+ { |
|
613 |
+ list($sort_item, $sort_dir) = explode('_', $sort); |
|
614 |
+ |
|
615 |
+ if (empty($sort_methods[$sort_item])) |
|
616 |
+ { |
|
617 |
+ $sort_item = 'updated'; |
|
618 |
+ $sort = ''; |
|
619 |
+ } |
|
620 |
+ |
|
621 |
+ if (!in_array($sort_dir, array('asc', 'desc'))) |
|
622 |
+ { |
|
623 |
+ $sort = ''; |
|
624 |
+ $sort_dir = 'asc'; |
|
625 |
+ } |
|
626 |
+ } |
|
627 |
+ else |
|
628 |
+ { |
|
629 |
+ $sort = ''; |
|
630 |
+ $sort_item = 'updated'; |
|
631 |
+ $sort_dir = $_REQUEST['sa'] == 'closedtickets' || $_REQUEST['sa'] == 'recyclebin' ? 'desc' : 'asc'; // default to newest first if on recyclebin or closed tickets, otherwise oldest first |
|
632 |
+ } |
|
633 |
+ |
|
634 |
+ if ($sort != '') |
|
635 |
+ $_REQUEST['so_' . $block_key] = $sort; // sanitise! |
|
636 |
+ elseif (isset($_REQUEST['so_' . $block_key])) |
|
637 |
+ unset($_REQUEST['so_' . $block_key]); |
|
638 |
+ |
|
639 |
+ $context['ticket_blocks'][$block_key]['sort'] = array( |
|
640 |
+ 'item' => $sort_item, |
|
641 |
+ 'direction' => $sort_dir, |
|
642 |
+ 'add_link' => ($sort != ''), |
|
643 |
+ 'sql' => array( |
|
644 |
+ 'select' => !empty($sort_methods[$sort_item]['sql_select']) ? $sort_methods[$sort_item]['sql_select'] : '', |
|
645 |
+ 'join' => !empty($sort_methods[$sort_item]['sql_join']) ? $sort_methods[$sort_item]['sql_join'] : '', |
|
646 |
+ 'sort' => $sort_methods[$sort_item]['sql'] . ' ' . strtoupper($sort_dir), |
|
647 |
+ ), |
|
648 |
+ 'link_bits' => array(), |
|
649 |
+ ); |
|
650 |
+ } |
|
651 |
+ |
|
652 |
+ // Having got all that, step through the blocks again to determine the full URL fragments |
|
653 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
654 |
+ foreach ($sort_methods as $method => $sort_details) |
|
655 |
+ $context['ticket_blocks'][$block_key]['sort']['link_bits'][$method] = ';so_' . $block_key . '=' . $method . '_' . $block['sort']['direction']; |
|
656 |
+ |
|
657 |
+ // Now go actually do the whole block thang, setting up space for a list of users as we go along |
|
658 |
+ $users = array(); |
|
659 |
+ |
|
660 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
661 |
+ { |
|
662 |
+ if (empty($block['display']) || !empty($block['collapsed'])) |
|
663 |
+ continue; |
|
664 |
+ |
|
665 |
+ $context['ticket_blocks'][$block_key]['tickets'] = array(); |
|
666 |
+ |
|
667 |
+ $query = shd_db_query('', ' |
|
668 |
+ SELECT hdt.id_ticket, hdt.id_last_msg, hdt.id_member_started, hdt.id_member_updated, hdt.id_member_assigned, |
|
669 |
+ hdt.subject, hdt.status, hdt.num_replies, hdt.deleted_replies, hdt.private, hdt.urgency, |
|
670 |
+ hdtr_first.poster_name AS ticket_opener, hdtr_last.poster_name AS respondent, hdtr_last.poster_time, |
|
671 |
+ IFNULL(hdlr.id_msg, 0) AS log_read' . (!empty($block['sort']['sql']['select']) ? ', ' . $block['sort']['sql']['select'] : '') . ' |
|
672 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
673 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg) |
|
674 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg) |
|
675 |
+ LEFT JOIN {db_prefix}helpdesk_log_read AS hdlr ON (hdt.id_ticket = hdlr.id_ticket AND hdlr.id_member = {int:user}) |
|
676 |
+ ' . (!empty($block['sort']['sql']['join']) ? $block['sort']['sql']['join'] : '') . ' |
|
677 |
+ WHERE {query_see_ticket}' . (!empty($block['where']) ? ' AND ' . $block['where'] : '') . ' |
|
678 |
+ ORDER BY ' . (!empty($block['sort']['sql']['sort']) ? $block['sort']['sql']['sort'] : 'hdt.id_last_msg ASC') . ' |
|
679 |
+ LIMIT {int:start}, {int:items_per_page}', |
|
680 |
+ array( |
|
681 |
+ 'user' => $context['user']['id'], |
|
682 |
+ 'start' => $block['start'], |
|
683 |
+ 'items_per_page' => $context['items_per_page'], |
|
684 |
+ ) |
|
685 |
+ ); |
|
686 |
+ |
|
687 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
688 |
+ { |
|
689 |
+ $is_own = $user_info['id'] == $row['id_member_started']; |
|
690 |
+ censorText($row['subject']); |
|
691 |
+ |
|
692 |
+ $new_block = array( |
|
693 |
+ 'id' => $row['id_ticket'], |
|
694 |
+ 'display_id' => str_pad($row['id_ticket'], 5, '0', STR_PAD_LEFT), |
|
695 |
+ 'link' => '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '">' . $row['subject'] . '</a>', |
|
696 |
+ 'subject' => $row['subject'], |
|
697 |
+ 'status' => array( |
|
698 |
+ 'level' => $row['status'], |
|
699 |
+ 'label' => $txt['shd_status_' . $row['status']], |
|
700 |
+ ), |
|
701 |
+ 'starter' => array( |
|
702 |
+ 'id' => $row['id_member_started'], |
|
703 |
+ 'name' => $row['ticket_opener'], |
|
704 |
+ ), |
|
705 |
+ 'last_update' => $row['status'] != TICKET_STATUS_NEW ? timeformat($row['poster_time']) : $txt['never'], |
|
706 |
+ 'assigned' => array( |
|
707 |
+ 'id' => $row['id_member_assigned'], |
|
708 |
+ ), |
|
709 |
+ 'respondent' => array( |
|
710 |
+ 'id' => $row['id_member_updated'], |
|
711 |
+ 'name' => $row['respondent'], |
|
712 |
+ ), |
|
713 |
+ 'urgency' => array( |
|
714 |
+ 'level' => $row['urgency'], |
|
715 |
+ 'label' => $row['urgency'] > TICKET_URGENCY_HIGH ? '<span class="error">' . $txt['shd_urgency_' . $row['urgency']] . '</span>' : $txt['shd_urgency_' . $row['urgency']], |
|
716 |
+ ), |
|
717 |
+ 'is_unread' => ($row['id_last_msg'] > $row['log_read']), |
|
718 |
+ 'private' => $row['private'], |
|
719 |
+ 'actions' => array(), |
|
720 |
+ 'num_replies' => $row['num_replies'], |
|
721 |
+ 'all_replies' => (int) $row['num_replies'] + (int) $row['deleted_replies'], |
|
722 |
+ ); |
|
723 |
+ |
|
724 |
+ if ($row['status'] == TICKET_STATUS_CLOSED) |
|
725 |
+ { |
|
726 |
+ $new_block['actions'] += array( |
|
727 |
+ 'resolve' => shd_allowed_to('shd_resolve_ticket_any') || ($is_own && shd_allowed_to('shd_resolve_ticket_own')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_unresolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/unresolved.png" alt="' . $txt['shd_ticket_unresolved'] . '" /></a>' : '', |
|
728 |
+ ); |
|
729 |
+ } |
|
730 |
+ elseif ($row['status'] == TICKET_STATUS_DELETED) // and thus, we're in the recycle bin |
|
731 |
+ { |
|
732 |
+ $new_block['actions'] += array( |
|
733 |
+ 'restore' => shd_allowed_to('shd_restore_ticket_any') || ($is_own && shd_allowed_to('shd_restore_ticket_own')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=restoreticket;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_restore'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/restore.png" alt="' . $txt['shd_ticket_restore'] . '" /></a>' : '', |
|
734 |
+ 'permadelete' => shd_allowed_to('shd_delete_recycling') ? '<a href="' . $scripturl . '?action=helpdesk;sa=permadelete;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_delete_permanently'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_permanently_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_delete_permanently'] . '" /></a>' : '', |
|
735 |
+ ); |
|
736 |
+ } |
|
737 |
+ else |
|
738 |
+ { |
|
739 |
+ $langstring = ''; |
|
740 |
+ if (shd_allowed_to('shd_assign_ticket_any')) |
|
741 |
+ $langstring = empty($row['id_member_assigned']) ? $txt['shd_ticket_assign'] : $txt['shd_ticket_reassign']; |
|
742 |
+ elseif (shd_allowed_to('shd_assign_ticket_own') && (empty($row['id_member_assigned']) || $row['id_member_assigned'] == $context['user']['id'])) |
|
743 |
+ $langstring = $row['id_member_assigned'] == $context['user']['id'] ? $txt['shd_ticket_unassign'] : $txt['shd_ticket_assign_self']; |
|
744 |
+ |
|
745 |
+ if (!empty($langstring)) |
|
746 |
+ $new_block['actions']['assign'] = '<a href="' . $scripturl . '?action=helpdesk;sa=assign;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $langstring . '"><img src="' . $settings['default_images_url'] . '/simpledesk/assign.png" alt="' . $langstring . '" /></a>'; |
|
747 |
+ |
|
748 |
+ $new_block['actions'] += array( |
|
749 |
+ 'resolve' => shd_allowed_to('shd_resolve_ticket_any') || ($is_own && shd_allowed_to('shd_resolve_ticket_own')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_resolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/resolved.png" alt="' . $txt['shd_ticket_resolved'] . '" /></a>' : '', |
|
750 |
+ 'tickettotopic' => empty($modSettings['shd_helpdesk_only']) && shd_allowed_to('shd_ticket_to_topic') && ($row['deleted_replies'] == 0 || shd_allowed_to('shd_access_recyclebin')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=tickettotopic;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_move_to_topic'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/tickettotopic.png" alt="' . $txt['shd_ticket_move_to_topic'] . '" /></a>' : '', |
|
751 |
+ 'delete' => shd_allowed_to('shd_delete_ticket_any') || ($is_own && shd_allowed_to('shd_delete_ticket_own')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=deleteticket;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_delete'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_ticket_delete'] . '" /></a>' : '', |
|
752 |
+ ); |
|
753 |
+ } |
|
754 |
+ |
|
755 |
+ $context['ticket_blocks'][$block_key]['tickets'][] = $new_block; |
|
756 |
+ |
|
757 |
+ $users[] = $row['id_member_started']; |
|
758 |
+ $users[] = $row['id_member_updated']; |
|
759 |
+ $users[] = $row['id_member_assigned']; |
|
760 |
+ } |
|
761 |
+ $smcFunc['db_free_result']($query); |
|
762 |
+ } |
|
763 |
+ |
|
764 |
+ $users = array_unique($users); |
|
765 |
+ if (!empty($users)) |
|
766 |
+ loadMemberData($users, false, 'minimal'); |
|
767 |
+ |
|
768 |
+ foreach ($context['ticket_blocks'] as $block_id => $block) |
|
769 |
+ { |
|
770 |
+ if (empty($block['tickets'])) |
|
771 |
+ continue; |
|
772 |
+ |
|
773 |
+ foreach ($block['tickets'] as $tid => $ticket) |
|
774 |
+ { |
|
775 |
+ // Set up names and profile links for topic starter |
|
776 |
+ if (!empty($user_profile[$ticket['starter']['id']])) |
|
777 |
+ { |
|
778 |
+ // We found the name, so let's use their current name and profile link |
|
779 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name'] = $user_profile[$ticket['starter']['id']]['real_name']; |
|
780 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = shd_profile_link($user_profile[$ticket['starter']['id']]['real_name'], $ticket['starter']['id']); |
|
781 |
+ } |
|
782 |
+ else |
|
783 |
+ // We didn't, so keep using the name we found previously and don't make an actual link |
|
784 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name']; |
|
785 |
+ |
|
786 |
+ // Set up names and profile links for assigned user |
|
787 |
+ if ($ticket['assigned']['id'] == 0 || empty($user_profile[$ticket['assigned']['id']])) |
|
788 |
+ { |
|
789 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $txt['shd_unassigned']; |
|
790 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = '<span class="error">' . $txt['shd_unassigned'] . '</span>'; |
|
791 |
+ } |
|
792 |
+ else |
|
793 |
+ { |
|
794 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $user_profile[$ticket['assigned']['id']]['real_name']; |
|
795 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = shd_profile_link($user_profile[$ticket['assigned']['id']]['real_name'], $ticket['assigned']['id']); |
|
796 |
+ } |
|
797 |
+ |
|
798 |
+ // And last respondent |
|
799 |
+ if ($ticket['respondent']['id'] == 0 || empty($user_profile[$ticket['respondent']['id']])) |
|
800 |
+ { |
|
801 |
+ // Didn't find the name, so reuse what we have |
|
802 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name']; |
|
803 |
+ } |
|
804 |
+ else |
|
805 |
+ { |
|
806 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name'] = $user_profile[$ticket['respondent']['id']]['real_name']; |
|
807 |
+ $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = shd_profile_link($user_profile[$ticket['respondent']['id']]['real_name'], $ticket['respondent']['id']); |
|
808 |
+ } |
|
809 |
+ } |
|
810 |
+ } |
|
811 |
+ |
|
812 |
+ foreach ($context['ticket_blocks'] as $block_id => $block) |
|
813 |
+ { |
|
814 |
+ if (empty($block['display']) || (empty($block['count']) && !$block['required'] && empty($block['collapsed']))) |
|
815 |
+ unset($context['ticket_blocks'][$block_id]); |
|
816 |
+ } |
|
817 |
+ |
|
818 |
+ $base_url = ''; |
|
819 |
+ foreach ($context['ticket_blocks'] as $block_id => $block) |
|
820 |
+ { |
|
821 |
+ if ($block['sort']['add_link']) |
|
822 |
+ $base_url .= $block['sort']['link_bits'][$block['sort']['item']]; |
|
823 |
+ } |
|
824 |
+ |
|
825 |
+ if ($_REQUEST['sa'] != 'viewblock') |
|
826 |
+ { |
|
827 |
+ foreach ($context['ticket_blocks'] as $block_id => $block) |
|
828 |
+ { |
|
829 |
+ $url_fragment = $base_url; |
|
830 |
+ |
|
831 |
+ foreach ($block_list as $block_item) |
|
832 |
+ { |
|
833 |
+ if ($block_item == $block_id) |
|
834 |
+ $url_fragment .= ';st_' . $block_item . '=%1$d'; |
|
835 |
+ elseif (!empty($context['ticket_blocks'][$block_item]['start'])) |
|
836 |
+ $url_fragment .= ';st_' . $block_item . '=' . $context['ticket_blocks'][$block_item]['start']; |
|
837 |
+ } |
|
838 |
+ |
|
839 |
+ $context['start'] = $context['ticket_blocks'][$block_id]['start']; |
|
840 |
+ $context['ticket_blocks'][$block_id]['page_index'] = shd_no_expand_pageindex($scripturl . $primary_url . $url_fragment . '#shd_block_' . $block_id, $context['start'], $block['count'], $context['items_per_page'], true); |
|
841 |
+ } |
|
842 |
+ } |
|
843 |
+} |
|
844 |
+ |
|
845 |
+/** |
|
846 |
+ * Return the list of columns that is applicable to a given block. |
|
847 |
+ * |
|
848 |
+ * In order to centralise the list of actions to be displayed in a block, and in its counterpart that displays all the values, |
|
849 |
+ * the lists of columns per block is kept here. |
|
850 |
+ * |
|
851 |
+ * @param string $block The block we are calling from: |
|
852 |
+ * - assigned: assigned to me |
|
853 |
+ * - new: new tickets |
|
854 |
+ * - staff: pending staff |
|
855 |
+ * - user_staff: pending with user (staff view) |
|
856 |
+ * - user_user: pending with user (user view) |
|
857 |
+ * - closed: resolved tickets |
|
858 |
+ * - recycled: deleted tickets |
|
859 |
+ * - withdeleted: tickets with deleted replies |
|
860 |
+ * |
|
861 |
+ * @return array An indexed array of the columns in the order they should be displayed. |
|
862 |
+ * @see shd_main_helpdesk() |
|
863 |
+ * @see shd_closed_tickets() |
|
864 |
+ * @see shd_recycle_bin() |
|
865 |
+ * @since 1.0 |
|
866 |
+*/ |
|
867 |
+function shd_get_block_columns($block) |
|
868 |
+{ |
|
869 |
+ switch ($block) |
|
870 |
+ { |
|
871 |
+ case 'assigned': |
|
872 |
+ return array( |
|
873 |
+ 'ticket_id', |
|
874 |
+ 'ticket_name', |
|
875 |
+ 'starting_user', |
|
876 |
+ 'replies', |
|
877 |
+ 'status', |
|
878 |
+ 'urgency', |
|
879 |
+ 'updated', |
|
880 |
+ 'actions', |
|
881 |
+ ); |
|
882 |
+ case 'new': |
|
883 |
+ return array( |
|
884 |
+ 'ticket_id', |
|
885 |
+ 'ticket_name', |
|
886 |
+ 'starting_user', |
|
887 |
+ 'assigned', |
|
888 |
+ 'urgency', |
|
889 |
+ 'updated', |
|
890 |
+ 'actions', |
|
891 |
+ ); |
|
892 |
+ case 'staff': |
|
893 |
+ return array( |
|
894 |
+ 'ticket_id', |
|
895 |
+ 'ticket_name', |
|
896 |
+ 'starting_user', |
|
897 |
+ 'replies', |
|
898 |
+ 'assigned', |
|
899 |
+ 'urgency', |
|
900 |
+ 'updated', |
|
901 |
+ 'actions', |
|
902 |
+ ); |
|
903 |
+ case 'user_staff': |
|
904 |
+ return array( |
|
905 |
+ 'ticket_id', |
|
906 |
+ 'ticket_name', |
|
907 |
+ 'starting_user', |
|
908 |
+ 'last_reply', |
|
909 |
+ 'replies', |
|
910 |
+ 'urgency', |
|
911 |
+ 'updated', |
|
912 |
+ 'actions', |
|
913 |
+ ); |
|
914 |
+ case 'user_user': |
|
915 |
+ return array( |
|
916 |
+ 'ticket_id', |
|
917 |
+ 'ticket_name', |
|
918 |
+ 'last_reply', |
|
919 |
+ 'replies', |
|
920 |
+ 'urgency', |
|
921 |
+ 'updated', |
|
922 |
+ 'actions', |
|
923 |
+ ); |
|
924 |
+ case 'closed': |
|
925 |
+ return array( |
|
926 |
+ 'ticket_id', |
|
927 |
+ 'ticket_name', |
|
928 |
+ 'starting_user', |
|
929 |
+ 'replies', |
|
930 |
+ 'updated', |
|
931 |
+ 'actions', |
|
932 |
+ ); |
|
933 |
+ case 'recycled': |
|
934 |
+ return array( |
|
935 |
+ 'ticket_id', |
|
936 |
+ 'ticket_name', |
|
937 |
+ 'starting_user', |
|
938 |
+ 'allreplies', |
|
939 |
+ 'assigned', |
|
940 |
+ 'updated', |
|
941 |
+ 'actions', |
|
942 |
+ ); |
|
943 |
+ case 'withdeleted': |
|
944 |
+ return array( |
|
945 |
+ 'ticket_id', |
|
946 |
+ 'ticket_name', |
|
947 |
+ 'starting_user', |
|
948 |
+ 'allreplies', |
|
949 |
+ 'assigned', |
|
950 |
+ 'updated', |
|
951 |
+ 'actions', |
|
952 |
+ ); |
|
953 |
+ default: |
|
954 |
+ return array(); |
|
955 |
+ } |
|
956 |
+} |
|
957 |
+?> |
|
0 | 958 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,702 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: Subs-SimpleDesk.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles key functions for SimpleDesk that can be called on every page load, such as the |
|
22 |
+ * custom query function to handle ticket visibility, the counter for active tickets in the menu header, or the action log. |
|
23 |
+ * |
|
24 |
+ * @package subs |
|
25 |
+ * @since 1.0 |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Query wrapper around $smcFunc['db_query'] for helpdesk specific operations. |
|
33 |
+ * |
|
34 |
+ * This function provides a basic wrapper around SMF's internal $smcFunc['db_query'] function, adding the parameter {query_see_ticket} |
|
35 |
+ * to it, specifically so that ticket visibility can be enforced in a query without being aware of the specific rules for the user. |
|
36 |
+ * |
|
37 |
+ * If not previously loaded, user permissions are loaded with {@link shd_load_user_perms()}. |
|
38 |
+ * |
|
39 |
+ * @param string $identifier SMF-style query identifier for database backend-specific replacements |
|
40 |
+ * @param string $db_string Standard SMF 2.0 style database query, including {query_see_ticket} if appropriate |
|
41 |
+ * @param array $db_values Standard SMF 2.0 style hash map of parameters to inject into the query |
|
42 |
+ * @param resource $connection A database connection variable, if supplied, to override the one used by SMF by default |
|
43 |
+ * @return resource Standard database query resource, suitable for processing with other $smcFunc['db_*'] functions |
|
44 |
+ * |
|
45 |
+ * @see shd_load_user_perms() |
|
46 |
+ * @since 1.0 |
|
47 |
+*/ |
|
48 |
+function shd_db_query($identifier, $db_string, $db_values = array(), $connection = null) |
|
49 |
+{ |
|
50 |
+ global $user_info, $smcFunc; |
|
51 |
+ |
|
52 |
+ if (!isset($user_info['query_see_ticket'])) |
|
53 |
+ shd_load_user_perms(); |
|
54 |
+ |
|
55 |
+ $replacements = array( |
|
56 |
+ '{query_see_ticket}' => $user_info['query_see_ticket'], |
|
57 |
+ ); |
|
58 |
+ |
|
59 |
+ $db_string = str_replace(array_keys($replacements), array_values($replacements), $db_string); |
|
60 |
+ $db_values['user_info_id'] = $user_info['id']; |
|
61 |
+ |
|
62 |
+ return $smcFunc['db_query']($identifier, $db_string, $db_values, $connection); |
|
63 |
+} |
|
64 |
+ |
|
65 |
+/** |
|
66 |
+ * Defines user permissions, most importantly concerning ticket visibility |
|
67 |
+ * |
|
68 |
+ * Populates specific parameters in $user_info, mostly to add {} abstract variables in $smcFunc['db_query'] data calls. |
|
69 |
+ * The foremost one of these is {query_see_ticket}, an SQL clause constructed to ensure ticket visibility is maintained given the |
|
70 |
+ * active user's permission set. |
|
71 |
+ * |
|
72 |
+ * @see shd_db_query() |
|
73 |
+ * @since 1.0 |
|
74 |
+*/ |
|
75 |
+function shd_load_user_perms() |
|
76 |
+{ |
|
77 |
+ global $user_info; |
|
78 |
+ if ($user_info['is_admin']) |
|
79 |
+ $user_info['query_see_ticket'] = '1=1'; |
|
80 |
+ elseif (shd_allowed_to('shd_view_ticket_any')) |
|
81 |
+ $user_info['query_see_ticket'] = shd_allowed_to('shd_view_ticket_private_any') ? '1=1' : ('(hdt.private = 0' . (shd_allowed_to('shd_view_ticket_private_own') ? ' OR (hdt.private = 1 AND hdt.id_member_started = {int:user_info_id}))' : ')')); |
|
82 |
+ elseif (shd_allowed_to('shd_view_ticket_own')) |
|
83 |
+ $user_info['query_see_ticket'] = 'hdt.id_member_started = {int:user_info_id}' . (shd_allowed_to('shd_view_ticket_private_own') ? '' : ' AND hdt.private = 0'); |
|
84 |
+ else |
|
85 |
+ $user_info['query_see_ticket'] = '1=0'; |
|
86 |
+ |
|
87 |
+ if (!shd_allowed_to('shd_access_recyclebin')) |
|
88 |
+ $user_info['query_see_ticket'] .= ' AND hdt.status != 6'; |
|
89 |
+} |
|
90 |
+ |
|
91 |
+/** |
|
92 |
+ * Defines the helpdesk menu item, including the number of active tickets to be displayed to the user. |
|
93 |
+ * |
|
94 |
+ * Identifies the number of tickets that a user might be interested in, and generates the menu text for the main menu |
|
95 |
+ * to include this; note that the value should be cached through SMF's functions. The cache is also clearable, through |
|
96 |
+ * the {@link shd_clear_active_tickets()} function. |
|
97 |
+ * |
|
98 |
+ * @return string A formatted string containing the language-specific version of "Helpdesk [x]" menu item with the x in bold |
|
99 |
+ * @see shd_clear_active_tickets() |
|
100 |
+ * @since 1.0 |
|
101 |
+*/ |
|
102 |
+function shd_get_active_tickets() |
|
103 |
+{ |
|
104 |
+ global $modSettings, $user_info, $smcFunc, $context, $txt; |
|
105 |
+ |
|
106 |
+ if (empty($txt['shd_helpdesk'])) // provide a last-ditch fallback in the event we can't even find the file; SimpleDesk.{language}.php should be loaded by now (falling back to english if lang-specific doesn't exist) |
|
107 |
+ $txt['shd_helpdesk'] = 'Helpdesk'; |
|
108 |
+ |
|
109 |
+ if (!$modSettings['helpdesk_active'] || $context['user']['is_guest']) |
|
110 |
+ return $txt['shd_helpdesk']; |
|
111 |
+ |
|
112 |
+ // Have we already run on this page? If so we already have the answer. |
|
113 |
+ if (!empty($context['active_tickets'])) |
|
114 |
+ return $txt['shd_helpdesk'] . $context['active_tickets']; |
|
115 |
+ |
|
116 |
+ // Figure out the status(es) that the ticket could be. Note that we have to use numeric values rather than our proper constants |
|
117 |
+ // because they are not declared at this point (only in the main helpdesk itself) |
|
118 |
+ if (shd_allowed_to('shd_staff')) |
|
119 |
+ $status = array(0, 1); // TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF (i.e. staff actually need to deal with these) |
|
120 |
+ else |
|
121 |
+ $status = array(2); // TICKET_STATUS_PENDING_USER (i.e. user actually needs to deal with this) |
|
122 |
+ |
|
123 |
+ // Can we get it from the cache? |
|
124 |
+ $temp = cache_get_data('shd_active_tickets_' . $user_info['id'], 180); |
|
125 |
+ if ($temp !== null) |
|
126 |
+ { |
|
127 |
+ list($context['active_tickets'], $context['active_tickets_raw']) = $temp; |
|
128 |
+ $context['menu_buttons']['helpdesk']['alttitle'] = $txt['shd_helpdesk'] . !empty($context['active_tickets_raw']) ? (' [' . $context['active_tickets_raw'] . ']') : ''; |
|
129 |
+ return $txt['shd_helpdesk'] . $context['active_tickets']; |
|
130 |
+ } |
|
131 |
+ |
|
132 |
+ $query = shd_db_query('', ' |
|
133 |
+ SELECT COUNT(id_ticket) |
|
134 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
135 |
+ WHERE {query_see_ticket} AND status IN ({array_int:status})', |
|
136 |
+ array( |
|
137 |
+ 'status' => $status, |
|
138 |
+ ) |
|
139 |
+ ); |
|
140 |
+ |
|
141 |
+ $context['active_tickets_raw'] = 0; |
|
142 |
+ |
|
143 |
+ $row = $smcFunc['db_fetch_row']($query); |
|
144 |
+ if (!empty($row[0])) |
|
145 |
+ { |
|
146 |
+ $context['menu_buttons']['helpdesk']['alttitle'] = $txt['shd_helpdesk'] . ' [' . $row[0] . ']'; |
|
147 |
+ $context['active_tickets'] = ' [<strong>' . $row[0] . '</strong>]'; |
|
148 |
+ $context['active_tickets_raw'] = $row[0]; // in case you want to do something funky in the theme later? |
|
149 |
+ } |
|
150 |
+ else |
|
151 |
+ $context['active_tickets'] = ''; |
|
152 |
+ |
|
153 |
+ cache_put_data('shd_active_tickets_' . $user_info['id'], array($context['active_tickets'], $context['active_tickets_raw']), 120); |
|
154 |
+ |
|
155 |
+ return $txt['shd_helpdesk'] . $context['active_tickets']; |
|
156 |
+} |
|
157 |
+ |
|
158 |
+/** |
|
159 |
+ * Clears the cache of active tickets for the menu item. |
|
160 |
+ * |
|
161 |
+ * {@link shd_get_active_tickets()} generates the number of active tickets for the user display, and caches it for 180 seconds |
|
162 |
+ * normally. This function clears the cache and should be called whenever any operation modifies the state of a ticket. |
|
163 |
+ * |
|
164 |
+ * @see shd_get_active_tickets() |
|
165 |
+ * @since 1.0 |
|
166 |
+*/ |
|
167 |
+function shd_clear_active_tickets($id = 0) |
|
168 |
+{ |
|
169 |
+ global $user_info; |
|
170 |
+ |
|
171 |
+ $members = shd_members_allowed_to('shd_staff'); |
|
172 |
+ if ($id != 0) |
|
173 |
+ $members[] = $id; |
|
174 |
+ |
|
175 |
+ $members[] = $user_info['id']; |
|
176 |
+ |
|
177 |
+ $members = array_unique($members); |
|
178 |
+ |
|
179 |
+ foreach ($members as $member) |
|
180 |
+ cache_put_data('shd_active_tickets_' . $member, null, 0); |
|
181 |
+} |
|
182 |
+ |
|
183 |
+/** |
|
184 |
+ * Adds an action to the helpdesk internal action log. |
|
185 |
+ * |
|
186 |
+ * This function deals with adding items to the action log maintained by the helpdesk. |
|
187 |
+ * |
|
188 |
+ * @param string $action Specifies the name of the action to log, which implies the image and language string (log_$action is |
|
189 |
+ * the name of the image, and $txt['shd_log_$action'] is the string used to express the action, as listed in |
|
190 |
+ * SimpleDesk-LogAction.english.php. |
|
191 |
+ * @param array $params This is a list of named parameters in a hash array to be used in the language string later. |
|
192 |
+ * |
|
193 |
+ * @see shd_load_action_log_entries() |
|
194 |
+ * @since 1.0 |
|
195 |
+*/ |
|
196 |
+function shd_log_action($action, $params) |
|
197 |
+{ |
|
198 |
+ global $smcFunc, $context, $user_info, $modSettings; |
|
199 |
+ |
|
200 |
+ if (!empty($modSettings['shd_disable_action_log'])) |
|
201 |
+ return; |
|
202 |
+ |
|
203 |
+ // Some parts of $params we will want in the main row for sorting + lookups later. Let's see if they're here. |
|
204 |
+ if (!empty($params['ticket'])) |
|
205 |
+ { |
|
206 |
+ $ticket_id = (int) $params['ticket']; |
|
207 |
+ if ($ticket_id == 0) |
|
208 |
+ trigger_error('log_action(): received data with non-numeric ticket', E_USER_NOTICE); |
|
209 |
+ else |
|
210 |
+ unset($params['ticket']); |
|
211 |
+ } |
|
212 |
+ else |
|
213 |
+ $ticket_id = 0; |
|
214 |
+ |
|
215 |
+ if (!empty($params['msg'])) |
|
216 |
+ { |
|
217 |
+ $msg_id = (int) $params['msg']; |
|
218 |
+ if ($msg_id == 0) |
|
219 |
+ trigger_error('log_action(): received data with non-numeric msg', E_USER_NOTICE); |
|
220 |
+ else |
|
221 |
+ unset($params['msg']); |
|
222 |
+ } |
|
223 |
+ else |
|
224 |
+ $msg_id = 0; |
|
225 |
+ |
|
226 |
+ $smcFunc['db_insert']('', |
|
227 |
+ '{db_prefix}helpdesk_log_action', |
|
228 |
+ array( |
|
229 |
+ 'log_time' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', 'id_ticket' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534', |
|
230 |
+ ), |
|
231 |
+ array( |
|
232 |
+ time(), $user_info['id'], $user_info['ip'], $action, $ticket_id, $msg_id, serialize($params), |
|
233 |
+ ), |
|
234 |
+ array('id_action') |
|
235 |
+ ); |
|
236 |
+} |
|
237 |
+ |
|
238 |
+/** |
|
239 |
+ * Determines if the current user can raise/lower the urgency of a ticket. |
|
240 |
+ * |
|
241 |
+ * This function identifies whether the current user can raise or lower the urgency of a ticket based on the current urgency |
|
242 |
+ * of the ticket and whether it is their ticket; this is used in the ticket display as well as the actions linked directly to |
|
243 |
+ * modifying urgency (both AJAXively and non AJAXively) |
|
244 |
+ * |
|
245 |
+ * @param int $urgency The current urgency of a ticket as an integer |
|
246 |
+ * @param bool $ticket_starter Whether the user in question is the starter of the ticket (instead of querying to establish that, |
|
247 |
+ * that detail should already be known to the calling function) |
|
248 |
+ * @param bool $closed Whether the ticket is currently closed or not |
|
249 |
+ * @param bool $deleted Whether the ticket is currently closed or not |
|
250 |
+ * |
|
251 |
+ * @see shd_urgency_change_noajax() |
|
252 |
+ * @since 1.0 |
|
253 |
+*/ |
|
254 |
+function shd_can_alter_urgency($urgency, $ticket_starter, $closed, $deleted) |
|
255 |
+{ |
|
256 |
+ global $user_info; |
|
257 |
+ |
|
258 |
+ $can_urgency = array( |
|
259 |
+ 'increase' => false, |
|
260 |
+ 'decrease' => false, |
|
261 |
+ ); |
|
262 |
+ |
|
263 |
+ if ($closed || $deleted) |
|
264 |
+ return $can_urgency; |
|
265 |
+ |
|
266 |
+ if (shd_allowed_to('shd_alter_urgency_any')) |
|
267 |
+ { |
|
268 |
+ if (shd_allowed_to('shd_alter_urgency_higher_any') || (shd_allowed_to('shd_alter_urgency_higher_own') && $ticket_starter == $user_info['id'])) |
|
269 |
+ $can_urgency = array( // can alter any urgency and can alter this one's higher urgency too |
|
270 |
+ 'increase' => ($urgency < TICKET_URGENCY_CRITICAL), |
|
271 |
+ 'decrease' => ($urgency > TICKET_URGENCY_LOW), |
|
272 |
+ ); |
|
273 |
+ else |
|
274 |
+ $can_urgency = array( // can alter any base urgency - just not this one's higher urgency |
|
275 |
+ 'increase' => ($urgency < TICKET_URGENCY_HIGH), |
|
276 |
+ 'decrease' => ($urgency > TICKET_URGENCY_LOW && $urgency < TICKET_URGENCY_VHIGH), |
|
277 |
+ ); |
|
278 |
+ } |
|
279 |
+ elseif (shd_allowed_to('shd_alter_urgency_own') && $ticket_starter == $user_info['id']) |
|
280 |
+ $can_urgency = array( // ok, so this is our ticket and we can change it |
|
281 |
+ 'increase' => ($urgency < (shd_allowed_to('shd_alter_urgency_higher_own') ? TICKET_URGENCY_CRITICAL : TICKET_URGENCY_HIGH)), |
|
282 |
+ 'decrease' => ($urgency > TICKET_URGENCY_LOW && $urgency <= (shd_allowed_to('shd_alter_urgency_higher_own') ? TICKET_URGENCY_CRITICAL : TICKET_URGENCY_VHIGH)), |
|
283 |
+ ); |
|
284 |
+ |
|
285 |
+ return $can_urgency; |
|
286 |
+} |
|
287 |
+ |
|
288 |
+/** |
|
289 |
+ * Queries the database to find the number of applicable tickets |
|
290 |
+ * |
|
291 |
+ * This function collects counts for the different states of tickets (new, with staff, with user, etc) of all the tickets |
|
292 |
+ * visible to the user, and returns a selection of that dataset based on the values provided to $status and $is_staff. |
|
293 |
+ * |
|
294 |
+ * @param string $status The relevant count of tickets to return: |
|
295 |
+ * <ul> |
|
296 |
+ * <li>'open': All tickets currently open that the user can see</li> |
|
297 |
+ * <li>'assigned': All tickets assigned to the current user</li> |
|
298 |
+ * <li>'new': All the new tickets that the user can see</li> |
|
299 |
+ * <li>'staff': All the tickets currently with staff (varies for staff vs user; user count here includes 'new' tickets)</li> |
|
300 |
+ * <li>'with_user': All the tickets pending user comment</li> |
|
301 |
+ * <li>'closed': All the tickets the user can see that are resolved</li> |
|
302 |
+ * <li>'recycled': All the tickets the user can see that are currently in the recycle bin</li> |
|
303 |
+ * <li>'withdeleted': All the tickets that have at least one deleted reply</li> |
|
304 |
+ * <li>'' or unspecified: Return the total of all tickets in the helpdesk (subject to visibility)</li> |
|
305 |
+ * </ul> |
|
306 |
+ * @param bool $is_staff If the user in question is staff or not. |
|
307 |
+ * |
|
308 |
+ * @return int Number of applicable tickets. |
|
309 |
+ * @since 1.0 |
|
310 |
+*/ |
|
311 |
+function shd_count_helpdesk_tickets($status = '', $is_staff = false) |
|
312 |
+{ |
|
313 |
+ global $smcFunc, $context; |
|
314 |
+ |
|
315 |
+ if (empty($context['ticket_count'])) |
|
316 |
+ { |
|
317 |
+ $context['ticket_count'] = array(); |
|
318 |
+ for ($i = 0; $i <= 6; $i++) |
|
319 |
+ $context['ticket_count'][$i] = 0; // set the count to zero for all known states |
|
320 |
+ |
|
321 |
+ $query = shd_db_query('', ' |
|
322 |
+ SELECT status, COUNT(status) AS tickets |
|
323 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
324 |
+ WHERE {query_see_ticket} |
|
325 |
+ GROUP BY status |
|
326 |
+ ORDER BY null', |
|
327 |
+ array() |
|
328 |
+ ); |
|
329 |
+ |
|
330 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
331 |
+ $context['ticket_count'][$row['status']] = $row['tickets']; |
|
332 |
+ |
|
333 |
+ $smcFunc['db_free_result']($query); |
|
334 |
+ |
|
335 |
+ $context['ticket_count']['assigned'] = 0; |
|
336 |
+ if (shd_allowed_to('shd_staff')) |
|
337 |
+ { |
|
338 |
+ $query = shd_db_query('', ' |
|
339 |
+ SELECT status, COUNT(status) AS tickets |
|
340 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
341 |
+ WHERE {query_see_ticket} |
|
342 |
+ AND id_member_assigned = {int:user} |
|
343 |
+ GROUP BY status |
|
344 |
+ ORDER BY null', |
|
345 |
+ array( |
|
346 |
+ 'user' => $context['user']['id'], |
|
347 |
+ ) |
|
348 |
+ ); |
|
349 |
+ |
|
350 |
+ while ($row = $smcFunc['db_fetch_assoc']($query)) |
|
351 |
+ { |
|
352 |
+ if (!in_array($row['status'], array(3, 6))) // not TICKET_STATUS_CLOSED or TICKET_STATUS_DELETE |
|
353 |
+ { |
|
354 |
+ $context['ticket_count']['assigned'] += $row['tickets']; |
|
355 |
+ $context['ticket_count'][$row['status']] -= $row['tickets']; |
|
356 |
+ } |
|
357 |
+ } |
|
358 |
+ |
|
359 |
+ $smcFunc['db_free_result']($query); |
|
360 |
+ } |
|
361 |
+ |
|
362 |
+ if (shd_allowed_to('shd_access_recyclebin')) |
|
363 |
+ { |
|
364 |
+ $query = shd_db_query('', ' |
|
365 |
+ SELECT COUNT(id_ticket) AS tickets |
|
366 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
367 |
+ WHERE {query_see_ticket} |
|
368 |
+ AND hdt.withdeleted = {int:has_deleted} |
|
369 |
+ AND hdt.status != {int:ticket_deleted}', |
|
370 |
+ array( |
|
371 |
+ 'has_deleted' => 1, // MSG_STATUS_DELETED |
|
372 |
+ 'ticket_deleted' => 6, // TICKET_STATUS_DELETED; we want all non deleted tickets with deleted replies |
|
373 |
+ ) |
|
374 |
+ ); |
|
375 |
+ list($count) = $smcFunc['db_fetch_row']($query); |
|
376 |
+ $smcFunc['db_free_result']($query); |
|
377 |
+ |
|
378 |
+ $context['ticket_count']['withdeleted'] = $count; |
|
379 |
+ } |
|
380 |
+ else |
|
381 |
+ $context['ticket_count']['withdeleted'] = 0; |
|
382 |
+ } |
|
383 |
+ |
|
384 |
+ switch($status) |
|
385 |
+ { |
|
386 |
+ case 'open': |
|
387 |
+ return ( |
|
388 |
+ $context['ticket_count'][0] + // _NEW |
|
389 |
+ $context['ticket_count'][1] + // _PENDING_STAFF |
|
390 |
+ $context['ticket_count'][2] + // _PENDING_USER |
|
391 |
+ $context['ticket_count'][4] + // _WITH_SUPERVISOR |
|
392 |
+ $context['ticket_count'][5] // _ESCALATED |
|
393 |
+ ); |
|
394 |
+ case 'assigned': |
|
395 |
+ return $context['ticket_count']['assigned']; |
|
396 |
+ case 'new': |
|
397 |
+ return $context['ticket_count'][0]; |
|
398 |
+ case 'staff': |
|
399 |
+ return $is_staff ? $context['ticket_count'][1] : ($context['ticket_count'][0] + $context['ticket_count'][1]); // both "new" and "with staff" should appear as 'with staff' to non staff |
|
400 |
+ case 'with_user': |
|
401 |
+ return $context['ticket_count'][2]; |
|
402 |
+ case 'closed': |
|
403 |
+ return $context['ticket_count'][3]; |
|
404 |
+ case 'recycled': |
|
405 |
+ return $context['ticket_count'][6]; |
|
406 |
+ case 'withdeleted': |
|
407 |
+ return $context['ticket_count']['withdeleted']; |
|
408 |
+ default: |
|
409 |
+ return array_sum($context['ticket_count']) - $context['ticket_count']['assigned']; |
|
410 |
+ } |
|
411 |
+} |
|
412 |
+ |
|
413 |
+/** |
|
414 |
+ * Attempts to load a given ticket's data. |
|
415 |
+ * |
|
416 |
+ * This function permission-checks, and throws appropriate errors if no ticket is specified either directly or through URL, |
|
417 |
+ * or if the ticket is not accessible either through deletion or lack of permissions. |
|
418 |
+ * |
|
419 |
+ * @param int $ticket The ticket to use; if none is specified, use the one from $_REQUEST['ticket'], which will have been processed |
|
420 |
+ * into $context['ticket_id'] if it is available. |
|
421 |
+ * |
|
422 |
+ * @return array A large hash map stating many ticket details |
|
423 |
+ * @since 1.0 |
|
424 |
+*/ |
|
425 |
+function shd_load_ticket($ticket = 0) |
|
426 |
+{ |
|
427 |
+ global $context, $smcFunc, $scripturl; |
|
428 |
+ |
|
429 |
+ // Make sure they set a ticket ID. |
|
430 |
+ if ($ticket == 0 && empty($context['ticket_id'])) |
|
431 |
+ fatal_lang_error('shd_no_ticket', false); |
|
432 |
+ |
|
433 |
+ // Get the ticket data. Note this implicitly checks perms too. |
|
434 |
+ $query = shd_db_query('', ' |
|
435 |
+ SELECT hdt.id_first_msg, hdt.id_last_msg, hdt.id_member_started, hdt.subject, hdt.urgency, hdt.status, |
|
436 |
+ hdt.num_replies, hdt.deleted_replies, hdt.private, hdtr.body, hdtr.id_member, hdtr.poster_time, |
|
437 |
+ hdtr.modified_time, hdtr.smileys_enabled, |
|
438 |
+ IFNULL(mem.real_name, hdtr.poster_name) AS starter_name, IFNULL(mem.id_member, 0) AS starter_id, hdtr.poster_ip AS starter_ip, |
|
439 |
+ IFNULL(ma.real_name, 0) AS assigned_name, IFNULL(ma.id_member, 0) AS assigned_id, |
|
440 |
+ IFNULL(mm.real_name, hdtr.modified_name) AS modified_name, IFNULL(mm.id_member, 0) AS modified_id |
|
441 |
+ FROM {db_prefix}helpdesk_tickets AS hdt |
|
442 |
+ INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_first_msg = hdtr.id_msg) |
|
443 |
+ LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member) |
|
444 |
+ LEFT JOIN {db_prefix}members AS ma ON (hdt.id_member_assigned = ma.id_member) |
|
445 |
+ LEFT JOIN {db_prefix}members AS mm ON (hdtr.modified_member = mm.id_member) |
|
446 |
+ WHERE {query_see_ticket} AND hdt.id_ticket = {int:ticket}', |
|
447 |
+ array( |
|
448 |
+ 'ticket' => $ticket == 0 ? $context['ticket_id'] : $ticket, |
|
449 |
+ ) |
|
450 |
+ ); |
|
451 |
+ |
|
452 |
+ if ($smcFunc['db_num_rows']($query) == 0) |
|
453 |
+ { |
|
454 |
+ $smcFunc['db_free_result']($query); |
|
455 |
+ fatal_lang_error('shd_no_ticket', false); |
|
456 |
+ } |
|
457 |
+ |
|
458 |
+ $ticketinfo = $smcFunc['db_fetch_assoc']($query); |
|
459 |
+ $smcFunc['db_free_result']($query); |
|
460 |
+ |
|
461 |
+ // Anything else we'll use a lot? |
|
462 |
+ $ticketinfo['is_own'] = ($context['user']['id'] == $ticketinfo['starter_id']); |
|
463 |
+ $ticketinfo['closed'] = $ticketinfo['status'] == TICKET_STATUS_CLOSED; |
|
464 |
+ $ticketinfo['deleted'] = $ticketinfo['status'] == TICKET_STATUS_DELETED; |
|
465 |
+ |
|
466 |
+ $ticketinfo['link_ip'] = shd_allowed_to('moderate_forum'); |
|
467 |
+ |
|
468 |
+ return $ticketinfo; |
|
469 |
+} |
|
470 |
+ |
|
471 |
+/** |
|
472 |
+ * Formats a string for bbcode and/or smileys. |
|
473 |
+ * |
|
474 |
+ * Formatting is done according to the supplied settings and the master administration settings. |
|
475 |
+ * |
|
476 |
+ * @param string $text Raw text with optional bbcode formatting |
|
477 |
+ * @param bool $smileys Whether smileys should be used; this is not an override to the master administration setting of |
|
478 |
+ * whether to use smileys or not, and that takes precedence. |
|
479 |
+ * @param string $cache If specified, this will provide the cache'd id that SMF should use to cache the output if it is suitably large. |
|
480 |
+ * |
|
481 |
+ * @return string Will return $text as processed for bbcode (if $modSettings['shd_allow_ticket_bbc'] permits) and smileys (if |
|
482 |
+ * $modSettings['shd_allow_ticket_smileys'] and $smileys permits) |
|
483 |
+ * @since 1.0 |
|
484 |
+*/ |
|
485 |
+function shd_format_text($text, $smileys = true, $cache = '') |
|
486 |
+{ |
|
487 |
+ global $modSettings; |
|
488 |
+ if (empty($modSettings['shd_allow_ticket_bbc'])) |
|
489 |
+ { |
|
490 |
+ if (!empty($modSettings['shd_allow_ticket_smileys']) && $smileys) |
|
491 |
+ parsesmileys($text); |
|
492 |
+ } |
|
493 |
+ else |
|
494 |
+ { |
|
495 |
+ // See what tagz we can haz. |
|
496 |
+ if (!empty($modSettings['shd_enabled_bbc'])) |
|
497 |
+ $enabled_tags = explode(',', $modSettings['shd_enabled_bbc']); |
|
498 |
+ else |
|
499 |
+ $enabled_tags = array(false); |
|
500 |
+ |
|
501 |
+ // wecanhazbbc |
|
502 |
+ $text = parse_bbc($text, (!empty($modSettings['shd_allow_ticket_smileys']) ? $smileys : false), $cache, $enabled_tags); |
|
503 |
+ } |
|
504 |
+ |
|
505 |
+ return $text; |
|
506 |
+} |
|
507 |
+ |
|
508 |
+/** |
|
509 |
+ * Determines if a user has a given permission within the system. |
|
510 |
+ * |
|
511 |
+ * All SimpleDesk-specific permissions should be checked with this function. Any other permission check that is not specifically |
|
512 |
+ * SimpleDesk-related should use allowedTo instead. |
|
513 |
+ * |
|
514 |
+ * @param mixed $permission A string or array of strings naming a permission or permissions that wish to be examined |
|
515 |
+ * @return bool True if any of the permission(s) outlined in $permission are true. |
|
516 |
+ * @see shd_is_allowed_to |
|
517 |
+ * @todo This function will likely be expanded to not use SMF's allowedTo function eventually, as its requirements will outgrow |
|
518 |
+ * or replace conventional SMF permissions. |
|
519 |
+ * @since 1.0 |
|
520 |
+*/ |
|
521 |
+function shd_allowed_to($permission) |
|
522 |
+{ |
|
523 |
+ return allowedTo($permission); |
|
524 |
+} |
|
525 |
+ |
|
526 |
+/** |
|
527 |
+ * Enforces a user having a given permission and returning to a fatal error message if not. |
|
528 |
+ * |
|
529 |
+ * All fatal-level SimpleDesk-specific permissions should be checked with this function. Any other permission check that is |
|
530 |
+ * not specifically SimpleDesk-related should use isAllowedTo instead. Note that this is a void function because should this |
|
531 |
+ * fail, SMF execution will be halted. |
|
532 |
+ * |
|
533 |
+ * @param mixed $permission A string or array of strings naming a permission or permissions that wish to be examined |
|
534 |
+ * @see shd_allowed_to |
|
535 |
+ * @todo This function will likely be expanded to not use SMF's allowedTo function eventually, as its requirements will outgrow |
|
536 |
+ * or replace conventional SMF permissions. |
|
537 |
+ * @since 1.0 |
|
538 |
+*/ |
|
539 |
+function shd_is_allowed_to($permission) |
|
540 |
+{ |
|
541 |
+ isAllowedTo($permission); |
|
542 |
+} |
|
543 |
+ |
|
544 |
+/** |
|
545 |
+ * Identifies all members who hold a given permission. |
|
546 |
+ * |
|
547 |
+ * Currently lists of staff are generated by users who hold shd_staff permission. This function identifies those users through |
|
548 |
+ * an internal lookup provided by SMF. |
|
549 |
+ * |
|
550 |
+ * @param mixed $permission A string naming a permission that members should hold. |
|
551 |
+ * @return array Array of zero or more user ids who hold the stated permission. |
|
552 |
+ * @see shd_allowed_to |
|
553 |
+ * @todo This function will likely be expanded to not use SMF's permissions eventually. |
|
554 |
+ * @since 1.0 |
|
555 |
+*/ |
|
556 |
+function shd_members_allowed_to($permission) |
|
557 |
+{ |
|
558 |
+ global $sourcedir; |
|
559 |
+ require_once($sourcedir . '/Subs-Members.php'); |
|
560 |
+ return membersAllowedTo($permission); |
|
561 |
+} |
|
562 |
+ |
|
563 |
+/** |
|
564 |
+ * Generates a profile link given user id and name. |
|
565 |
+ * |
|
566 |
+ * SMF itself has loadMemberData() and loadMemberContext to perform this act, however those two functions are much larger and more |
|
567 |
+ * complex than we need more often than not, especially when all we want/need is member name (and subsequently profile link) |
|
568 |
+ * |
|
569 |
+ * Since profile links should be based on the view profile permission, we will need to establish that. |
|
570 |
+ * |
|
571 |
+ * @param string $name The name to display. This should be a standard SMF type name, which means already sanitised for HTML. |
|
572 |
+ * @param int $id The numeric id of the user we are linking to. |
|
573 |
+ * |
|
574 |
+ * @return string Returns an HTML link to user profile if sufficient permission and both a name and id are supplied. Otherwise just the name is. |
|
575 |
+ * @since 1.0 |
|
576 |
+*/ |
|
577 |
+function shd_profile_link($name, $id = 0) |
|
578 |
+{ |
|
579 |
+ global $user_info, $scripturl; |
|
580 |
+ static $any = null; |
|
581 |
+ static $own = null; |
|
582 |
+ |
|
583 |
+ if ($any === null) |
|
584 |
+ { |
|
585 |
+ $any = allowedTo('profile_view_any'); // using allowedTo as it's an SMF permission, not an SD specific one |
|
586 |
+ $own = allowedTo('profile_view_own'); |
|
587 |
+ } |
|
588 |
+ |
|
589 |
+ if (empty($id)) |
|
590 |
+ return $name; |
|
591 |
+ elseif ($any || ($own && $id == $user_info['id'])) |
|
592 |
+ return '<a href="' . $scripturl . '?action=profile;u=' . $id . '">' . $name . '</a>'; |
|
593 |
+ else |
|
594 |
+ return $name; |
|
595 |
+} |
|
596 |
+ |
|
597 |
+/** |
|
598 |
+ * Establishes the next change of status of a ticket. |
|
599 |
+ * |
|
600 |
+ * Tickets invariably have multiple changes of status during their life. All actions that could change |
|
601 |
+ * a ticket's status should call here, even if it is a straight forward, one-route-only change of status |
|
602 |
+ * since it is possible we could end up giving the user a choice one day over how statuses work, so |
|
603 |
+ * we should route everything through here all the time. |
|
604 |
+ * |
|
605 |
+ * @param string $action (required), represents the action carried out by the calling function |
|
606 |
+ * Known values: new, resolve, unresolve, deleteticket, restoreticket, deletereply, restorereply, reply, merge, topictoticket (new is default) |
|
607 |
+ * @param int $starter_id Numeric id of the ticket's starter (should be provided) |
|
608 |
+ * @param int $replier_id Numeric id of the ticket's last reply author (should be provided) |
|
609 |
+ * @param int $replies Number of replies in the ticket (should be provided) |
|
610 |
+ * |
|
611 |
+ * @return int Returns an integer value that corresponds to the ticket's status, relating to one of the TICKET_STATUS states. |
|
612 |
+ * @since 1.0 |
|
613 |
+*/ |
|
614 |
+function shd_determine_status($action, $starter_id = 0, $replier_id = 0, $replies = -1) |
|
615 |
+{ |
|
616 |
+ $known_states = array( |
|
617 |
+ 'new', |
|
618 |
+ 'resolve', |
|
619 |
+ 'unresolve', |
|
620 |
+ 'deleteticket', |
|
621 |
+ 'restoreticket', |
|
622 |
+ 'deletereply', |
|
623 |
+ 'restorereply', |
|
624 |
+ 'reply', |
|
625 |
+ 'topictoticket', |
|
626 |
+ ); |
|
627 |
+ |
|
628 |
+ if (!in_array($action, $known_states)) |
|
629 |
+ $action = 'new'; |
|
630 |
+ |
|
631 |
+ switch ($action) |
|
632 |
+ { |
|
633 |
+ case 'new': |
|
634 |
+ return TICKET_STATUS_NEW; // it's a new ticket, what more can I say? |
|
635 |
+ case 'resolve': |
|
636 |
+ return TICKET_STATUS_CLOSED; // yup, all done |
|
637 |
+ case 'deleteticket': |
|
638 |
+ return TICKET_STATUS_DELETED; // bye bye |
|
639 |
+ case 'merge': // used in handling deleted replies |
|
640 |
+ case 'deletereply': |
|
641 |
+ case 'restorereply': |
|
642 |
+ case 'unresolve': |
|
643 |
+ case 'restoreticket': |
|
644 |
+ case 'reply': |
|
645 |
+ case 'topictoticket': |
|
646 |
+ if ($replies == 0) |
|
647 |
+ return TICKET_STATUS_NEW; |
|
648 |
+ else |
|
649 |
+ { |
|
650 |
+ $staff = shd_members_allowed_to('shd_staff'); |
|
651 |
+ if (in_array($replier_id, $staff)) |
|
652 |
+ $new_status = $starter_id == $replier_id ? TICKET_STATUS_PENDING_STAFF : TICKET_STATUS_PENDING_USER; // i.e. if they're staff but it's their own ticket they're replying to, it's not with user. |
|
653 |
+ else |
|
654 |
+ $new_status = TICKET_STATUS_PENDING_STAFF; |
|
655 |
+ |
|
656 |
+ return $new_status; |
|
657 |
+ } |
|
658 |
+ } |
|
659 |
+} |
|
660 |
+ |
|
661 |
+/** |
|
662 |
+ * Wrapper function for constructPageIndex to forcibly block the extensible ... item in page indexes |
|
663 |
+ * |
|
664 |
+ * SimpleDesk uses SMF's core page index function in numerous places, but unlike SMF, it often places it in containers |
|
665 |
+ * that have backgrounds driven by menu_block.png, meaning that they are often fixed in height. Under some circumstances |
|
666 |
+ * layout can be broken, so this function forcibly ensures the block can never expand to force wrapping. |
|
667 |
+ * |
|
668 |
+ * @param string $base_url Form of URL pageindex links should take, using $1%d to represent the start point identifier. |
|
669 |
+ * @param int &$start Position to start. If not a multiple of the number per page, it will be forced to become a multiple. |
|
670 |
+ * @param int $max_value Number of items in total to paginate for. |
|
671 |
+ * @param int $num_per_page Number of items to be shown on a page. |
|
672 |
+ * @param bool $flexible_start Whether a more flexible % option is to be used in the base URL. |
|
673 |
+ * |
|
674 |
+ * @return string The constructed page index, without Javascript expander(s). |
|
675 |
+ * @since 1.0 |
|
676 |
+*/ |
|
677 |
+function shd_no_expand_pageindex($base_url, &$start, $max_value, $num_per_page, $flexible_start = false) |
|
678 |
+{ |
|
679 |
+ return preg_replace('~<span([^<]+)~i', '<span style="font-weight: bold;"> ... ', constructPageIndex($base_url, $start, $max_value, $num_per_page, $flexible_start)); |
|
680 |
+} |
|
681 |
+ |
|
682 |
+/** |
|
683 |
+ * Wrapper for loadLanguage to ensure English language files are always loaded regardless of user language settings as a fallback |
|
684 |
+ * |
|
685 |
+ * As of 2.0 RC2, there is detection code in SMF to ensure the Modifications language file is always loaded, but the same detection is not applied to all language files. This ensures it will be for SD files. |
|
686 |
+ * |
|
687 |
+ * @param string $langfile Name of a language file to load, typically SimpleDesk prefixed, though could be used for any SMF language file. |
|
688 |
+ * @since 1.1 |
|
689 |
+*/ |
|
690 |
+function shd_load_language($langfile) |
|
691 |
+{ |
|
692 |
+ global $modSettings, $user_info; |
|
693 |
+ if (empty($modSettings['disable_language_fallback'])) |
|
694 |
+ { |
|
695 |
+ $cur_language = isset($user_info['language']) ? $user_info['language'] : $language; |
|
696 |
+ if ($cur_language !== 'english') |
|
697 |
+ loadLanguage($langfile, 'english', false); |
|
698 |
+ } |
|
699 |
+ loadLanguage($langfile); |
|
700 |
+} |
|
701 |
+ |
|
702 |
+?> |
|
0 | 703 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,184 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: Subs-SimpleDeskAdmin.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file deals with some of the items required by the helpdesk, but are primarily supporting |
|
22 |
+ * functions; they're not the principle functions that drive the admin area. |
|
23 |
+ * |
|
24 |
+ * @package subs |
|
25 |
+ * @since 1.0 |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+/** |
|
32 |
+ * Load the items from the helpdesk action log |
|
33 |
+ * |
|
34 |
+ * It is subject to given parameters (start, number of items, order/sorting), parses the language strings and adds the |
|
35 |
+ * parameter information provided. |
|
36 |
+ * |
|
37 |
+ * @param int $start Number of items into the log to start (for pagination) |
|
38 |
+ * @param int $items_per_page How many items to load |
|
39 |
+ * @param string $sort SQL clause to state which column(s) to order the data by |
|
40 |
+ * @param string $order SQL clause to state whether the order is ascending or descending |
|
41 |
+ * |
|
42 |
+ * @return array A hash array of the log items, with the auto-incremented id being the key: |
|
43 |
+ * <ul> |
|
44 |
+ * <li>id: Numeric identifier of the log item</li> |
|
45 |
+ * <li>time: Formatted time of the event (as per usual for SMF, formatted for user's timezone)</li> |
|
46 |
+ * <li>member: hash array: |
|
47 |
+ * <ul> |
|
48 |
+ * <li>id: Id of the user that committed the action</li> |
|
49 |
+ * <li>name: Name of the user</li> |
|
50 |
+ * <li>link: Link to the profile of the user that committed the action</li> |
|
51 |
+ * <li>ip: User IP address recorded when the action was carried out</li> |
|
52 |
+ * <li>group: Name of the group of the user (uses primary group, failing that post count group)</li> |
|
53 |
+ * </ul> |
|
54 |
+ * </li> |
|
55 |
+ * <li>action: Raw name of the action (for use with collecting the image later)</li> |
|
56 |
+ * <li>id_ticket: Numeric id of the ticket this action refers to</li> |
|
57 |
+ * <li>id_msg: Numeric id of the individual reply this action refers to</li> |
|
58 |
+ * <li>extra: Array of extra parameters for the log action</li> |
|
59 |
+ * <li>action_text: Formatted text of the log item (parsed with parameters)</li> |
|
60 |
+ * </ul> |
|
61 |
+ * |
|
62 |
+ * @see shd_log_action() |
|
63 |
+ * @see shd_count_action_log_entries() |
|
64 |
+ * @since 1.0 |
|
65 |
+*/ |
|
66 |
+function shd_load_action_log_entries($start, $items_per_page, $sort, $order) |
|
67 |
+{ |
|
68 |
+ global $smcFunc, $txt, $scripturl, $context; |
|
69 |
+ |
|
70 |
+ // Load languages incase they aren't there (Read: ticket-specific logs) |
|
71 |
+ shd_load_language('SimpleDeskLogAction'); |
|
72 |
+ shd_load_language('SimpleDeskAdmin'); |
|
73 |
+ |
|
74 |
+ // Without further screaming and waving, fetch the actions. |
|
75 |
+ $request = shd_db_query('',' |
|
76 |
+ SELECT la.id_action, la.log_time, la.id_member, la.ip, la.action, la.id_ticket, la.id_msg, la.extra, |
|
77 |
+ mem.real_name, mg.group_name |
|
78 |
+ FROM {db_prefix}helpdesk_log_action AS la |
|
79 |
+ LEFT JOIN {db_prefix}members AS mem ON(mem.id_member = la.id_member) |
|
80 |
+ LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END) |
|
81 |
+ ORDER BY {raw:sort} {raw:order} |
|
82 |
+ LIMIT {int:start}, {int:items_per_page}', |
|
83 |
+ array( |
|
84 |
+ 'reg_group_id' => 0, |
|
85 |
+ 'sort' => $sort, |
|
86 |
+ 'start' => $start, |
|
87 |
+ 'items_per_page' => $items_per_page, |
|
88 |
+ 'order' => $order, |
|
89 |
+ ) |
|
90 |
+ ); |
|
91 |
+ |
|
92 |
+ $actions = array(); |
|
93 |
+ |
|
94 |
+ while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
95 |
+ { |
|
96 |
+ $row['extra'] = @unserialize($row['extra']); |
|
97 |
+ $row['extra'] = is_array($row['extra']) ? $row['extra'] : array(); |
|
98 |
+ |
|
99 |
+ $actions[$row['id_action']] = array( |
|
100 |
+ 'id' => $row['id_action'], |
|
101 |
+ 'time' => timeformat($row['log_time']), |
|
102 |
+ 'member' => array( |
|
103 |
+ 'id' => $row['id_member'], |
|
104 |
+ 'name' => $row['real_name'], |
|
105 |
+ 'link' => shd_profile_link($row['real_name'], $row['id_member']), |
|
106 |
+ 'ip' => !empty($row['ip']) ? $row['ip'] : $txt['shd_admin_actionlog_unknown'], |
|
107 |
+ 'group' => $row['group_name'], |
|
108 |
+ ), |
|
109 |
+ 'action' => $row['action'], |
|
110 |
+ 'id_ticket' => $row['id_ticket'], |
|
111 |
+ 'id_msg' => $row['id_msg'], |
|
112 |
+ 'extra' => $row['extra'], |
|
113 |
+ 'action_text' => '', |
|
114 |
+ 'action_icon' => 'log_' . $row['action'] . '.png', |
|
115 |
+ 'can_remove' => $row['log_time'] < $context['waittime'], |
|
116 |
+ ); |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ // Do some formatting of the action string. |
|
120 |
+ foreach ($actions as $k => $action) |
|
121 |
+ { |
|
122 |
+ if (empty($actions[$k]['action_text'])) |
|
123 |
+ $actions[$k]['action_text'] = isset($txt['shd_log_' . $action['action']]) ? $txt['shd_log_' . $action['action']] : $action['action']; |
|
124 |
+ |
|
125 |
+ $actions[$k]['action_text'] = str_replace('{scripturl}', $scripturl, $actions[$k]['action_text']); |
|
126 |
+ |
|
127 |
+ if (isset($action['extra']['subject'])) |
|
128 |
+ { |
|
129 |
+ $actions[$k]['action_text'] = str_replace('{ticket}', $actions[$k]['id_ticket'], $actions[$k]['action_text']); |
|
130 |
+ $actions[$k]['action_text'] = str_replace('{msg}', $actions[$k]['id_msg'], $actions[$k]['action_text']); |
|
131 |
+ |
|
132 |
+ if (isset($actions[$k]['extra']['subject'])) |
|
133 |
+ $actions[$k]['action_text'] = str_replace('{subject}', $actions[$k]['extra']['subject'], $actions[$k]['action_text']); |
|
134 |
+ |
|
135 |
+ if (isset($actions[$k]['extra']['urgency'])) |
|
136 |
+ $actions[$k]['action_text'] = str_replace('{urgency}', $txt['shd_urgency_' . $actions[$k]['extra']['urgency']], $actions[$k]['action_text']); |
|
137 |
+ } |
|
138 |
+ if (isset($action['extra']['user_name'])) |
|
139 |
+ { |
|
140 |
+ $actions[$k]['action_text'] = str_replace('{profile_link}', shd_profile_link($actions[$k]['extra']['user_name'], (isset($actions[$k]['extra']['user_id']) ? $actions[$k]['extra']['user_id'] : 0)), $actions[$k]['action_text']); |
|
141 |
+ $actions[$k]['action_text'] = str_replace('{user_name}', $actions[$k]['extra']['user_name'], $actions[$k]['action_text']); |
|
142 |
+ } |
|
143 |
+ if (isset($action['extra']['user_id'])) |
|
144 |
+ $actions[$k]['action_text'] = str_replace('{user_id}', $actions[$k]['extra']['user_id'], $actions[$k]['action_text']); |
|
145 |
+ if (isset($actions[$k]['extra']['board_name'])) |
|
146 |
+ $actions[$k]['action_text'] = str_replace('{board_name}', $actions[$k]['extra']['board_name'], $actions[$k]['action_text']); |
|
147 |
+ if (isset($actions[$k]['extra']['board_id'])) |
|
148 |
+ $actions[$k]['action_text'] = str_replace('{board_id}', $actions[$k]['extra']['board_id'], $actions[$k]['action_text']); |
|
149 |
+ } |
|
150 |
+ return $actions; |
|
151 |
+} |
|
152 |
+ |
|
153 |
+/** |
|
154 |
+ * Returns the total number of items in the helpdesk log. |
|
155 |
+ * |
|
156 |
+ * This function gets the total number of items logged in the helpdesk log, for the purposes of establishing the number of |
|
157 |
+ * pages there should be in the page-index. |
|
158 |
+ * |
|
159 |
+ * @return int Number of entries in the helpdesk action log table. |
|
160 |
+ * @see shd_load_action_log_entries() |
|
161 |
+ * @since 1.0 |
|
162 |
+*/ |
|
163 |
+function shd_count_action_log_entries() |
|
164 |
+{ |
|
165 |
+ global $smcFunc; |
|
166 |
+ |
|
167 |
+ // Without further screaming and waving, fetch the actions. |
|
168 |
+ $request = shd_db_query('',' |
|
169 |
+ SELECT COUNT(*) |
|
170 |
+ FROM {db_prefix}helpdesk_log_action AS la |
|
171 |
+ LEFT JOIN {db_prefix}members AS mem ON(mem.id_member = la.id_member) |
|
172 |
+ LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END)', |
|
173 |
+ array( |
|
174 |
+ 'reg_group_id' => 0, |
|
175 |
+ ) |
|
176 |
+ ); |
|
177 |
+ |
|
178 |
+ list ($entry_count) = $smcFunc['db_fetch_row']($request); |
|
179 |
+ $smcFunc['db_free_result']($request); |
|
180 |
+ |
|
181 |
+ return $entry_count; |
|
182 |
+} |
|
183 |
+ |
|
184 |
+?> |
... | ... |
@@ -0,0 +1,513 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: Subs-SimpleDeskPost.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This file handles probably the two most critical functions in SimpleDesk: the one that adds new posts to the database |
|
22 |
+ * and one that saves updated posts; also contains miscellaneous code that applies generally in posting. |
|
23 |
+ * |
|
24 |
+ * @package subs |
|
25 |
+ * @since 1.0 |
|
26 |
+ */ |
|
27 |
+ |
|
28 |
+if (!defined('SMF')) |
|
29 |
+ die('Hacking attempt...'); |
|
30 |
+ |
|
31 |
+ |
|
32 |
+/** |
|
33 |
+ * Creates a new ticket or reply in the database. |
|
34 |
+ * |
|
35 |
+ * This function handles all of the creation of posts and tickets within SimpleDesk, even with respect to managing tickets spawned |
|
36 |
+ * from forum topics being moved, as well as newly deleted tickets (formed as a split when replies are deleted). New tickets' contents |
|
37 |
+ * as well as replies to tickets generally hold the same format. |
|
38 |
+ * |
|
39 |
+ * All three parameters are by <b>reference</b> meaning they WILL be updated if things change. Note that this function |
|
40 |
+ * is not validating that they are sensible values; it is up to the calling function to ascertain that. |
|
41 |
+ * |
|
42 |
+ * @param array &$msgOptions A hash array by reference, containing details of the post you wish to add. |
|
43 |
+ * <ul> |
|
44 |
+ * <li>id: Not required on input (and is ignored) - and will be overwritten with the new message id when the function completes.</li> |
|
45 |
+ * <li>body: Required string, the principle body content of the message to post. Assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and preparsecode)</li> |
|
46 |
+ * <li>smileys_enabled: Optional, boolean denoting whether smileys should be active on this post; defaults to false</li> |
|
47 |
+ * <li>time: Optional, timestamp of the post. If omitted, time() will be used instead (for "now" based on server clock)</li> |
|
48 |
+ * <li>modified: Optional, hash array containing items relating to modification (if 'modified' key exists, all of these should be set) |
|
49 |
+ * <ul> |
|
50 |
+ * <li> time: Unsigned int timestamp of the change</li> |
|
51 |
+ * <li> name: String; user name of the user making the change; if omitted, modified will be ignored</li> |
|
52 |
+ * <li> id: Unsigned int user id of the user making the change; if not provided, id MUST be. If id isn't, or it doesn't exist, modified will be ignored entirely</li> |
|
53 |
+ * </ul> |
|
54 |
+ * </li> |
|
55 |
+ * <li> attachments: Optional, array of attachment ids that need attaching to this message; if omitted no changes will occur |
|
56 |
+ * </ul> |
|
57 |
+ * |
|
58 |
+ * @param array &$ticketOptions A hash array by reference, containing details of the ticket as a whole. |
|
59 |
+ * <ul> |
|
60 |
+ * <li>id: Required if replying to a ticket, 0 if a new ticket (will default to 0 if not specified)</li> |
|
61 |
+ * <li>mark_as_read: Optional boolean, whether to mark the ticket as read by the person posting it ($posterOptions['id'] is required to use this)</li> |
|
62 |
+ * <li>subject: Semi-optional string with the new subject in; required for a new ticket, ignored if adding a reply. If set, assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and strtr)</li> |
|
63 |
+ * <li>private: Semi-optional boolean with ticket privacy (true = private); required for a new ticket, ignored if adding a reply.</li> |
|
64 |
+ * <li>status: Integer to denote new status of the ticket, defaults to TICKET_STATUS_NEW. Calling function to determine new status.</li> |
|
65 |
+ * <li>urgency: Semi-optional integer with the ticket urgency; required for a new ticket, ignored if adding a reply. If not stated on a new ticket, TICKET_URGENCY_LOW will be used.</li> |
|
66 |
+ * <li>assigned: Optional integer of user id, used to create a ticket with assignment, ignored if not a new ticket.</li> |
|
67 |
+ * </ul> |
|
68 |
+ * |
|
69 |
+ * @param array &$posterOptions A hash array by reference, containing details of the person the reply is written by. |
|
70 |
+ * <ul> |
|
71 |
+ * <li>id: User id to credit the post to. Uses 0 if not specified.</li> |
|
72 |
+ * <li>ip: IP address the post came from. Uses the current user's IP address if not specified.</li> |
|
73 |
+ * <li>name: Name to credit against the post. If not specified, and a user id was supplied, look that up in the member table, otherwise just use 'Guest'.</li> |
|
74 |
+ * <li>email: Email address to list against the post. If not specified, and a user id was supplied, look that up in the member table, otherwise just use ''.</li> |
|
75 |
+ * </ul> |
|
76 |
+ * @return bool True on success, false on failure. |
|
77 |
+ * @since 1.0 |
|
78 |
+ */ |
|
79 |
+function shd_create_ticket_post(&$msgOptions, &$ticketOptions, &$posterOptions) |
|
80 |
+{ |
|
81 |
+ global $user_info, $txt, $modSettings, $smcFunc, $context, $user_profile; |
|
82 |
+ |
|
83 |
+ // Clean them incoming vars up good 'n' proper |
|
84 |
+ $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']); |
|
85 |
+ $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments']; |
|
86 |
+ $msgOptions['time'] = empty($msgOptions['time']) ? time() : (int) $msgOptions['time']; |
|
87 |
+ $ticketOptions['id'] = empty($ticketOptions['id']) ? 0 : (int) $ticketOptions['id']; |
|
88 |
+ $ticketOptions['private'] = !empty($ticketOptions['private']); |
|
89 |
+ $ticketOptions['urgency'] = empty($ticketOptions['urgency']) ? TICKET_URGENCY_LOW : (int) $ticketOptions['urgency']; |
|
90 |
+ $ticketOptions['assigned'] = empty($ticketOptions['assigned']) ? 0 : (int) $ticketOptions['assigned']; |
|
91 |
+ $ticketOptions['status'] = empty($ticketOptions['status']) ? TICKET_STATUS_NEW : (int) $ticketOptions['status']; |
|
92 |
+ $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id']; |
|
93 |
+ $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip']; |
|
94 |
+ |
|
95 |
+ // If nothing was filled in as name/e-mail address, try the member table. |
|
96 |
+ if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || (empty($posterOptions['email']) && !empty($posterOptions['id']))) |
|
97 |
+ { |
|
98 |
+ if (empty($posterOptions['id'])) |
|
99 |
+ { |
|
100 |
+ $posterOptions['id'] = 0; |
|
101 |
+ $posterOptions['name'] = $txt['guest_title']; |
|
102 |
+ $posterOptions['email'] = ''; |
|
103 |
+ } |
|
104 |
+ elseif ($posterOptions['id'] != $user_info['id']) |
|
105 |
+ { |
|
106 |
+ if (empty($user_profile[$posterOptions['id']])) |
|
107 |
+ loadMemberData($posterOptions['id'], false, 'minimal'); |
|
108 |
+ |
|
109 |
+ // Couldn't find the current poster? |
|
110 |
+ if (empty($user_profile[$posterOptions['id']])) |
|
111 |
+ { |
|
112 |
+ trigger_error('shd_create_ticket_post(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE); |
|
113 |
+ $posterOptions['id'] = 0; |
|
114 |
+ $posterOptions['name'] = $txt['guest_title']; |
|
115 |
+ $posterOptions['email'] = ''; |
|
116 |
+ } |
|
117 |
+ else |
|
118 |
+ { |
|
119 |
+ $posterOptions['name'] = $user_profile[$posterOptions['id']]['real_name']; |
|
120 |
+ $posterOptions['email'] = $user_profile[$posterOptions['id']]['email_address']; |
|
121 |
+ } |
|
122 |
+ } |
|
123 |
+ else |
|
124 |
+ { |
|
125 |
+ $posterOptions['name'] = $user_info['name']; |
|
126 |
+ $posterOptions['email'] = $user_info['email']; |
|
127 |
+ } |
|
128 |
+ } |
|
129 |
+ |
|
130 |
+ // Is there modified name data? (For topic->ticket) |
|
131 |
+ $modified = true; |
|
132 |
+ if (isset($msgOptions['modified'])) |
|
133 |
+ { |
|
134 |
+ $msgOptions['modified']['time'] = empty($msgOptions['modified']['time']) ? 0 : (int) $msgOptions['modified']['time']; |
|
135 |
+ $msgOptions['modified']['id'] = empty($msgOptions['modified']['id']) ? 0 : (int) $msgOptions['modified']['id']; |
|
136 |
+ $msgOptions['modified']['name'] = empty($msgOptions['modified']['name']) ? '' : $msgOptions['modified']['name']; |
|
137 |
+ |
|
138 |
+ $cancel = false; |
|
139 |
+ if (empty($msgOptions['modified']['time']) || (empty($msgOptions['modified']['name']) && empty($msgOptions['modified']['id']))) |
|
140 |
+ $modified = false; |
|
141 |
+ |
|
142 |
+ if ($modified) |
|
143 |
+ { |
|
144 |
+ // So they have a time, and name or id (or even both). Let's see what we need. |
|
145 |
+ if (empty($msgOptions['modified']['name'])) |
|
146 |
+ { |
|
147 |
+ loadMemberData($msgOptions['modified']['id'], false, 'minimal'); |
|
148 |
+ if (empty($user_profile[$msgOptions['modified']['id']])) |
|
149 |
+ $modified = false; // oops, they gave us a user id that doesn't exist -- and we don't have a name |
|
150 |
+ } |
|
151 |
+ // Otherwise, we have a name and no id, which is fine. Can't be doing with trying to figure out usernames. |
|
152 |
+ } |
|
153 |
+ } |
|
154 |
+ else |
|
155 |
+ $modified = false; |
|
156 |
+ |
|
157 |
+ if (!$modified) |
|
158 |
+ $msgOptions['modified'] = array( |
|
159 |
+ 'id' => 0, |
|
160 |
+ 'name' => '', |
|
161 |
+ 'time' => 0, |
|
162 |
+ ); |
|
163 |
+ |
|
164 |
+ // It's do or die time: forget any user aborts! |
|
165 |
+ $previous_ignore_user_abort = ignore_user_abort(true); |
|
166 |
+ |
|
167 |
+ $new_ticket = empty($ticketOptions['id']); |
|
168 |
+ |
|
169 |
+ // OK, so let's add the reply. Even if it's a new ticket and stuff, let's still add the msg first so we have our friendly msg id |
|
170 |
+ $smcFunc['db_insert']('', |
|
171 |
+ '{db_prefix}helpdesk_ticket_replies', |
|
172 |
+ array( |
|
173 |
+ 'id_ticket' => 'int', 'id_member' => 'int', 'body' => 'string-65534', |
|
174 |
+ 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', |
|
175 |
+ 'smileys_enabled' => 'int', 'modified_member' => 'int', 'modified_name' => 'string', 'modified_time' => 'int', |
|
176 |
+ ), |
|
177 |
+ array( |
|
178 |
+ $ticketOptions['id'], $posterOptions['id'], $msgOptions['body'], |
|
179 |
+ $posterOptions['name'], $posterOptions['email'], $msgOptions['time'], $posterOptions['ip'], |
|
180 |
+ $msgOptions['smileys_enabled'] ? 1 : 0, $msgOptions['modified']['id'], $msgOptions['modified']['name'], $msgOptions['modified']['time'], |
|
181 |
+ ), |
|
182 |
+ array('id_msg') |
|
183 |
+ ); |
|
184 |
+ $msgOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}messages', 'id_msg'); |
|
185 |
+ |
|
186 |
+ // Something went wrong creating the message... |
|
187 |
+ if (empty($msgOptions['id'])) |
|
188 |
+ return false; |
|
189 |
+ |
|
190 |
+ // Insert a new ticket (if the ID was left empty) |
|
191 |
+ if ($new_ticket) |
|
192 |
+ { |
|
193 |
+ $smcFunc['db_insert']('', |
|
194 |
+ '{db_prefix}helpdesk_tickets', |
|
195 |
+ array( |
|
196 |
+ 'id_first_msg' => 'int', 'id_member_started' => 'int', 'id_last_msg' => 'int', 'id_member_updated' => 'int', |
|
197 |
+ 'id_member_assigned' => 'int', 'subject' => 'string-100', 'urgency' => 'int', 'status' => 'int', |
|
198 |
+ 'private' => 'int', |
|
199 |
+ ), |
|
200 |
+ array( |
|
201 |
+ $msgOptions['id'], $posterOptions['id'], $msgOptions['id'], $posterOptions['id'], |
|
202 |
+ $ticketOptions['assigned'], $ticketOptions['subject'], $ticketOptions['urgency'], $ticketOptions['status'], |
|
203 |
+ $ticketOptions['private'] ? 1 : 0, |
|
204 |
+ ), |
|
205 |
+ array('id_ticket') |
|
206 |
+ ); |
|
207 |
+ $ticketOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}helpdesk_tickets', 'id_ticket'); |
|
208 |
+ |
|
209 |
+ // The ticket couldn't be created for some reason. |
|
210 |
+ if (empty($ticketOptions['id'])) |
|
211 |
+ { |
|
212 |
+ // We should delete the post that did work, though... |
|
213 |
+ shd_db_query('', ' |
|
214 |
+ DELETE FROM {db_prefix}helpdesk_ticket_replies |
|
215 |
+ WHERE id_msg = {int:id_msg}', |
|
216 |
+ array( |
|
217 |
+ 'id_msg' => $msgOptions['id'], |
|
218 |
+ ) |
|
219 |
+ ); |
|
220 |
+ |
|
221 |
+ return false; |
|
222 |
+ } |
|
223 |
+ |
|
224 |
+ // Fix the message with the ticket. |
|
225 |
+ shd_db_query('', ' |
|
226 |
+ UPDATE {db_prefix}helpdesk_ticket_replies |
|
227 |
+ SET id_ticket = {int:id_ticket} |
|
228 |
+ WHERE id_msg = {int:id_msg}', |
|
229 |
+ array( |
|
230 |
+ 'id_ticket' => $ticketOptions['id'], |
|
231 |
+ 'id_msg' => $msgOptions['id'], |
|
232 |
+ ) |
|
233 |
+ ); |
|
234 |
+ |
|
235 |
+ } |
|
236 |
+ // The ticket already exists, it only needs a little updating. |
|
237 |
+ else |
|
238 |
+ { |
|
239 |
+ shd_db_query('', ' |
|
240 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
241 |
+ SET |
|
242 |
+ id_member_updated = {int:poster_id}, |
|
243 |
+ id_last_msg = {int:id_msg}, |
|
244 |
+ num_replies = num_replies + 1, |
|
245 |
+ status = {int:status} |
|
246 |
+ WHERE id_ticket = {int:id_ticket}', |
|
247 |
+ array( |
|
248 |
+ 'poster_id' => $posterOptions['id'], |
|
249 |
+ 'id_msg' => $msgOptions['id'], |
|
250 |
+ 'status' => $ticketOptions['status'], |
|
251 |
+ 'id_ticket' => $ticketOptions['id'], |
|
252 |
+ ) |
|
253 |
+ ); |
|
254 |
+ } |
|
255 |
+ |
|
256 |
+ // Fix the attachments. |
|
257 |
+ if (!empty($msgOptions['attachments'])) |
|
258 |
+ { |
|
259 |
+ $array = array(); |
|
260 |
+ foreach ($msgOptions['attachments'] as $attach) |
|
261 |
+ $array[] = array($attach, $msgOptions['id'], $ticketOptions['id']); |
|
262 |
+ |
|
263 |
+ $smcFunc['db_insert']('replace', |
|
264 |
+ '{db_prefix}helpdesk_attachments', |
|
265 |
+ array( |
|
266 |
+ 'id_attach' => 'int', 'id_msg' => 'int', 'id_ticket' => 'int', |
|
267 |
+ ), |
|
268 |
+ $array, |
|
269 |
+ array('id_attach') |
|
270 |
+ ); |
|
271 |
+ } |
|
272 |
+ |
|
273 |
+ // Mark inserted ticket as read (only for the user listed as the author -- oftentimes will be the current user though) |
|
274 |
+ if (!empty($ticketOptions['mark_as_read']) && !empty($posterOptions['id'])) |
|
275 |
+ { |
|
276 |
+ // Since it's likely they *read* it before replying, let's try an UPDATE first. |
|
277 |
+ if (!$new_ticket) |
|
278 |
+ { |
|
279 |
+ shd_db_query('', ' |
|
280 |
+ UPDATE {db_prefix}helpdesk_log_read |
|
281 |
+ SET id_msg = {int:id_msg} |
|
282 |
+ WHERE id_member = {int:current_member} |
|
283 |
+ AND id_ticket = {int:id_ticket}', |
|
284 |
+ array( |
|
285 |
+ 'current_member' => $posterOptions['id'], |
|
286 |
+ 'id_msg' => $msgOptions['id'], |
|
287 |
+ 'id_ticket' => $ticketOptions['id'], |
|
288 |
+ ) |
|
289 |
+ ); |
|
290 |
+ |
|
291 |
+ $flag = $smcFunc['db_affected_rows']() != 0; |
|
292 |
+ } |
|
293 |
+ |
|
294 |
+ if (empty($flag)) |
|
295 |
+ { |
|
296 |
+ $smcFunc['db_insert']('replace', |
|
297 |
+ '{db_prefix}helpdesk_log_read', |
|
298 |
+ array('id_ticket' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), |
|
299 |
+ array($ticketOptions['id'], $posterOptions['id'], $msgOptions['id']), |
|
300 |
+ array('id_ticket', 'id_member') |
|
301 |
+ ); |
|
302 |
+ return false; |
|
303 |
+ } |
|
304 |
+ } |
|
305 |
+ |
|
306 |
+ ignore_user_abort($previous_ignore_user_abort); |
|
307 |
+ |
|
308 |
+ // Success. |
|
309 |
+ return true; |
|
310 |
+} |
|
311 |
+ |
|
312 |
+/** |
|
313 |
+ * Updates a ticket/reply item in the database. |
|
314 |
+ * |
|
315 |
+ * This function allows modification of all post/ticket details - and can be used independently; it is possible (and even done |
|
316 |
+ * in SimpleDesk) to update just a ticket or just a post from this function. All three parameters are by <b>reference</b> |
|
317 |
+ * meaning they WILL be updated if things change. Note that this function is not validating that they are sensible values; it is |
|
318 |
+ * up to the calling function to ascertain that. |
|
319 |
+ * |
|
320 |
+ * @param array &$msgOptions - a hash array by reference, stating zero or more details to change on a message (if the change is strictly ticket-only, the entire $msgOptions array can be an empty array): |
|
321 |
+ * <ul> |
|
322 |
+ * <li>id: Required if changing a message; the principle numeric id of the message to modify</li> |
|
323 |
+ * <li>body: Optional, the principle body content of the message to change; if omitted, no change will occur. If set, assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and preparsecode)</li> |
|
324 |
+ * <li>modified: Optional, hash array containing items relating to modification (if 'modified' key exists, all of these should be set) |
|
325 |
+ * <ul> |
|
326 |
+ * <li>time: Unsigned int timestamp of the change</li> |
|
327 |
+ * <li>name: String; user name of the user making the change</li> |
|
328 |
+ * <li>id: Unsigned int user id of the user making the change</li> |
|
329 |
+ * </ul> |
|
330 |
+ * </li> |
|
331 |
+ * <li>smileys_enabled: Optional, boolean denoting whether smileys should be active on this post; if omitted no change will occur</li> |
|
332 |
+ * <li>attachments: Optional, array of attachment ids that need attaching to this message; if omitted no changes will occur</li> |
|
333 |
+ * </ul> |
|
334 |
+ * |
|
335 |
+ * @param array &$ticketOptions - a hash array by reference, stating one or more details necessary to change on a ticket: |
|
336 |
+ * <ul> |
|
337 |
+ * <li>id: Required in all cases, numeric ticket id that the edit relates to</li> |
|
338 |
+ * <li>subject: Optional string with the new subject in; if omitted no change will occur. If set, assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and strtr)</li> |
|
339 |
+ * <li>urgency: Optional integer with the new urgency in; if omitted no change will occur</li> |
|
340 |
+ * <li>status: Optional integer with the new status in; if omitted no change will occur</li> |
|
341 |
+ * <li>ssigned: Optional integer with the user id of assigned user; if omitted no change will occur (note, you would declare this as 0 to unassign a ticket - set to 0 is not omitted)</li> |
|
342 |
+ * <li>private: Optional boolean as to privacy of ticket: true = private, false = not private (note, you still declare this to change it)</li> |
|
343 |
+ * </ul> |
|
344 |
+ * |
|
345 |
+ * @param array &$posterOptions - a hash array by reference of details to change on the poster of a message: |
|
346 |
+ * <ul> |
|
347 |
+ * <li>name: Optional string, name of credited poster (in absence of id, this will be used); if omitted no change will occur</li> |
|
348 |
+ * <li>email: Optional string, email address of poster; if omitted no change will occur</li> |
|
349 |
+ * </ul> |
|
350 |
+ * |
|
351 |
+ * @return bool True on success, false on failure. |
|
352 |
+ * @since 1.0 |
|
353 |
+*/ |
|
354 |
+function shd_modify_ticket_post(&$msgOptions, &$ticketOptions, &$posterOptions) |
|
355 |
+{ |
|
356 |
+ global $user_info, $txt, $modSettings, $smcFunc, $context; |
|
357 |
+ |
|
358 |
+ $messages_columns = array(); |
|
359 |
+ $ticket_columns = array(); |
|
360 |
+ |
|
361 |
+ $ticketOptions['id'] = !empty($ticketOptions['id']) ? (int) $ticketOptions['id'] : 0; |
|
362 |
+ if ($ticketOptions['id'] == 0) |
|
363 |
+ return false; |
|
364 |
+ |
|
365 |
+ if (isset($posterOptions['name'])) |
|
366 |
+ $messages_columns['poster_name'] = $posterOptions['name']; |
|
367 |
+ if (isset($posterOptions['email'])) |
|
368 |
+ $messages_columns['poster_email'] = $posterOptions['email']; |
|
369 |
+ if (isset($msgOptions['body'])) |
|
370 |
+ $messages_columns['body'] = $msgOptions['body']; |
|
371 |
+ if (!empty($msgOptions['modified'])) |
|
372 |
+ { |
|
373 |
+ $messages_columns['modified_time'] = $msgOptions['modified']['time']; |
|
374 |
+ $messages_columns['modified_name'] = $msgOptions['modified']['name']; |
|
375 |
+ $messages_columns['modified_member'] = $msgOptions['modified']['id']; |
|
376 |
+ } |
|
377 |
+ if (isset($msgOptions['smileys_enabled'])) |
|
378 |
+ $messages_columns['smileys_enabled'] = empty($msgOptions['smileys_enabled']) ? 0 : 1; |
|
379 |
+ if (isset($ticketOptions['subject'])) |
|
380 |
+ $ticket_columns['subject'] = $ticketOptions['subject']; |
|
381 |
+ if (isset($ticketOptions['status'])) |
|
382 |
+ $ticket_columns['status'] = $ticketOptions['status']; |
|
383 |
+ if (isset($ticketOptions['urgency'])) |
|
384 |
+ $ticket_columns['urgency'] = $ticketOptions['urgency']; |
|
385 |
+ if (isset($ticketOptions['assigned'])) |
|
386 |
+ $ticket_columns['id_member_assigned'] = $ticketOptions['assigned']; |
|
387 |
+ if (isset($ticketOptions['private'])) |
|
388 |
+ $ticket_columns['private'] = empty($ticketOptions['private']) ? 0 : 1; |
|
389 |
+ |
|
390 |
+ // Fix the attachments. |
|
391 |
+ if (!empty($msgOptions['attachments'])) |
|
392 |
+ { |
|
393 |
+ $array = array(); |
|
394 |
+ foreach ($msgOptions['attachments'] as $attach) |
|
395 |
+ $array[] = array($attach, $msgOptions['id'], $ticketOptions['id']); |
|
396 |
+ |
|
397 |
+ $smcFunc['db_insert']('replace', |
|
398 |
+ '{db_prefix}helpdesk_attachments', |
|
399 |
+ array( |
|
400 |
+ 'id_attach' => 'int', 'id_msg' => 'int', 'id_ticket' => 'int', |
|
401 |
+ ), |
|
402 |
+ $array, |
|
403 |
+ array('id_attach') |
|
404 |
+ ); |
|
405 |
+ } |
|
406 |
+ |
|
407 |
+ if (empty($messages_columns) && empty($ticket_columns)) |
|
408 |
+ return true; |
|
409 |
+ |
|
410 |
+ // It's do or die time: forget any user aborts! |
|
411 |
+ $previous_ignore_user_abort = ignore_user_abort(true); |
|
412 |
+ |
|
413 |
+ // OK, let's get all this set up ready for SQL magic |
|
414 |
+ // Which columns need to be ints? |
|
415 |
+ $messageInts = array('modified_time', 'modified_member', 'smileys_enabled'); |
|
416 |
+ $msg_update_parameters = array( |
|
417 |
+ 'id_msg' => empty($msgOptions['id']) ? 0 : (int) $msgOptions['id'], |
|
418 |
+ ); |
|
419 |
+ |
|
420 |
+ foreach ($messages_columns as $var => $val) |
|
421 |
+ { |
|
422 |
+ $messages_columns[$var] = $var . ' = {' . (in_array($var, $messageInts) ? 'int' : 'string') . ':var_' . $var . '}'; |
|
423 |
+ $msg_update_parameters['var_' . $var] = $val; |
|
424 |
+ } |
|
425 |
+ |
|
426 |
+ $ticketInts = array('status', 'urgency'); |
|
427 |
+ $ticket_update_parameters = array( |
|
428 |
+ 'id_ticket' => $ticketOptions['id'], |
|
429 |
+ ); |
|
430 |
+ |
|
431 |
+ foreach ($ticket_columns as $var => $val) |
|
432 |
+ { |
|
433 |
+ $ticket_columns[$var] = $var . ' = {' . (in_array($var, $ticketInts) ? 'int' : 'string') . ':var_' . $var . '}'; |
|
434 |
+ $ticket_update_parameters['var_' . $var] = $val; |
|
435 |
+ } |
|
436 |
+ |
|
437 |
+ // GO GO GO! (message first) |
|
438 |
+ if (!empty($messages_columns)) |
|
439 |
+ { |
|
440 |
+ shd_db_query('', ' |
|
441 |
+ UPDATE {db_prefix}helpdesk_ticket_replies |
|
442 |
+ SET ' . implode(', ', $messages_columns) . ' |
|
443 |
+ WHERE id_msg = {int:id_msg}', |
|
444 |
+ $msg_update_parameters |
|
445 |
+ ); |
|
446 |
+ } |
|
447 |
+ |
|
448 |
+ if (!empty($ticket_columns)) |
|
449 |
+ { |
|
450 |
+ shd_db_query('', ' |
|
451 |
+ UPDATE {db_prefix}helpdesk_tickets |
|
452 |
+ SET ' . implode(', ', $ticket_columns) . ' |
|
453 |
+ WHERE id_ticket = {int:id_ticket}', |
|
454 |
+ $ticket_update_parameters |
|
455 |
+ ); |
|
456 |
+ } |
|
457 |
+ |
|
458 |
+ ignore_user_abort($previous_ignore_user_abort); |
|
459 |
+ |
|
460 |
+ // Success. |
|
461 |
+ return true; |
|
462 |
+} |
|
463 |
+ |
|
464 |
+/** |
|
465 |
+ * Identifies the range of options that a user could have for ticket urgency and updates $context['ticket_form'] accordingly. |
|
466 |
+ * |
|
467 |
+ * Ticket urgency permissions are checked, and an array is built suitable for $context['ticket_form'], which is the principle |
|
468 |
+ * format used in the ticket posting/reply posting functions in SimpleDesk-Post.php. |
|
469 |
+ * |
|
470 |
+ * There is no return function; $context['ticket_form']['urgency'] is updated, both the ['options'] and ['can_change'] keys |
|
471 |
+ * may be modified. |
|
472 |
+ * |
|
473 |
+ * @param bool $self_ticket (default false) Permissions will be different for many users depending on whether it is one |
|
474 |
+ * of their own tickets or not. This allows the code to state whether it is a ticket owned by the current user or not. |
|
475 |
+ * |
|
476 |
+ * @see SimpleDesk-Display.php |
|
477 |
+ * @since 1.0 |
|
478 |
+*/ |
|
479 |
+function shd_get_urgency_options($self_ticket = false) |
|
480 |
+{ |
|
481 |
+ global $context; |
|
482 |
+ $context['ticket_form']['urgency']['options'] = array( |
|
483 |
+ TICKET_URGENCY_LOW => 'shd_urgency_0', |
|
484 |
+ TICKET_URGENCY_MEDIUM => 'shd_urgency_1', |
|
485 |
+ TICKET_URGENCY_HIGH => 'shd_urgency_2', |
|
486 |
+ TICKET_URGENCY_VHIGH => 'shd_urgency_3', |
|
487 |
+ TICKET_URGENCY_SEVERE => 'shd_urgency_4', |
|
488 |
+ TICKET_URGENCY_CRITICAL => 'shd_urgency_5', |
|
489 |
+ ); |
|
490 |
+ |
|
491 |
+ if (shd_allowed_to('shd_alter_urgency_higher_any') || ($self_ticket && shd_allowed_to('shd_alter_urgency_higher_own'))) |
|
492 |
+ { |
|
493 |
+ $context['ticket_form']['urgency']['can_change'] = true; |
|
494 |
+ } |
|
495 |
+ elseif (shd_allowed_to('shd_alter_urgency_any') || ($self_ticket && shd_allowed_to('shd_alter_urgency_own'))) |
|
496 |
+ { |
|
497 |
+ if (!empty($context['ticket_form']['urgency']['setting']) && $context['ticket_form']['urgency']['setting'] > TICKET_URGENCY_HIGH) |
|
498 |
+ $context['ticket_form']['urgency']['can_change'] = false; |
|
499 |
+ else |
|
500 |
+ { |
|
501 |
+ $context['ticket_form']['urgency']['can_change'] = true; |
|
502 |
+ unset( |
|
503 |
+ $context['ticket_form']['urgency']['options'][TICKET_URGENCY_VHIGH], |
|
504 |
+ $context['ticket_form']['urgency']['options'][TICKET_URGENCY_SEVERE], |
|
505 |
+ $context['ticket_form']['urgency']['options'][TICKET_URGENCY_CRITICAL] |
|
506 |
+ ); |
|
507 |
+ } |
|
508 |
+ } |
|
509 |
+ else |
|
510 |
+ $context['ticket_form']['urgency']['can_change'] = false; |
|
511 |
+} |
|
512 |
+ |
|
513 |
+?> |
|
0 | 514 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,696 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk's administration area |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * Displays SimpleDesk's administration panel, options pages, action log and the get-support page. |
|
6 |
+ * |
|
7 |
+ * @package template |
|
8 |
+ * @since 1.0 |
|
9 |
+*/ |
|
10 |
+ |
|
11 |
+/** |
|
12 |
+ * Display the main information center for the administration panel. |
|
13 |
+ * |
|
14 |
+ * This function handles output of data populated by {@link shd_admin_info()}: |
|
15 |
+ * - upgraded SD version advisory |
|
16 |
+ * - latest news from SimpleDesk.net |
|
17 |
+ * - basic version check |
|
18 |
+ * - count of open/closed/recycled tickets in the helpdesk in total |
|
19 |
+ * - list of current helpdesk staff |
|
20 |
+ * - credits |
|
21 |
+ * |
|
22 |
+ * @see shd_admin_info() |
|
23 |
+ * @since 1.0 |
|
24 |
+*/ |
|
25 |
+function template_shd_admin() |
|
26 |
+{ |
|
27 |
+ global $context, $settings, $options, $scripturl, $txt, $modSettings; |
|
28 |
+ |
|
29 |
+ // Make our admin feel welcome |
|
30 |
+ echo ' |
|
31 |
+ <div id="admincenter">'; |
|
32 |
+ |
|
33 |
+ // Welcome, sir. |
|
34 |
+ echo ' |
|
35 |
+ <div class="tborder"> |
|
36 |
+ <h3 class="catbg"><span class="left"></span> |
|
37 |
+ <span class="ie6_header floatleft"> |
|
38 |
+ <img src="', $settings['default_images_url'], '/admin/simpledesk.png" class="icon" alt="*" /> ', $txt['shd_admin_info'], ' |
|
39 |
+ </span> |
|
40 |
+ </h3> |
|
41 |
+ <p class="windowbg description shd_info_box"> |
|
42 |
+ <strong>', $txt['hello_guest'], ' ', $context['user']['name'], '!</strong><br /> |
|
43 |
+ ', $txt['shd_admin_info_desc'], ' |
|
44 |
+ </p> |
|
45 |
+ </div> |
|
46 |
+ <br />'; |
|
47 |
+ |
|
48 |
+ // Update? |
|
49 |
+ echo ' |
|
50 |
+ <div id="sd_update_section" class="tborder" style="display: none;"></div>'; |
|
51 |
+ |
|
52 |
+ echo ' |
|
53 |
+ <div id="admin_main_section">'; |
|
54 |
+ |
|
55 |
+ // Display the "live news" from simpledesk.net |
|
56 |
+ echo ' |
|
57 |
+ <div id="sd_live_news" class="floatleft"> |
|
58 |
+ <div class="tborder"> |
|
59 |
+ <div class="cat_bar grid_header"> |
|
60 |
+ <h3 class="catbg"> |
|
61 |
+ <img src="', $settings['default_images_url'], '/simpledesk/live.png" alt="*" /> |
|
62 |
+ ', $txt['shd_live_from'], ' |
|
63 |
+ <span class="righttext"><a href="', $scripturl, '?action=helpadmin;help=shd_admin_help_live" onclick="return reqWin(this.href);"><img src="', $settings['images_url'], '/helptopics.gif" alt="', $txt['help'], '" /></a></span> |
|
64 |
+ </h3> |
|
65 |
+ </div> |
|
66 |
+ <div class="windowbg"> |
|
67 |
+ <div class="content"> |
|
68 |
+ <div id="sdAnnouncements">', $txt['shd_no_connect'], '</div> |
|
69 |
+ </div> |
|
70 |
+ <span class="botslice"><span></span></span> |
|
71 |
+ </div> |
|
72 |
+ </div> |
|
73 |
+ </div>'; |
|
74 |
+ |
|
75 |
+ // Show the user version information from their server. |
|
76 |
+ echo ' |
|
77 |
+ <div id="sd_supportVersionsTable" class="floatright"> |
|
78 |
+ <div class="tborder"> |
|
79 |
+ <div class="cat_bar grid_header"> |
|
80 |
+ <h3 class="catbg"> |
|
81 |
+ <img src="', $settings['default_images_url'], '/simpledesk/modification.png" alt="*" /> |
|
82 |
+ ', $txt['shd_mod_information'], ' |
|
83 |
+ <span class="righttext"><a href="', $scripturl, '?action=helpadmin;help=shd_admin_help_modification" onclick="return reqWin(this.href);"><img src="', $settings['images_url'], '/helptopics.gif" alt="', $txt['help'], '" /></a></span> |
|
84 |
+ </h3> |
|
85 |
+ </div> |
|
86 |
+ <div class="windowbg"> |
|
87 |
+ <div class="content"> |
|
88 |
+ <div id="sd_version_details"> |
|
89 |
+ <strong>', $txt['support_versions'], ':</strong><br /> |
|
90 |
+ ', $txt['shd_your_version'], ': |
|
91 |
+ <em id="yourVersion" class="shd_nowrap">', $context['shd_version'], '</em><br /> |
|
92 |
+ ', $txt['shd_current_version'], ': |
|
93 |
+ <em id="sdVersion" class="shd_nowrap">??</em><br /><br /> |
|
94 |
+ <strong>', $txt['shd_ticket_information'], ':</strong><br /> |
|
95 |
+ ', $txt['shd_total_tickets'], ': |
|
96 |
+ <em id="totalTickets" class="shd_nowrap"> |
|
97 |
+ <a href="javascript: shd_ticket_total_information();" >', $context['total_tickets'], '</a> |
|
98 |
+ </em> |
|
99 |
+ <div id="shd_ticket_total_information" style="display: none;"> |
|
100 |
+ ', $txt['shd_open_tickets'], ': <em>', $context['open_tickets'], '</em><br /> |
|
101 |
+ ', $txt['shd_closed_tickets'], ': <em>', $context['closed_tickets'], '</em><br /> |
|
102 |
+ ', $txt['shd_recycled_tickets'], ': <em>', $context['recycled_tickets'], '</em><br /> |
|
103 |
+ </div> |
|
104 |
+ <br />'; |
|
105 |
+ |
|
106 |
+ // Display all the members who can manage the helpdesk. |
|
107 |
+ // NOTE: This is currently (15/1/10) uncapped, meaning it's just the full list direct from SimpleDesk-Admin.php. |
|
108 |
+ // That gets the data. Up to here how it should be displayed. |
|
109 |
+ echo ' |
|
110 |
+ <br /> |
|
111 |
+ <strong>', $txt['shd_staff_list'], ':</strong> |
|
112 |
+ ', implode(', ', $context['staff']); |
|
113 |
+ |
|
114 |
+ echo ' |
|
115 |
+ </div> |
|
116 |
+ </div> |
|
117 |
+ <span class="botslice"><span></span></span> |
|
118 |
+ </div> |
|
119 |
+ </div> |
|
120 |
+ </div> |
|
121 |
+ </div> |
|
122 |
+ <div class="shd_credits_break"> </div>'; |
|
123 |
+ |
|
124 |
+ |
|
125 |
+ echo ' |
|
126 |
+ <div id="sd_credits"> |
|
127 |
+ <div class="tborder"> |
|
128 |
+ <div class="title_bar grid_header"> |
|
129 |
+ <h3 class="titlebg sd_no_margin"> |
|
130 |
+ <span class="left"></span> |
|
131 |
+ <img src="', $settings['default_images_url'], '/simpledesk/credits.png" alt="*" /> |
|
132 |
+ ', $txt['shd_credits'], ' |
|
133 |
+ <span class="righttext"><a href="', $scripturl, '?action=helpadmin;help=shd_admin_help_credits" onclick="return reqWin(this.href);"><img src="', $settings['images_url'], '/helptopics.gif" alt="', $txt['help'], '" /></a></span> |
|
134 |
+ </h3> |
|
135 |
+ </div>'; |
|
136 |
+ |
|
137 |
+ foreach ($context['shd_credits'] as $section) |
|
138 |
+ { |
|
139 |
+ echo ' |
|
140 |
+ <div class="roundframe"> |
|
141 |
+ <div class="content"> |
|
142 |
+ ', $section['pretext'], ' |
|
143 |
+ <hr />'; |
|
144 |
+ |
|
145 |
+ foreach ($section['groups'] as $group) |
|
146 |
+ { |
|
147 |
+ echo ' |
|
148 |
+ <div class="description">'; |
|
149 |
+ |
|
150 |
+ if (isset($group['title'])) |
|
151 |
+ echo ' |
|
152 |
+ <strong>', $group['title'], '</strong>', !empty($group['desc']) ? ' - <em class="smalltext">' . $group['desc'] . '</em>' : '', '<hr />'; |
|
153 |
+ |
|
154 |
+ // Try to make this read nicely. |
|
155 |
+ if (count($group['members']) <= 2) |
|
156 |
+ echo implode(' ' . $txt['shd_credits_and'] . ' ', $group['members']); |
|
157 |
+ else |
|
158 |
+ { |
|
159 |
+ $last_peep = array_pop($group['members']); |
|
160 |
+ echo implode(', ', $group['members']), ', ', $txt['shd_credits_and'], ' ', $last_peep; |
|
161 |
+ } |
|
162 |
+ |
|
163 |
+ echo ' |
|
164 |
+ |
|
165 |
+ </div>'; |
|
166 |
+ } |
|
167 |
+ |
|
168 |
+ echo ' |
|
169 |
+ </div> |
|
170 |
+ </div> |
|
171 |
+ <span class="lowerframe"><span></span></span> |
|
172 |
+ </div> |
|
173 |
+ </div>'; |
|
174 |
+ } |
|
175 |
+ |
|
176 |
+ echo ' |
|
177 |
+ </div> |
|
178 |
+ <br class="clear" />'; |
|
179 |
+ |
|
180 |
+ // The below functions include all the scripts needed from the simpledesk.net site. The language and format are passed for internationalization. |
|
181 |
+ if (empty($modSettings['disable_smf_js'])) |
|
182 |
+ echo ' |
|
183 |
+ <script type="text/javascript" src="http://www.simpledesk.net/sd/current-version.js"></script> |
|
184 |
+ <script type="text/javascript" src="http://www.simpledesk.net/sd/latest-news.js"></script>'; |
|
185 |
+ |
|
186 |
+ // This sets the announcements and current versions themselves ;). |
|
187 |
+ echo ' |
|
188 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
189 |
+ |
|
190 |
+ var oAdminIndex = new sd_AdminIndex({ |
|
191 |
+ sSelf: \'oAdminCenter\', |
|
192 |
+ |
|
193 |
+ bLoadAnnouncements: true, |
|
194 |
+ sAnnouncementTemplate: ', JavaScriptEscape(' |
|
195 |
+ <dl> |
|
196 |
+ %content% |
|
197 |
+ </dl> |
|
198 |
+ '), ', |
|
199 |
+ sAnnouncementMessageTemplate: ', JavaScriptEscape(' |
|
200 |
+ <dt><a href="%href%" target="_blank">%subject%</a> ' . $txt['on'] . ' %time% ' . $txt['by'] . ' %author%</dt> |
|
201 |
+ <dd> |
|
202 |
+ %message%<br /> |
|
203 |
+ <a href="%readmore%" class="smalltext" target="_blank">' . $txt['shd_admin_readmore'] . '</a> |
|
204 |
+ </dd> |
|
205 |
+ '), ', |
|
206 |
+ sAnnouncementContainerId: \'sdAnnouncements\', |
|
207 |
+ |
|
208 |
+ bLoadVersions: true, |
|
209 |
+ sSdVersionContainerId: \'sdVersion\', |
|
210 |
+ sYourVersionContainerId: \'yourVersion\', |
|
211 |
+ sVersionOutdatedTemplate: ', JavaScriptEscape(' |
|
212 |
+ <span class="alert">%currentVersion%</span> |
|
213 |
+ '), ', |
|
214 |
+ |
|
215 |
+ bLoadUpdateNotification: true, |
|
216 |
+ sUpdateNotificationContainerId: \'sd_update_section\', |
|
217 |
+ sUpdateNotificationDefaultTitle: ', JavaScriptEscape($txt['shd_update_available']), ', |
|
218 |
+ sUpdateNotificationDefaultMessage: ', JavaScriptEscape($txt['shd_update_message']), ', |
|
219 |
+ sUpdateNotificationTemplate: ', JavaScriptEscape(' |
|
220 |
+ <div class="cat_bar grid_header" id="update_title"> |
|
221 |
+ <h3 class="catbg"> |
|
222 |
+ <img src="' . $settings['default_images_url'] . '/simpledesk/update.png" alt="" /> |
|
223 |
+ %title% |
|
224 |
+ <span class="righttext"><a href="' . $scripturl . '?action=helpadmin;help=shd_admin_help_update" onclick="return reqWin(this.href);"><img src="'. $settings['images_url'] . '/helptopics.gif" alt="' . $txt['help'] . '" /></a></span> |
|
225 |
+ </h3> |
|
226 |
+ </div> |
|
227 |
+ <div class="windowbg" id="update_container"> |
|
228 |
+ <div class="content" id="update_content"> |
|
229 |
+ <p id="update_critical_alert" class="alert" style="display: none;">!!</p> |
|
230 |
+ <h3 id="update_critical_title" style="display: none;">%criticaltitle%</h3> |
|
231 |
+ <div id="update_message" class="smalltext"> |
|
232 |
+ <p> |
|
233 |
+ %message% |
|
234 |
+ </p> |
|
235 |
+ </div> |
|
236 |
+ </div> |
|
237 |
+ <span class="botslice"><span></span></span> |
|
238 |
+ </div> |
|
239 |
+ '), ', |
|
240 |
+ sUpdateNotificationLink: ', JavaScriptEscape($scripturl . '?action=admin;area=packages;pgdownload;auto;package=%package%;' . $context['session_var'] . '=' . $context['session_id']), ', |
|
241 |
+ sUpdateInformationLink: \'%information%\', |
|
242 |
+ }); |
|
243 |
+ // ]]></script>'; |
|
244 |
+} |
|
245 |
+ |
|
246 |
+/** |
|
247 |
+ * Display options as set up by the options functions. |
|
248 |
+ * |
|
249 |
+ * This is a modified version of the standard SMF template for displaying settings, mostly so we have access to a custom BBC template. |
|
250 |
+ * |
|
251 |
+ * In short, SMF's functions call the relevant function in {@link SimpleDesk-Admin.php} to gather which options should be displayed, store in $context, then pass it here. |
|
252 |
+ * |
|
253 |
+ * The same template services all of the defined areas inside Admin: SimpleDesk: Options. |
|
254 |
+ * |
|
255 |
+ * @see shd_admin_options() |
|
256 |
+ * @since 1.0 |
|
257 |
+*/ |
|
258 |
+function template_shd_show_settings() |
|
259 |
+{ |
|
260 |
+ global $context, $txt, $settings, $scripturl; |
|
261 |
+ |
|
262 |
+ echo ' |
|
263 |
+ <script type="text/javascript"><!-- // --><![CDATA['; |
|
264 |
+ |
|
265 |
+ if (!empty($context['settings_pre_javascript'])) |
|
266 |
+ echo $context['settings_pre_javascript']; |
|
267 |
+ |
|
268 |
+ // If we have BBC selection we have a bit of JS. |
|
269 |
+ if (!empty($context['bbc_sections'])) |
|
270 |
+ { |
|
271 |
+ echo ' |
|
272 |
+ function toggleBBCDisabled(section, disable) |
|
273 |
+ { |
|
274 |
+ for (var i = 0; i < document.forms.bbcForm.length; i++) |
|
275 |
+ { |
|
276 |
+ if (typeof(document.forms.bbcForm[i].name) == "undefined" || (document.forms.bbcForm[i].name.substr(0, 11) != "enabledTags") || (document.forms.bbcForm[i].name.indexOf(section) != 11)) |
|
277 |
+ continue; |
|
278 |
+ |
|
279 |
+ document.forms.bbcForm[i].disabled = disable; |
|
280 |
+ } |
|
281 |
+ document.getElementById("bbc_" + section + "_select_all").disabled = disable; |
|
282 |
+ }'; |
|
283 |
+ } |
|
284 |
+ echo ' |
|
285 |
+ // ]]></script>'; |
|
286 |
+ |
|
287 |
+ if (!empty($context['settings_insert_above'])) |
|
288 |
+ echo $context['settings_insert_above']; |
|
289 |
+ |
|
290 |
+ echo ' |
|
291 |
+ <div id="admincenter"> |
|
292 |
+ <form action="', $context['post_url'], '" method="post" accept-charset="', $context['character_set'], '"', !empty($context['force_form_onsubmit']) ? ' onsubmit="' . $context['force_form_onsubmit'] . '"' : '', '>'; |
|
293 |
+ |
|
294 |
+ // Is there a custom title? |
|
295 |
+ if (isset($context['settings_title'])) |
|
296 |
+ echo ' |
|
297 |
+ <div class="tborder"> |
|
298 |
+ <div class="cat_bar grid_header"> |
|
299 |
+ <h3 class="catbg"> |
|
300 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $context['settings_icon'], '" class="icon" alt="*" /> ', $context['settings_title'], ' |
|
301 |
+ </h3> |
|
302 |
+ </div>'; |
|
303 |
+ |
|
304 |
+ // Have we got some custom code to insert? |
|
305 |
+ if (!empty($context['settings_message'])) |
|
306 |
+ echo ' |
|
307 |
+ <div class="information">', $context['settings_message'], '</div>'; |
|
308 |
+ |
|
309 |
+ // Now actually loop through all the variables. |
|
310 |
+ $is_open = false; |
|
311 |
+ foreach ($context['config_vars'] as $config_var) |
|
312 |
+ { |
|
313 |
+ // Is it a title or a description? |
|
314 |
+ if (is_array($config_var) && ($config_var['type'] == 'title' || $config_var['type'] == 'desc')) |
|
315 |
+ { |
|
316 |
+ // Not a list yet? |
|
317 |
+ if ($is_open) |
|
318 |
+ { |
|
319 |
+ $is_open = false; |
|
320 |
+ echo ' |
|
321 |
+ </dl> |
|
322 |
+ </div> |
|
323 |
+ <span class="botslice"><span></span></span> |
|
324 |
+ </div> |
|
325 |
+ </div>'; |
|
326 |
+ } |
|
327 |
+ |
|
328 |
+ // A title? |
|
329 |
+ if ($config_var['type'] == 'title') |
|
330 |
+ { |
|
331 |
+ echo ' |
|
332 |
+ <div class="cat_bar"> |
|
333 |
+ <h3 class="', !empty($config_var['class']) ? $config_var['class'] : 'catbg', '"', !empty($config_var['force_div_id']) ? ' id="' . $config_var['force_div_id'] . '"' : '', '> |
|
334 |
+ ', ($config_var['help'] ? '<a href="' . $scripturl . '?action=helpadmin;help=' . $config_var['help'] . '" onclick="return reqWin(this.href);" class="help"><img src="' . $settings['images_url'] . '/helptopics.gif" alt="' . $txt['help'] . '" /></a>' : ''), ' |
|
335 |
+ ', $config_var['label'], ' |
|
336 |
+ </h3> |
|
337 |
+ </div>'; |
|
338 |
+ } |
|
339 |
+ // A description? |
|
340 |
+ else |
|
341 |
+ { |
|
342 |
+ echo ' |
|
343 |
+ <p class="description"> |
|
344 |
+ ', $config_var['label'], ' |
|
345 |
+ </p>'; |
|
346 |
+ } |
|
347 |
+ |
|
348 |
+ continue; |
|
349 |
+ } |
|
350 |
+ |
|
351 |
+ // Not a list yet? |
|
352 |
+ if (!$is_open) |
|
353 |
+ { |
|
354 |
+ $is_open = true; |
|
355 |
+ |
|
356 |
+ if (!isset($context['settings_title'])) |
|
357 |
+ echo '<div class="tborder">'; |
|
358 |
+ |
|
359 |
+ echo ' |
|
360 |
+ <div class="windowbg2"> |
|
361 |
+ <div class="content"> |
|
362 |
+ <dl class="settings">'; |
|
363 |
+ } |
|
364 |
+ |
|
365 |
+ // Hang about? Are you pulling my leg - a callback?! |
|
366 |
+ if (is_array($config_var) && $config_var['type'] == 'callback') |
|
367 |
+ { |
|
368 |
+ if (function_exists('template_callback_' . $config_var['name'])) |
|
369 |
+ call_user_func('template_callback_' . $config_var['name']); |
|
370 |
+ |
|
371 |
+ continue; |
|
372 |
+ } |
|
373 |
+ |
|
374 |
+ if (is_array($config_var)) |
|
375 |
+ { |
|
376 |
+ // First off, is this a span like a message? |
|
377 |
+ if (in_array($config_var['type'], array('message', 'warning'))) |
|
378 |
+ { |
|
379 |
+ echo ' |
|
380 |
+ <dd', $config_var['type'] == 'warning' ? ' class="alert"' : '', (!empty($config_var['force_div_id']) ? ' id="' . $config_var['force_div_id'] . '_dd"' : ''), '> |
|
381 |
+ ', $config_var['label'], ' |
|
382 |
+ </dd>'; |
|
383 |
+ } |
|
384 |
+ // Otherwise it's an input box of some kind. |
|
385 |
+ else |
|
386 |
+ { |
|
387 |
+ echo ' |
|
388 |
+ <dt', is_array($config_var) && !empty($config_var['force_div_id']) ? ' id="' . $config_var['force_div_id'] . '"' : '', '>'; |
|
389 |
+ |
|
390 |
+ // Some quick helpers... |
|
391 |
+ $javascript = $config_var['javascript']; |
|
392 |
+ $disabled = !empty($config_var['disabled']) ? ' disabled="disabled"' : ''; |
|
393 |
+ $subtext = !empty($config_var['subtext']) ? '<br /><span class="smalltext"> ' . $config_var['subtext'] . '</span>' : ''; |
|
394 |
+ |
|
395 |
+ // Show the [?] button. |
|
396 |
+ if ($config_var['help']) |
|
397 |
+ echo ' |
|
398 |
+ <a id="setting_', $config_var['name'], '" href="', $scripturl, '?action=helpadmin;help=', $config_var['help'], '" onclick="return reqWin(this.href);" class="help"><img src="', $settings['images_url'], '/helptopics.gif" alt="', $txt['help'], '" border="0" /></a><span', ($config_var['disabled'] ? ' style="color: #777777;"' : ($config_var['invalid'] ? ' class="error"' : '')), '><label for="', $config_var['name'], '">', $config_var['label'], '</label>', $subtext, ($config_var['type'] == 'password' ? '<br /><em>' . $txt['admin_confirm_password'] . '</em>' : ''), '</span> |
|
399 |
+ </dt>'; |
|
400 |
+ else |
|
401 |
+ echo ' |
|
402 |
+ <a id="setting_', $config_var['name'], '"></a> <span', ($config_var['disabled'] ? ' style="color: #777777;"' : ($config_var['invalid'] ? ' class="error"' : '')), '><label for="', $config_var['name'], '">', $config_var['label'], '</label>', $subtext, ($config_var['type'] == 'password' ? '<br /><em>' . $txt['admin_confirm_password'] . '</em>' : ''), '</span> |
|
403 |
+ </dt>'; |
|
404 |
+ |
|
405 |
+ echo ' |
|
406 |
+ <dd', (!empty($config_var['force_div_id']) ? ' id="' . $config_var['force_div_id'] . '_dd"' : ''), '>', |
|
407 |
+ $config_var['preinput']; |
|
408 |
+ |
|
409 |
+ // Show a check box. |
|
410 |
+ if ($config_var['type'] == 'check') |
|
411 |
+ echo ' |
|
412 |
+ <input type="checkbox"', $javascript, $disabled, ' name="', $config_var['name'], '" id="', $config_var['name'], '"', ($config_var['value'] ? ' checked="checked"' : ''), ' value="1" class="input_check" />'; |
|
413 |
+ // Escape (via htmlspecialchars.) the text box. |
|
414 |
+ elseif ($config_var['type'] == 'password') |
|
415 |
+ echo ' |
|
416 |
+ <input type="password"', $disabled, $javascript, ' name="', $config_var['name'], '[0]"', ($config_var['size'] ? ' size="' . $config_var['size'] . '"' : ''), ' value="*#fakepass#*" onfocus="this.value = \'\'; this.form.', $config_var['name'], '.disabled = false;" class="input_password" /><br /> |
|
417 |
+ <input type="password" disabled="disabled" id="', $config_var['name'], '" name="', $config_var['name'], '[1]"', ($config_var['size'] ? ' size="' . $config_var['size'] . '"' : ''), ' class="input_password" />'; |
|
418 |
+ // Show a selection box. |
|
419 |
+ elseif ($config_var['type'] == 'select') |
|
420 |
+ { |
|
421 |
+ echo ' |
|
422 |
+ <select name="', $config_var['name'], '" id="', $config_var['name'], '" ', $javascript, $disabled, (!empty($config_var['multiple']) ? ' multiple="multiple"' : ''), '>'; |
|
423 |
+ foreach ($config_var['data'] as $option) |
|
424 |
+ echo ' |
|
425 |
+ <option value="', $option[0], '"', (($option[0] == $config_var['value'] || (!empty($config_var['multiple']) && in_array($option[0], $config_var['value']))) ? ' selected="selected"' : ''), '>', $option[1], '</option>'; |
|
426 |
+ echo ' |
|
427 |
+ </select>'; |
|
428 |
+ } |
|
429 |
+ // Text area? |
|
430 |
+ elseif ($config_var['type'] == 'large_text') |
|
431 |
+ { |
|
432 |
+ echo ' |
|
433 |
+ <textarea rows="', ($config_var['size'] ? $config_var['size'] : 4), '" cols="30" ', $javascript, $disabled, ' name="', $config_var['name'], '" id="', $config_var['name'], '">', $config_var['value'], '</textarea>'; |
|
434 |
+ } |
|
435 |
+ // Permission group? |
|
436 |
+ elseif ($config_var['type'] == 'permissions') |
|
437 |
+ { |
|
438 |
+ theme_inline_permissions($config_var['name']); |
|
439 |
+ } |
|
440 |
+ // BBC selection? |
|
441 |
+ elseif ($config_var['type'] == 'bbc') |
|
442 |
+ { |
|
443 |
+ echo ' |
|
444 |
+ <fieldset id="', $config_var['name'], '"> |
|
445 |
+ <legend><strong>', $txt['bbcTagsToUse_select'], '</strong></legend> |
|
446 |
+ <ul class="reset">'; |
|
447 |
+ |
|
448 |
+ foreach ($context['bbc_columns'] as $bbcColumn) |
|
449 |
+ { |
|
450 |
+ foreach ($bbcColumn as $bbcTag) |
|
451 |
+ echo ' |
|
452 |
+ <li class="list_bbc align_left shd_bbc_list"> |
|
453 |
+ <input type="checkbox" name="', $config_var['name'], '_enabledTags[]" id="tag_', $config_var['name'], '_', $bbcTag['tag'], '" value="', $bbcTag['tag'], '"', in_array($bbcTag['tag'], $context['enabled_tags'][$config_var['name']]) ? ' checked="checked"' : '', ' class="input_check" /> <label for="tag_', $config_var['name'], '_', $bbcTag['tag'], '">', $bbcTag['tag'], '</label>', $bbcTag['show_help'] ? ' (<a href="' . $scripturl . '?action=helpadmin;help=tag_' . $bbcTag['tag'] . '" onclick="return reqWin(this.href);">?</a>)' : '', ' |
|
454 |
+ </li>'; |
|
455 |
+ } |
|
456 |
+ echo ' </ul> |
|
457 |
+ <br class="clear" /><input type="checkbox" id="select_all" onclick="invertAll(this, this.form, \'', $config_var['name'], '_enabledTags\');"', $context['all_enabled'][$config_var['name']] ? ' checked="checked"' : '', ' class="input_check" /> <label for="select_all"><em>', $txt['bbcTagsToUse_select_all'], '</em></label> |
|
458 |
+ </fieldset>'; |
|
459 |
+ } |
|
460 |
+ // A simple message? |
|
461 |
+ elseif ($config_var['type'] == 'var_message') |
|
462 |
+ echo ' |
|
463 |
+ <div', !empty($config_var['name']) ? ' id="' . $config_var['name'] . '"' : '', '>', $config_var['var_message'], '</div>'; |
|
464 |
+ // Assume it must be a text box. |
|
465 |
+ else |
|
466 |
+ echo ' |
|
467 |
+ <input type="text"', $javascript, $disabled, ' name="', $config_var['name'], '" id="', $config_var['name'], '" value="', $config_var['value'], '"', ($config_var['size'] ? ' size="' . $config_var['size'] . '"' : ''), ' class="input_text" />'; |
|
468 |
+ |
|
469 |
+ echo isset($config_var['postinput']) ? ' |
|
470 |
+ ' . $config_var['postinput'] : '', |
|
471 |
+ '</dd>'; |
|
472 |
+ } |
|
473 |
+ } |
|
474 |
+ |
|
475 |
+ else |
|
476 |
+ { |
|
477 |
+ // Just show a separator. |
|
478 |
+ if ($config_var == '') |
|
479 |
+ echo ' |
|
480 |
+ </dl> |
|
481 |
+ <hr class="hrcolor" /> |
|
482 |
+ <dl class="settings">'; |
|
483 |
+ else |
|
484 |
+ echo ' |
|
485 |
+ <dd> |
|
486 |
+ <strong>' . $config_var . '</strong> |
|
487 |
+ </dd>'; |
|
488 |
+ } |
|
489 |
+ } |
|
490 |
+ |
|
491 |
+ if ($is_open) |
|
492 |
+ echo ' |
|
493 |
+ </dl>'; |
|
494 |
+ |
|
495 |
+ if (empty($context['settings_save_dont_show'])) |
|
496 |
+ echo ' |
|
497 |
+ <hr class="hrcolor" /> |
|
498 |
+ <div class="righttext"> |
|
499 |
+ <input type="submit" value="', $txt['save'], '"', (!empty($context['save_disabled']) ? ' disabled="disabled"' : ''), (!empty($context['settings_save_onclick']) ? ' onclick="' . $context['settings_save_onclick'] . '"' : ''), ' class="button_submit" /> |
|
500 |
+ </div>'; |
|
501 |
+ |
|
502 |
+ if ($is_open) |
|
503 |
+ echo ' |
|
504 |
+ </div> |
|
505 |
+ <span class="botslice"><span></span></span> |
|
506 |
+ </div> |
|
507 |
+ </div>'; |
|
508 |
+ |
|
509 |
+ echo ' |
|
510 |
+ <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
|
511 |
+ </form> |
|
512 |
+ </div> |
|
513 |
+ <br class="clear" />'; |
|
514 |
+ |
|
515 |
+ if (!empty($context['settings_post_javascript'])) |
|
516 |
+ echo ' |
|
517 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
518 |
+ ', $context['settings_post_javascript'], ' |
|
519 |
+ // ]]></script>'; |
|
520 |
+ |
|
521 |
+ if (!empty($context['settings_insert_below'])) |
|
522 |
+ echo $context['settings_insert_below']; |
|
523 |
+ |
|
524 |
+} |
|
525 |
+ |
|
526 |
+/** |
|
527 |
+ * Display the action log. |
|
528 |
+ * |
|
529 |
+ * Little real work is done in this template; mostly is just iterating through the already-processed contents of the action log as done by {@link shd_admin_action_log()}. |
|
530 |
+ * |
|
531 |
+ * @see shd_admin_action_log() |
|
532 |
+ * @since 1.0 |
|
533 |
+*/ |
|
534 |
+function template_shd_action_log() |
|
535 |
+{ |
|
536 |
+ global $settings, $txt, $context, $scripturl, $sort_types, $modSettings; |
|
537 |
+ |
|
538 |
+ // The sort stuff here is huge. |
|
539 |
+ echo ' |
|
540 |
+ <div class="tborder"> |
|
541 |
+ <div class="cat_bar grid_header"> |
|
542 |
+ <h3 class="catbg"> |
|
543 |
+ <span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span> |
|
544 |
+ <img src="', $settings['default_images_url'], '/simpledesk/log.png" class="icon" alt="*" /> |
|
545 |
+ ', $txt['shd_admin_actionlog_title'], ' |
|
546 |
+ </h3> |
|
547 |
+ </div> |
|
548 |
+ <p class="description shd_actionloginfo"> |
|
549 |
+ ', $txt['shd_admin_actionlog_desc'], '<br /> |
|
550 |
+ ', !empty($modSettings['shd_disable_action_log']) ? '<span class="smalltext">' . $txt['shd_action_log_disabled'] . '</span>' : '', ' |
|
551 |
+ </p> |
|
552 |
+ <table class="shd_ticketlist" cellspacing="0" width="100%"> |
|
553 |
+ <tr class="titlebg"> |
|
554 |
+ <td width="24%" colspan="2"> |
|
555 |
+ <img src="', $settings['default_images_url'], '/simpledesk/action.png" class="shd_smallicon" alt="" /> |
|
556 |
+ <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['sort'] == $sort_types['action'] && !isset($_REQUEST['asc']) ? ';sort=action;asc' : ';sort=action', '"> |
|
557 |
+ ', $txt['shd_admin_actionlog_action'], ' |
|
558 |
+ </a> |
|
559 |
+ ', ($context['sort'] == $sort_types['action'] ? '<img src="' . $settings['default_images_url'] . '/' . (isset($_REQUEST['asc']) ? 'sort_up.gif' : 'sort_down.gif' ). '" alt="" />' : ''), ' |
|
560 |
+ </td> |
|
561 |
+ <td width="20%"> |
|
562 |
+ <img src="', $settings['default_images_url'], '/simpledesk/time.png" class="shd_smallicon" alt="" /> |
|
563 |
+ <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['sort'] == $sort_types['time'] && !isset($_REQUEST['asc']) ? ';sort=time;asc' : ';sort=time', '"> |
|
564 |
+ ', $txt['shd_admin_actionlog_date'], ' |
|
565 |
+ </a> |
|
566 |
+ ', ($context['sort'] == $sort_types['time'] ? '<img src="' . $settings['default_images_url'] . '/' . (isset($_REQUEST['asc']) ? 'sort_up.gif' : 'sort_down.gif' ). '" alt="" />' : ''), ' |
|
567 |
+ </td> |
|
568 |
+ <td width="20%"> |
|
569 |
+ <img src="', $settings['default_images_url'], '/simpledesk/user.png" class="shd_smallicon" alt="" /> |
|
570 |
+ <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['sort'] == $sort_types['member'] && !isset($_REQUEST['asc']) ? ';sort=member;asc' : ';sort=member', '"> |
|
571 |
+ ', $txt['shd_admin_actionlog_member'], ' |
|
572 |
+ </a> |
|
573 |
+ ', ($context['sort'] == $sort_types['member'] ? '<img src="' . $settings['default_images_url'] . '/' . (isset($_REQUEST['asc']) ? 'sort_up.gif' : 'sort_down.gif' ). '" alt="" />' : ''), ' |
|
574 |
+ </td> |
|
575 |
+ <td width="16%"> |
|
576 |
+ <img src="', $settings['default_images_url'], '/simpledesk/position.png" class="shd_smallicon" alt="" /> |
|
577 |
+ <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['sort'] == $sort_types['position'] && !isset($_REQUEST['asc']) ? ';sort=position;asc' : ';sort=position', '"> |
|
578 |
+ ', $txt['shd_admin_actionlog_position'], ' |
|
579 |
+ </a> |
|
580 |
+ ', ($context['sort'] == $sort_types['position'] ? '<img src="' . $settings['default_images_url'] . '/' . (isset($_REQUEST['asc']) ? 'sort_up.gif' : 'sort_down.gif' ). '" alt="" />' : ''), ' |
|
581 |
+ </td> |
|
582 |
+ <td width="20%"> |
|
583 |
+ <img src="', $settings['default_images_url'], '/simpledesk/ip.png" class="shd_smallicon" alt="" /> |
|
584 |
+ <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['sort'] == $sort_types['ip'] && !isset($_REQUEST['asc']) ? ';sort=ip;asc' : ';sort=ip', '"> |
|
585 |
+ ', $txt['shd_admin_actionlog_ip'], ' |
|
586 |
+ </a> |
|
587 |
+ ', ($context['sort'] == $sort_types['ip'] ? '<img src="' . $settings['default_images_url'] . '/' . (isset($_REQUEST['asc']) ? 'sort_up.gif' : 'sort_down.gif' ). '" alt="" />' : ''), ' |
|
588 |
+ </td> |
|
589 |
+ <td width="2%"> </td> |
|
590 |
+ </tr>'; |
|
591 |
+ |
|
592 |
+ if (empty($context['actions'])) |
|
593 |
+ echo ' |
|
594 |
+ <tr class="windowbg2"> |
|
595 |
+ <td colspan="7" class="shd_noticket">', $txt['shd_admin_actionlog_none'], '</td> |
|
596 |
+ </tr>'; |
|
597 |
+ else |
|
598 |
+ { |
|
599 |
+ $use_bg2 = true; // start with windowbg2 to differentiate between that and windowbg2 |
|
600 |
+ foreach ($context['actions'] AS $action) |
|
601 |
+ { |
|
602 |
+ echo ' |
|
603 |
+ <tr class="', ($use_bg2 ? 'windowbg2' : 'windowbg'), '"> |
|
604 |
+ <td width="1%" class="shd_nowrap"> |
|
605 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $action['action_icon'], '" alt="" class="shd_smallicon" /> |
|
606 |
+ </td> |
|
607 |
+ <td class="smalltext">', $action['action_text'], '</td> |
|
608 |
+ <td>', $action['time'], '</td> |
|
609 |
+ <td>', $action['member']['link'], '</td> |
|
610 |
+ <td>', $action['member']['group'], '</td> |
|
611 |
+ <td>', $action['member']['ip'], '</td> |
|
612 |
+ <td>', $action['can_remove'] && $context['can_delete'] ? '<a href="' . $scripturl . '?action=admin;area=helpdesk_actionlog;remove='. $action['id'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_delete_item'] . '" /></a>' : '', '</td> |
|
613 |
+ </tr>'; |
|
614 |
+ |
|
615 |
+ $use_bg2 = !$use_bg2; |
|
616 |
+ } |
|
617 |
+ } |
|
618 |
+ |
|
619 |
+ echo ' |
|
620 |
+ <tr class="titlebg"> |
|
621 |
+ <td colspan="7"> |
|
622 |
+ <span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span> |
|
623 |
+ <span class="smalltext shd_empty_log"><img src="', $settings['default_images_url'], '/simpledesk/delete.png" alt="X" /> <a href="', $scripturl, '?action=admin;area=helpdesk_actionlog', $context['url_sort'], $context['url_order'], ';removeall" onclick="return confirm(', JavaScriptEscape(sprintf($txt['shd_admin_actionlog_removeall_confirm'],$context['hoursdisable'])), ');">', $txt['shd_admin_actionlog_removeall'], '</a></span> |
|
624 |
+ </td> |
|
625 |
+ </tr> |
|
626 |
+ </table> |
|
627 |
+ </div>'; |
|
628 |
+} |
|
629 |
+ |
|
630 |
+/** |
|
631 |
+ * Displays the get-support form for posting directly to the SimpleDesk support board. |
|
632 |
+ * |
|
633 |
+ * This is little more than a simple HTML form, most of the real work is hidden behind the scenes in SimpleDesk's own site. |
|
634 |
+ * |
|
635 |
+ * @see shd_admin_support() |
|
636 |
+ * @since 1.0 |
|
637 |
+*/ |
|
638 |
+function template_shd_support() |
|
639 |
+{ |
|
640 |
+ global $context, $settings, $txt, $forum_version; |
|
641 |
+ |
|
642 |
+ // Information box. |
|
643 |
+ echo ' |
|
644 |
+ <div class="tborder"> |
|
645 |
+ <h3 class="catbg"><span class="left"></span> |
|
646 |
+ <span class="ie6_header floatleft"> |
|
647 |
+ <img src="', $settings['default_images_url'], '/simpledesk/support.png" class="icon" alt="*" /> ', $txt['shd_admin_support'], ' |
|
648 |
+ </span> |
|
649 |
+ </h3> |
|
650 |
+ <p class="windowbg description shd_info_box"> |
|
651 |
+ ', $txt['shd_admin_support_desc'], ' |
|
652 |
+ </p> |
|
653 |
+ </div> |
|
654 |
+ <br /> |
|
655 |
+ <div class="shd_admin_leftcolumn floatleft"> |
|
656 |
+ <div class="tborder"> |
|
657 |
+ <div class="cat_bar grid_header"> |
|
658 |
+ <h3 class="catbg"> |
|
659 |
+ <img src="', $settings['default_images_url'], '/simpledesk/edit.png" alt="*" /> ', $txt['shd_admin_support_form_title'], ' |
|
660 |
+ </h3> |
|
661 |
+ </div> |
|
662 |
+ <div class="roundframe"> |
|
663 |
+ <form action="', $context['shd_support_url'], '" method="post" class="content"> |
|
664 |
+ <dl id="post_header"> |
|
665 |
+ <dt><span id="caption_subject">', $txt['subject'], '</span></dt> |
|
666 |
+ <dd><input type="text" name="subject" tabindex="1" size="80" maxlength="80" class="input_text" /></dd> |
|
667 |
+ </dl> |
|
668 |
+ <textarea class="editor" name="message" rows="12" cols="60" tabindex="2" style="width: 90%; height: 150px;"></textarea> |
|
669 |
+ <br /><br /> |
|
670 |
+ <input type="hidden" value="', $forum_version, '" name="smf_version" /> |
|
671 |
+ <input type="hidden" value="', $context['shd_version'], '" name="shd_version" /> |
|
672 |
+ <input type="submit" value="', $txt['shd_admin_support_send'], '" tabindex="3" accesskey="s" class="button_submit" /> |
|
673 |
+ </form> |
|
674 |
+ </div> |
|
675 |
+ <span class="lowerframe"><span></span></span> |
|
676 |
+ </div> |
|
677 |
+ </div> |
|
678 |
+ <div class="shd_admin_rightcolumn floatleft"> |
|
679 |
+ <div class="tborder"> |
|
680 |
+ <div class="title_bar grid_header"> |
|
681 |
+ <h3 class="titlebg sd_no_margin"> |
|
682 |
+ <img src="', $settings['images_url'], '/helptopics.gif" alt="?" /> ', $txt['shd_admin_support_what_is_this'], ' |
|
683 |
+ </h3> |
|
684 |
+ </div> |
|
685 |
+ <div class="windowbg2"> |
|
686 |
+ <div class="content smalltext"> |
|
687 |
+ ', $txt['shd_admin_support_explanation'], ' |
|
688 |
+ </div> |
|
689 |
+ <span class="botslice"><span></span></span> |
|
690 |
+ </div> |
|
691 |
+ </div> |
|
692 |
+ </div> |
|
693 |
+ <br class="clear" />'; |
|
694 |
+} |
|
695 |
+ |
|
696 |
+?> |
|
0 | 697 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,81 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk ticket assignment |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * Handles ticket assignment. |
|
6 |
+ * |
|
7 |
+ * @package template |
|
8 |
+ * @since 1.0 |
|
9 |
+*/ |
|
10 |
+ |
|
11 |
+/** |
|
12 |
+ * Displays the list of possible users a ticket can have assigned. |
|
13 |
+ * |
|
14 |
+ * Will have been populated by shd_assign() in SimpleDesk-Assign.php, adding into $context['member_list']. |
|
15 |
+ * |
|
16 |
+ * This allows users to assign tickets to other users, or themselves, or to unassign a previously assigned ticket. Future versions will |
|
17 |
+ * likely add further options here. |
|
18 |
+ * |
|
19 |
+ * @see shd_assign() |
|
20 |
+ * @since 1.0 |
|
21 |
+*/ |
|
22 |
+function template_assign() |
|
23 |
+{ |
|
24 |
+ global $context, $txt, $scripturl, $settings; |
|
25 |
+ |
|
26 |
+ if (empty($context['shd_return_to'])) |
|
27 |
+ $context['shd_return_to'] = 'ticket'; |
|
28 |
+ |
|
29 |
+ // Back to the helpdesk. |
|
30 |
+ echo ' |
|
31 |
+ <div class="floatleft"> |
|
32 |
+ ', template_button_strip(array($context['navigation']['back']), 'bottom'), ' |
|
33 |
+ </div><br class="clear" /><br />'; |
|
34 |
+ |
|
35 |
+ echo ' |
|
36 |
+ <div class="cat_bar grid_header"> |
|
37 |
+ <h3 class="catbg"> |
|
38 |
+ <img src="', $settings['default_images_url'], '/simpledesk/assign.png" alt="*" /> |
|
39 |
+ ', $txt['shd_ticket_assign_ticket'], ' |
|
40 |
+ </h3> |
|
41 |
+ </div> |
|
42 |
+ <div class="roundframe"> |
|
43 |
+ <form action="', $scripturl, '?action=helpdesk;sa=assign2;ticket=', $context['ticket_id'], '" method="post" onsubmit="submitonce(this);"> |
|
44 |
+ <div class="content"> |
|
45 |
+ <dl class="settings"> |
|
46 |
+ <dt> |
|
47 |
+ <strong>', $txt['shd_ticket_assignedto'], ':</strong> |
|
48 |
+ </dt> |
|
49 |
+ <dd> |
|
50 |
+ ', $context['member_list'][$context['ticket_assigned']], ' |
|
51 |
+ </dd> |
|
52 |
+ <dt> |
|
53 |
+ <strong>', $txt['shd_ticket_assign_to'], ':</strong> |
|
54 |
+ </dt> |
|
55 |
+ <dd> |
|
56 |
+ <select name="to_user">'; |
|
57 |
+ |
|
58 |
+ foreach ($context['member_list'] as $id => $name) |
|
59 |
+ echo ' |
|
60 |
+ <option value="', $id, '"', ($id == $context['ticket_assigned'] ? ' selected="selected"' : ''), '>', $name, '</option>'; |
|
61 |
+ |
|
62 |
+ echo ' |
|
63 |
+ </select> |
|
64 |
+ </dd> |
|
65 |
+ </dl> |
|
66 |
+ <input type="submit" value="', $txt['shd_ticket_assign_ticket'], '" onclick="return submitThisOnce(this);" accesskey="s" class="button_submit" /> |
|
67 |
+ <input type="submit" name="cancel" value="', ($context['shd_return_to'] == 'home' ? $txt['shd_cancel_home'] : $txt['shd_cancel_ticket']), '" accesskey="c" class="button_submit" /> |
|
68 |
+ <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />'; |
|
69 |
+ |
|
70 |
+ if ($context['shd_return_to'] == 'home') |
|
71 |
+ echo ' |
|
72 |
+ <input type="hidden" name="home" value="1" />'; |
|
73 |
+ |
|
74 |
+ echo ' |
|
75 |
+ </div> |
|
76 |
+ </form> |
|
77 |
+ </div> |
|
78 |
+ <span class="lowerframe"><span></span></span>'; |
|
79 |
+} |
|
80 |
+ |
|
81 |
+?> |
|
0 | 82 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,374 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk ticket display |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * This file handles just displaying a ticket, its replies and working with SimpleDesk-Post.template.php to arrange the quick reply area. |
|
6 |
+ * |
|
7 |
+ * @package template |
|
8 |
+ * @since 1.0 |
|
9 |
+*/ |
|
10 |
+ |
|
11 |
+/** |
|
12 |
+ * Display the main view of a ticket. |
|
13 |
+ * |
|
14 |
+ * It is responsible for all the processing and display of the data gathered in {@link shd_view_ticket()} to the user, and in fact there |
|
15 |
+ * is little to discuss other than simply displaying the ticket in given HTML. |
|
16 |
+ * |
|
17 |
+ * It is also responsible for displaying attachments either to the ticket (in attachments-in-ticket mode) or to the first post |
|
18 |
+ * (in attachments-in-replies mode), and calling upon the posting routines to set up display of 'advanced' mode in quick reply. |
|
19 |
+ * |
|
20 |
+ * @see shd_view_ticket() |
|
21 |
+ * @see template_ticket_postbox() |
|
22 |
+ * @see template_ticket_meta() |
|
23 |
+ * @since 1.0 |
|
24 |
+*/ |
|
25 |
+function template_viewticket() |
|
26 |
+{ |
|
27 |
+ global $context, $txt, $scripturl, $settings, $modSettings, $options; |
|
28 |
+ |
|
29 |
+ // Back to the helpdesk. |
|
30 |
+ echo'<div class="floatleft">', template_button_strip(array($context['navigation']['back']), 'bottom'), '</div>', ($modSettings['shd_ticketnav_style'] != 'smf' ? '<br class="clear" /><br />' : ''), ''; |
|
31 |
+ |
|
32 |
+ if ($modSettings['shd_ticketnav_style'] == 'smf') |
|
33 |
+ { |
|
34 |
+ template_button_strip($context['ticket_navigation'], 'right'); |
|
35 |
+ echo '<br class="clear" />'; |
|
36 |
+ } |
|
37 |
+ |
|
38 |
+ echo ' |
|
39 |
+ <div class="tborder"> |
|
40 |
+ <div class="cat_bar grid_header"> |
|
41 |
+ <h3 class="catbg ticketheader"> |
|
42 |
+ <span class="floatright smalltext shd_ticketlinks" id="ticket">'; |
|
43 |
+ |
|
44 |
+ if ($modSettings['shd_ticketnav_style'] == 'sd') |
|
45 |
+ { |
|
46 |
+ foreach ($context['ticket_navigation'] as $button) |
|
47 |
+ if (!empty($button['display'])) |
|
48 |
+ echo ' |
|
49 |
+ <a href="', $button['url'], '"', (!empty($button['is_last']) ? ' id="last"' : ''), '', (!empty($button['onclick']) ? ' onclick="' . $button['onclick'] . '"' : ''), '><img src="', $settings['default_images_url'], '/simpledesk/', $button['icon'], '.png" alt="', $button['alt'], '" title="', $txt[$button['text']], '" /> ', $txt[$button['text']], '</a>'; |
|
50 |
+ } |
|
51 |
+ elseif ($modSettings['shd_ticketnav_style'] == 'sdcompact') |
|
52 |
+ { |
|
53 |
+ foreach ($context['ticket_navigation'] as $button) |
|
54 |
+ if (!empty($button['display'])) |
|
55 |
+ echo ' |
|
56 |
+ <a href="', $button['url'], '"', (!empty($button['is_last']) ? ' id="last"' : ''), '', (!empty($button['onclick']) ? ' onclick="' . $button['onclick'] . '"' : ''), '><img src="', $settings['default_images_url'], '/simpledesk/', $button['icon'], '.png" alt="', $button['alt'], '" title="', $txt[$button['text']], '" /></a>'; |
|
57 |
+ } |
|
58 |
+ |
|
59 |
+ echo ' |
|
60 |
+ </span> |
|
61 |
+ <img src="', $settings['default_images_url'], '/simpledesk/ticket.png" alt="x" /> ', $context['ticket']['subject'], ' [', $context['ticket']['display_id'], '] |
|
62 |
+ </h3> |
|
63 |
+ </div> |
|
64 |
+ <div class="windowbg"> |
|
65 |
+ <div class="content shd_ticket">'; |
|
66 |
+ |
|
67 |
+ // General ticket details |
|
68 |
+ echo ' |
|
69 |
+ <div class="information shd_ticketdetails"> |
|
70 |
+ <strong><img src="', $settings['default_images_url'], '/simpledesk/details.png" alt="" class="shd_smallicon shd_icon_minihead" /> ', $txt['shd_ticket_details'], '</strong> |
|
71 |
+ <hr /> |
|
72 |
+ <ul> |
|
73 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/id.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_id'], ': ', $context['ticket']['display_id'], '</li> |
|
74 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/user.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_user'], ': ', $context['ticket']['member']['link'], '</li> |
|
75 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/time.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_date'], ': ', $context['ticket']['poster_time'], '</li> |
|
76 |
+ <li> |
|
77 |
+ <img src="', $settings['default_images_url'], '/simpledesk/urgency.png" alt="" class="shd_smallicon" /> |
|
78 |
+ ', $txt['shd_ticket_urgency'], ': <span id="urgency">', $context['ticket']['urgency']['label'], '</span> |
|
79 |
+ <span id="urgency_increase">', (!empty($context['ticket']['urgency']['increase']) ? '<a id="urglink_increase" href="' . $scripturl . '?action=helpdesk;sa=urgencychange;ticket=' . $context['ticket']['id'] . ';change=increase;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_urgency_increase'] . '"><img src="' . $settings['images_url'] . '/sort_up.gif" width="9px" alt="' . $txt['shd_urgency_increase'] . '" /></a>' : ''), '</span> |
|
80 |
+ <span id="urgency_decrease">', (!empty($context['ticket']['urgency']['decrease']) ? '<a id="urglink_decrease" href="' . $scripturl . '?action=helpdesk;sa=urgencychange;ticket=' . $context['ticket']['id'] . ';change=decrease;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_urgency_decrease'] . '"><img src="' . $settings['images_url'] . '/sort_down.gif" width="9px" alt="' . $txt['shd_urgency_decrease'] . '" /></a>' : ''), '</span> |
|
81 |
+ </li> |
|
82 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/staff.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_assignedto'], ': ', $context['ticket']['assigned']['link'], '</li> |
|
83 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/status.png" alt="" class="shd_smallicon"/> ', $txt['shd_ticket_status'], ': ', $context['ticket']['status']['label'], '</li> |
|
84 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_num_replies'], ': <a href="#replies">', (empty($context['ticket']['display_recycle']) ? $context['ticket']['num_replies'] : (int) $context['ticket']['num_replies'] + (int) $context['ticket']['deleted_replies']), '</a></li>'; |
|
85 |
+ |
|
86 |
+ if (!empty($context['display_private'])) |
|
87 |
+ echo ' |
|
88 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/private.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_privacy'], ': <span id="privacy">', $context['ticket']['privacy']['label'], '</span>', ($context['ticket']['privacy']['can_change'] ? ' (<a id="privlink" href="' . $scripturl . '?action=helpdesk;sa=privacychange;ticket=' . $context['ticket']['id'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['shd_ticket_change'] . '</a>)' : ''), '</li>'; |
|
89 |
+ |
|
90 |
+ if (!empty($context['can_see_ip']) && !empty($context['ticket']['ip_address'])) |
|
91 |
+ echo ' |
|
92 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/ip.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_ip'], ': ', $context['ticket']['ip_address'], '</li>'; |
|
93 |
+ |
|
94 |
+ echo ' |
|
95 |
+ </ul>'; |
|
96 |
+ |
|
97 |
+ // Display ticket poster avatar? |
|
98 |
+ if (!empty($modSettings['shd_display_avatar']) && empty($options['show_no_avatars']) && !empty($context['ticket']['poster_avatar']['image'])) |
|
99 |
+ echo ' |
|
100 |
+ <div class="shd_ticket_avatar"> |
|
101 |
+ ', $context['ticket']['poster_avatar']['image'], ' |
|
102 |
+ </div>'; |
|
103 |
+ |
|
104 |
+ echo ' |
|
105 |
+ </div>'; |
|
106 |
+ |
|
107 |
+ echo ' |
|
108 |
+ <div class="shd_ticket_description">'; |
|
109 |
+ |
|
110 |
+ if (!empty($context['ticket']['display_recycle'])) |
|
111 |
+ echo ' |
|
112 |
+ <div class="errorbox" id="recycle_warning"> |
|
113 |
+ <img src="', $settings['default_images_url'], '/simpledesk/delete.png" alt="" /> ', $context['ticket']['display_recycle'], ' |
|
114 |
+ </div>'; |
|
115 |
+ |
|
116 |
+ echo ' |
|
117 |
+ <img src="', $settings['default_images_url'], '/simpledesk/name.png" alt="" class="shd_smallicon shd_icon_minihead" /> <strong>', $context['ticket']['subject'], '</strong><hr /><br /> |
|
118 |
+ <div id="shd_ticket_text"> |
|
119 |
+ ', $context['ticket']['body']; |
|
120 |
+ |
|
121 |
+ if ($settings['show_modify'] && !empty($context['ticket']['modified'])) |
|
122 |
+ { |
|
123 |
+ echo ' |
|
124 |
+ <div class="smalltext shd_modified"> |
|
125 |
+ « <em>', $txt['last_edit'], ': ', $context['ticket']['modified']['time'], ' ', $txt['by'], ' ', $context['ticket']['modified']['link'], '</em> » |
|
126 |
+ </div>'; |
|
127 |
+ } |
|
128 |
+ |
|
129 |
+ echo' |
|
130 |
+ </div>'; |
|
131 |
+ |
|
132 |
+ if ($context['can_reply']) |
|
133 |
+ echo ' |
|
134 |
+ <br /> |
|
135 |
+ <div class="description shd_replybutton floatright" id="shd_replybutton"> |
|
136 |
+ <a href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';num_replies=', $context['ticket']['num_replies'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_reply'], '</a><br /> |
|
137 |
+ </div>'; |
|
138 |
+ |
|
139 |
+ if ($context['can_quote']) |
|
140 |
+ echo ' |
|
141 |
+ <div class="description shd_quotebutton floatright" id="shd_quotebutton"> |
|
142 |
+ <a onclick="return oQuickReply.quote(', $context['ticket']['first_msg'], ', \'', $context['session_id'], '\', \'', $context['session_var'], '\', true);" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';quote=', $context['ticket']['first_msg'], ';num_replies=', $context['ticket']['num_replies'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_quote'], '</a><br /> |
|
143 |
+ </div>'; |
|
144 |
+ |
|
145 |
+ if (!empty($context['ticket_attach']['reply'][$context['ticket']['first_msg']])) |
|
146 |
+ { |
|
147 |
+ echo ' |
|
148 |
+ <div class="information shd_reply_attachments"> |
|
149 |
+ <dl id="postAttachment"> |
|
150 |
+ <dt> |
|
151 |
+ ', $txt['attached'], ': |
|
152 |
+ </dt>'; |
|
153 |
+ foreach ($context['ticket_attach']['reply'][$context['ticket']['first_msg']] as $attachment) |
|
154 |
+ echo ' |
|
155 |
+ <dd class="smalltext"> |
|
156 |
+ ', $attachment['link'], ' |
|
157 |
+ </dd>'; |
|
158 |
+ echo ' |
|
159 |
+ </dl> |
|
160 |
+ </div>'; |
|
161 |
+ } |
|
162 |
+ |
|
163 |
+ echo ' |
|
164 |
+ </div> |
|
165 |
+ </div> |
|
166 |
+ <span class="botslice"><span></span></span> |
|
167 |
+ </div> |
|
168 |
+ </div> |
|
169 |
+ <br />'; |
|
170 |
+ |
|
171 |
+ // The attachments column |
|
172 |
+ if (!empty($context['ticket_attach']['ticket'])) |
|
173 |
+ { |
|
174 |
+ echo ' |
|
175 |
+ <div class="shd_ticket_leftcolumn floatleft"> |
|
176 |
+ <div class="tborder shd_attachmentcolumn"> |
|
177 |
+ <div class="title_bar grid_header"> |
|
178 |
+ <h3 class="titlebg"> |
|
179 |
+ <img src="', $settings['default_images_url'], '/simpledesk/attachments.png" alt="x" />', $txt['shd_ticket_attachments'], ' (', count($context['ticket_attach']['ticket']), ') |
|
180 |
+ </h3> |
|
181 |
+ </div> |
|
182 |
+ <div class="windowbg2"> |
|
183 |
+ <div class="shd_attachmentbox">'; |
|
184 |
+ |
|
185 |
+ foreach ($context['ticket_attach']['ticket'] as $attachment) |
|
186 |
+ { |
|
187 |
+ echo ' |
|
188 |
+ <div class="description shd_attachment" id="attach', $attachment['id'], '"> |
|
189 |
+ <strong>', $attachment['link'], '</strong> |
|
190 |
+ <span class="smalltext"> |
|
191 |
+ (', $attachment['size'], ') |
|
192 |
+ </span> |
|
193 |
+ </div>'; |
|
194 |
+ } |
|
195 |
+ |
|
196 |
+ echo ' |
|
197 |
+ </div> |
|
198 |
+ <span class="botslice"><span></span></span> |
|
199 |
+ </div> |
|
200 |
+ </div> |
|
201 |
+ </div>'; |
|
202 |
+ } |
|
203 |
+ |
|
204 |
+ // The replies column |
|
205 |
+ echo ' |
|
206 |
+ <div class="shd_ticket_rightcolumn floatleft"', empty($context['ticket_attach']['ticket']) ? ' style="width: 100%;"' : '', '>', template_viewreplies(), '</div><br class="clear" />'; |
|
207 |
+ |
|
208 |
+ // Our mighty quick reply box :D |
|
209 |
+ if ($context['can_reply'] && !empty($options['display_quick_reply'])) |
|
210 |
+ { |
|
211 |
+ echo ' |
|
212 |
+ <br /> |
|
213 |
+ <div class="tborder"> |
|
214 |
+ <div class="title_bar', $options['display_quick_reply'] == 2 ? ' grid_header' : '', '" id="quickreplyheader" > |
|
215 |
+ <h3 class="titlebg"> |
|
216 |
+ <span class="floatright"><a href="javascript:oQuickReply.swap();"><img src="', $settings['images_url'], '/', $options['display_quick_reply'] == 2 ? 'collapse' : 'expand', '.gif" alt="+" id="quickReplyExpand" class="icon" /></a></span> |
|
217 |
+ <img src="', $settings['default_images_url'], '/simpledesk/respond.png" alt="x" /> |
|
218 |
+ <a href="javascript:oQuickReply.swap();">', $txt['shd_reply_ticket'], '</a> |
|
219 |
+ </h3> |
|
220 |
+ </div> |
|
221 |
+ <div class="roundframe" id="quickReplyOptions"', $options['display_quick_reply'] == 2 ? '' : ' style="display: none"', '> |
|
222 |
+ <div class="content"> |
|
223 |
+ <form action="', $scripturl, '?action=helpdesk;sa=savereply" method="post" accept-charset="', $context['character_set'], '" name="postreply" id="postreply" onsubmit="submitonce(this);smc_saveEntities(\'postreply\', [\'shd_reply\'], \'options\');" enctype="multipart/form-data" style="margin: 0;">'; |
|
224 |
+ |
|
225 |
+ if ($context['can_go_advanced']) |
|
226 |
+ { |
|
227 |
+ echo ' |
|
228 |
+ <div class="description shd_advancedbutton floatright" id="shd_goadvancedbutton"> |
|
229 |
+ <a onclick="goAdvanced(); return false;" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_go_advanced'], '</a><br /> |
|
230 |
+ </div>'; |
|
231 |
+ } |
|
232 |
+ |
|
233 |
+ template_ticket_postbox(); |
|
234 |
+ template_ticket_meta(); |
|
235 |
+ |
|
236 |
+ echo ' |
|
237 |
+ </form> |
|
238 |
+ </div> |
|
239 |
+ </div> |
|
240 |
+ <span id="quickreplyfooter" class="lowerframe"', $options['display_quick_reply'] == 2 ? '' : ' style="display: none"', '><span></span></span> |
|
241 |
+ </div>'; |
|
242 |
+ } |
|
243 |
+ |
|
244 |
+} |
|
245 |
+ |
|
246 |
+/** |
|
247 |
+ * Display all the replies to a ticket. |
|
248 |
+ * |
|
249 |
+ * This function deals simply with viewing of replies in a ticket, including deleted replies, which is initialised in {@link shd_view_ticket()} |
|
250 |
+ * and data gathered through the {@link shd_prepare_ticket_context()} call back, which simply deals with a single reply at a time. |
|
251 |
+ * |
|
252 |
+ * @see shd_view_ticket() |
|
253 |
+ * @see templaet_view_ticket() |
|
254 |
+ * @since 1.0 |
|
255 |
+*/ |
|
256 |
+function template_viewreplies() |
|
257 |
+{ |
|
258 |
+ global $context, $settings, $txt, $scripturl, $options, $modSettings, $reply_request; |
|
259 |
+ |
|
260 |
+ echo ' |
|
261 |
+ <div class="tborder"> |
|
262 |
+ <div class="title_bar grid_header"> |
|
263 |
+ <h3 class="titlebg"> |
|
264 |
+ <span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span> |
|
265 |
+ <img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="x" /> ', $txt['shd_ticket_replies'], ' |
|
266 |
+ </h3> |
|
267 |
+ </div> |
|
268 |
+ <div class="roundframe" id="replies"> |
|
269 |
+ <div class="content">'; |
|
270 |
+ |
|
271 |
+ if (empty($reply_request)) |
|
272 |
+ { |
|
273 |
+ echo $txt['shd_no_replies']; |
|
274 |
+ } |
|
275 |
+ else |
|
276 |
+ { |
|
277 |
+ while ($reply = $context['get_replies']()) |
|
278 |
+ { |
|
279 |
+ echo ' |
|
280 |
+ <div class="description shd_reply', (!empty($context['ticket']['display_recycle']) && $reply['message_status'] == MSG_STATUS_DELETED ? ' errorbox' : ''), '" id="msg', $reply['id'], '"> |
|
281 |
+ <span class="floatleft shd_posterinfo"> |
|
282 |
+ <strong class="shd_postername"> |
|
283 |
+ ', $reply['member']['link'], ' |
|
284 |
+ </strong> |
|
285 |
+ <br /> |
|
286 |
+ ', $reply['member']['group'], '<br class="shd_groupmargin" />'; |
|
287 |
+ |
|
288 |
+ if (!empty($modSettings['shd_display_avatar']) && empty($options['show_no_avatars']) && !empty($reply['member']['avatar']['image'])) |
|
289 |
+ echo ' |
|
290 |
+ ', $reply['member']['avatar']['image']; |
|
291 |
+ |
|
292 |
+ if ($modSettings['shd_staff_badge'] == (!empty($reply['is_team']) ? 'staffbadge' : 'userbadge') || $modSettings['shd_staff_badge'] == 'bothbadge') |
|
293 |
+ echo '<br /> |
|
294 |
+ ', $reply['member']['group_stars']; |
|
295 |
+ elseif (!empty($reply['is_team']) && $modSettings['shd_staff_badge'] == 'nobadge') |
|
296 |
+ echo '<br /> |
|
297 |
+ <img src="', $settings['default_images_url'] . '/simpledesk/staff.png" class="shd_smallicon" title="', $txt['shd_ticket_staff'], '" alt="', $txt['shd_ticket_staff'], '" />'; |
|
298 |
+ |
|
299 |
+ echo ' |
|
300 |
+ </span> |
|
301 |
+ <div class="shd_replyarea"> |
|
302 |
+ <div class="smalltext"> |
|
303 |
+ <span class="floatright shd_ticketlinks">'; |
|
304 |
+ if ($context['can_quote']) |
|
305 |
+ echo ' |
|
306 |
+ <img src="', $settings['default_images_url'], '/simpledesk/quote.png" class="shd_smallicon" alt="*" /><a onclick="return oQuickReply.quote(', $reply['id'], ', \'', $context['session_id'], '\', \'', $context['session_var'], '\', true);" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';quote=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_quote_short'], '</a>'; |
|
307 |
+ if ($reply['can_edit']) |
|
308 |
+ echo ' |
|
309 |
+ <img src="', $settings['default_images_url'], '/simpledesk/edit.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=editreply;ticket=', $context['ticket_id'], ';msg=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_edit'], '</a>'; |
|
310 |
+ if ($reply['can_delete']) |
|
311 |
+ echo ' |
|
312 |
+ <img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=deletereply;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_delete_reply_confirm']), ');">', $txt['shd_ticket_delete'], '</a>'; |
|
313 |
+ if ($reply['can_restore']) |
|
314 |
+ echo ' |
|
315 |
+ <img src="', $settings['default_images_url'], '/simpledesk/restore.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=restorereply;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_restore'], '</a>'; |
|
316 |
+ if ($reply['can_permadelete']) |
|
317 |
+ echo ' |
|
318 |
+ <img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=permadelete;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_delete_permanently_confirm']), ');">', $txt['shd_delete_permanently'], '</a>'; |
|
319 |
+ |
|
320 |
+ echo ' |
|
321 |
+ </span> |
|
322 |
+ ', sprintf($txt['shd_reply_written'], $reply['time']), ' |
|
323 |
+ </div> |
|
324 |
+ <hr class="clearfix" /> |
|
325 |
+ ', $reply['body'], ' |
|
326 |
+ <br /><br />'; |
|
327 |
+ |
|
328 |
+ if ($settings['show_modify'] && !empty($reply['modified'])) |
|
329 |
+ { |
|
330 |
+ echo ' |
|
331 |
+ <div class="smalltext shd_modified" style="margin-top:20px;"> |
|
332 |
+ « <em>', $txt['last_edit'], ': ', $reply['modified']['time'], ' ', $txt['by'], ' ', $reply['modified']['link'], '</em> » |
|
333 |
+ </div>'; |
|
334 |
+ } |
|
335 |
+ |
|
336 |
+ if (!empty($context['ticket_attach']['reply'][$reply['id']])) |
|
337 |
+ { |
|
338 |
+ echo ' |
|
339 |
+ <div class="smalltext"> |
|
340 |
+ <strong>', $txt['shd_ticket_attachments'], '</strong><br /> |
|
341 |
+ <ul class="shd_replyattachments">'; |
|
342 |
+ |
|
343 |
+ foreach ($context['ticket_attach']['reply'][$reply['id']] as $attach) |
|
344 |
+ echo ' |
|
345 |
+ <li>', $attach['link'], '</li>'; |
|
346 |
+ |
|
347 |
+ echo ' |
|
348 |
+ </ul> |
|
349 |
+ </div>'; |
|
350 |
+ } |
|
351 |
+ |
|
352 |
+ echo ' |
|
353 |
+ </div>'; |
|
354 |
+ |
|
355 |
+ if (!empty($context['can_see_ip']) && !empty($reply['ip_address'])) |
|
356 |
+ echo ' |
|
357 |
+ <span class="floatright"><img src="', $settings['default_images_url'], '/simpledesk/ip.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_ip'], ': ', $reply['ip_address'], '</span>'; |
|
358 |
+ |
|
359 |
+ echo ' |
|
360 |
+ <br class="clear" /> |
|
361 |
+ </div>'; |
|
362 |
+ } |
|
363 |
+ } |
|
364 |
+ |
|
365 |
+ echo ' |
|
366 |
+ </div> |
|
367 |
+ <span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span> |
|
368 |
+ <br class="clear" /> |
|
369 |
+ </div> |
|
370 |
+ <span class="lowerframe"><span></span></span> |
|
371 |
+ </div>'; |
|
372 |
+} |
|
373 |
+ |
|
374 |
+?> |
|
0 | 375 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,583 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk posting and replying |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * This file handles everything concerning posting, including displaying the display of ticket facia |
|
6 |
+ * around a post box, display of replies with insert-quote links, the postbox, attachments, errors etc. |
|
7 |
+ * |
|
8 |
+ * @package template |
|
9 |
+ * @todo Finish documenting this file. |
|
10 |
+ * @since 1.0 |
|
11 |
+*/ |
|
12 |
+ |
|
13 |
+/** |
|
14 |
+ * Entry point for displaying the post new ticket/edit ticket UI. |
|
15 |
+ * |
|
16 |
+ * @since 1.0 |
|
17 |
+*/ |
|
18 |
+ |
|
19 |
+function template_ticket_post() |
|
20 |
+{ |
|
21 |
+ global $context; |
|
22 |
+ |
|
23 |
+ // Back to the helpdesk. |
|
24 |
+ echo ' |
|
25 |
+ <div class="floatleft"> |
|
26 |
+ ', template_button_strip(array($context['navigation']['back']), 'bottom'), ' |
|
27 |
+ </div><br class="clear" /><br />'; |
|
28 |
+ |
|
29 |
+ template_preview(); |
|
30 |
+ template_ticket_info(); |
|
31 |
+ template_ticket_subjectbox(); |
|
32 |
+ template_ticket_meta(); |
|
33 |
+ template_ticket_postbox(); |
|
34 |
+ template_ticket_footer(); |
|
35 |
+ if (!empty($context['ticket_form']['do_replies'])) |
|
36 |
+ { |
|
37 |
+ template_ticket_begin_replies(); |
|
38 |
+ template_ticket_do_replies(); |
|
39 |
+ template_ticket_end_replies(); |
|
40 |
+ } |
|
41 |
+ template_ticket_pageend(); |
|
42 |
+} |
|
43 |
+ |
|
44 |
+function template_reply_post() |
|
45 |
+{ |
|
46 |
+ global $context; |
|
47 |
+ |
|
48 |
+ template_ticket_info(); |
|
49 |
+ template_ticket_content(); |
|
50 |
+ template_ticket_meta(); |
|
51 |
+ template_ticket_footer(); |
|
52 |
+ template_preview(); |
|
53 |
+ template_ticket_shd_replyarea(); |
|
54 |
+ if (!empty($context['ticket_form']['do_replies'])) |
|
55 |
+ { |
|
56 |
+ template_ticket_begin_replies(); |
|
57 |
+ template_ticket_do_replies(); |
|
58 |
+ template_ticket_end_replies(); |
|
59 |
+ } |
|
60 |
+ template_ticket_pageend(); |
|
61 |
+} |
|
62 |
+ |
|
63 |
+// yes, this isn't strictly conventional SMF style |
|
64 |
+function template_ticket_option($option) |
|
65 |
+{ |
|
66 |
+ global $context, $txt; |
|
67 |
+ |
|
68 |
+ if (!empty($context['ticket_form'][$option]['can_change'])) |
|
69 |
+ { |
|
70 |
+ echo ' |
|
71 |
+ <select name="shd_' . $option . '">'; |
|
72 |
+ foreach ($context['ticket_form'][$option]['options'] as $value => $caption) |
|
73 |
+ { |
|
74 |
+ echo ' |
|
75 |
+ <option value="', $value, '"', ($value == $context['ticket_form'][$option]['setting'] ? ' selected="selected"' : ''), '>', $txt[$caption], '</option>'; |
|
76 |
+ } |
|
77 |
+ echo ' |
|
78 |
+ </select>'; |
|
79 |
+ } |
|
80 |
+ else |
|
81 |
+ echo $txt[$context['ticket_form'][$option]['options'][$context['ticket_form'][$option]['setting']]]; |
|
82 |
+} |
|
83 |
+ |
|
84 |
+function template_ticket_info() |
|
85 |
+{ |
|
86 |
+ global $context, $txt, $scripturl, $settings, $modSettings, $options; |
|
87 |
+ |
|
88 |
+ echo ' |
|
89 |
+ <form action="', $context['ticket_form']['form_action'], '" method="post" accept-charset="', $context['character_set'], '" name="postmodify" id="postmodify" onsubmit="', 'submitonce(this);smc_saveEntities(\'postmodify\', [\'subject\', \'', $context['post_box_name'], '\'], \'options\');" enctype="multipart/form-data" style="margin: 0;"> |
|
90 |
+ <div class="tborder"> |
|
91 |
+ <div class="cat_bar grid_header"> |
|
92 |
+ <h3 class="catbg"> |
|
93 |
+ <img src="', $settings['default_images_url'], '/simpledesk/ticket.png" alt="x" /> ', $context['ticket_form']['form_title'], ' |
|
94 |
+ </h3> |
|
95 |
+ </div> |
|
96 |
+ <div class="windowbg"> |
|
97 |
+ <div class="content shd_ticket">'; |
|
98 |
+ |
|
99 |
+ // General ticket details |
|
100 |
+ echo ' |
|
101 |
+ <div class="information shd_ticketdetails"> |
|
102 |
+ <strong><img src="', $settings['default_images_url'], '/simpledesk/details.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_details'], '</strong> |
|
103 |
+ <hr /> |
|
104 |
+ <ul>'; |
|
105 |
+ |
|
106 |
+ if (!empty($context['ticket_form']['display_id'])) |
|
107 |
+ echo ' |
|
108 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/id.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_id'], ': ', $context['ticket_form']['display_id'], '</li>'; |
|
109 |
+ |
|
110 |
+ if (!empty($context['ticket_form']['member']['link'])) |
|
111 |
+ echo ' |
|
112 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/user.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_user'], ': ', $context['ticket_form']['member']['link'], '</li>'; |
|
113 |
+ |
|
114 |
+ echo ' |
|
115 |
+ <li> |
|
116 |
+ <img src="', $settings['default_images_url'], '/simpledesk/urgency.png" alt="" class="shd_smallicon" /> |
|
117 |
+ ', $txt['shd_ticket_urgency'], ': ', template_ticket_option('urgency'), ' |
|
118 |
+ </li>'; |
|
119 |
+ |
|
120 |
+ // New tickets aren't assigned - ever - but existing ones might be |
|
121 |
+ if (!empty($context['ticket_form']['ticket'])) |
|
122 |
+ echo ' |
|
123 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/staff.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_assignedto'], ': ', !empty($context['ticket_form']['assigned']['link']) ? $context['ticket_form']['assigned']['link'] : '<span class="error">' . $txt['shd_unassigned'] . '</span>', '</li>'; |
|
124 |
+ |
|
125 |
+ echo ' |
|
126 |
+ <li><img src="', $settings['default_images_url'], '/simpledesk/status.png" alt="" class="shd_smallicon"/> ', $txt['shd_ticket_status'], ': ', $txt['shd_status_' . $context['ticket_form']['status']], '</li>'; |
|
127 |
+ |
|
128 |
+ if (!empty($context['display_private'])) |
|
129 |
+ echo ' |
|
130 |
+ <li> |
|
131 |
+ <img src="', $settings['default_images_url'], '/simpledesk/private.png" alt="" class="shd_smallicon" /> |
|
132 |
+ ', $txt['shd_ticket_privacy'], ': ', template_ticket_option('private'), ' |
|
133 |
+ </li> |
|
134 |
+ </ul>'; |
|
135 |
+ |
|
136 |
+ // Display ticket poster avatar? |
|
137 |
+ if (!empty($modSettings['shd_display_avatar']) && empty($options['show_no_avatars']) && !empty($context['ticket_form']['member']['avatar']['image'])) |
|
138 |
+ echo ' |
|
139 |
+ <div class="shd_ticket_avatar"> |
|
140 |
+ ', $context['ticket_form']['member']['avatar']['image'], ' |
|
141 |
+ </div>'; |
|
142 |
+ |
|
143 |
+ echo ' |
|
144 |
+ </div>'; |
|
145 |
+} |
|
146 |
+ |
|
147 |
+function template_ticket_posterrors() |
|
148 |
+{ |
|
149 |
+ global $context, $txt; |
|
150 |
+ |
|
151 |
+ // Did anything go wrong? |
|
152 |
+ if (!empty($context['shd_errors'])) |
|
153 |
+ { |
|
154 |
+ echo ' |
|
155 |
+ <div class="errorbox" id="errors"> |
|
156 |
+ <dl> |
|
157 |
+ <dt> |
|
158 |
+ <strong style="" id="error_serious">', $txt['shd_ticket_post_error'], ':</strong> |
|
159 |
+ </dt> |
|
160 |
+ <dt class="error" id="error_list">'; |
|
161 |
+ |
|
162 |
+ foreach ($context['shd_errors'] as $error) |
|
163 |
+ echo ' |
|
164 |
+ ', $txt['error_' . $error], '<br />'; |
|
165 |
+ |
|
166 |
+ echo ' |
|
167 |
+ </dt> |
|
168 |
+ </dl> |
|
169 |
+ </div>'; |
|
170 |
+ } |
|
171 |
+} |
|
172 |
+ |
|
173 |
+function template_ticket_subjectbox() |
|
174 |
+{ |
|
175 |
+ global $context, $txt, $scripturl, $settings, $modSettings; |
|
176 |
+ |
|
177 |
+ echo ' |
|
178 |
+ <div class="shd_ticket_description">'; |
|
179 |
+ |
|
180 |
+ template_ticket_posterrors(); |
|
181 |
+ echo ' |
|
182 |
+ <img src="', $settings['default_images_url'], '/simpledesk/description.png" alt="" class="shd_smallicon" /> <strong>', $txt['shd_ticket_subject'], ':</strong> |
|
183 |
+ <input type="text" name="subject" size="50" maxlength="100" class="input_text" value="', $context['ticket_form']['subject'], '" tabindex="', $context['tabindex']++, '" /> |
|
184 |
+ <hr /><br /> |
|
185 |
+ '; |
|
186 |
+} |
|
187 |
+ |
|
188 |
+function template_ticket_content() |
|
189 |
+{ |
|
190 |
+ global $context, $txt, $scripturl, $settings, $modSettings; |
|
191 |
+ |
|
192 |
+ echo ' |
|
193 |
+ <div class="shd_ticket_description">'; |
|
194 |
+ |
|
195 |
+ template_ticket_posterrors(); |
|
196 |
+ echo ' |
|
197 |
+ <img src="', $settings['default_images_url'], '/simpledesk/description.png" alt="" class="shd_smallicon" /> <strong>', $context['ticket_form']['subject'], '</strong> |
|
198 |
+ <hr /><br /> |
|
199 |
+ ', $context['ticket_form']['message']; |
|
200 |
+ |
|
201 |
+ if ($settings['show_modify'] && !empty($context['ticket']['modified'])) |
|
202 |
+ { |
|
203 |
+ echo ' |
|
204 |
+ <div class="smalltext shd_modified" style="margin-top:20px;"> |
|
205 |
+ « <em>', $txt['last_edit'], ': ', $context['ticket']['modified']['time'], ' ', $txt['by'], ' ', $context['ticket']['modified']['link'], '</em> » |
|
206 |
+ </div>'; |
|
207 |
+ } |
|
208 |
+} |
|
209 |
+ |
|
210 |
+function template_ticket_meta() |
|
211 |
+{ |
|
212 |
+ global $context; |
|
213 |
+ |
|
214 |
+ // Management/meta information |
|
215 |
+ echo ' |
|
216 |
+ <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
|
217 |
+ <input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />'; |
|
218 |
+ |
|
219 |
+ if (!empty($context['ticket_form']['ticket'])) |
|
220 |
+ echo ' |
|
221 |
+ <input type="hidden" name="ticket" value="', $context['ticket_form']['ticket'], '" />'; |
|
222 |
+ |
|
223 |
+ if (!empty($context['ticket_form']['msg'])) |
|
224 |
+ echo ' |
|
225 |
+ <input type="hidden" name="msg" value="', $context['ticket_form']['msg'], '" />'; |
|
226 |
+ |
|
227 |
+ if (!empty($context['ticket_form']['num_replies'])) |
|
228 |
+ echo ' |
|
229 |
+ <input type="hidden" name="num_replies" value="', $context['ticket_form']['num_replies'], '" />'; |
|
230 |
+} |
|
231 |
+ |
|
232 |
+function template_ticket_shd_replyarea() |
|
233 |
+{ |
|
234 |
+ global $context, $settings, $scripturl, $txt; |
|
235 |
+ echo ' |
|
236 |
+ <div class="tborder"> |
|
237 |
+ <div class="title_bar grid_header"> |
|
238 |
+ <h3 class="titlebg"> |
|
239 |
+ <img src="', $settings['default_images_url'], '/simpledesk/respond.png" alt="x" /> |
|
240 |
+ ', !empty($context['ticket_form']['form_title']) ? $context['ticket_form']['form_title'] : $txt['shd_reply_ticket'], ' |
|
241 |
+ </h3> |
|
242 |
+ </div> |
|
243 |
+ <div class="roundframe"> |
|
244 |
+ <div class="content">'; |
|
245 |
+ |
|
246 |
+ template_ticket_postbox(); |
|
247 |
+ |
|
248 |
+ echo ' |
|
249 |
+ </div> |
|
250 |
+ </div> |
|
251 |
+ <span class="lowerframe"><span></span></span> |
|
252 |
+ </div> |
|
253 |
+ <br />'; |
|
254 |
+} |
|
255 |
+ |
|
256 |
+function template_ticket_postbox() |
|
257 |
+{ |
|
258 |
+ global $modSettings, $context, $txt; |
|
259 |
+ $editor_context = &$context['controls']['richedit'][$context['post_box_name']]; |
|
260 |
+ |
|
261 |
+ // The postbox |
|
262 |
+ echo ' |
|
263 |
+ <div id="shd_bbcbox"', ((empty($modSettings['shd_allow_ticket_bbc']) || !empty($context['shd_display'])) ? ' style="display:none;"' : ''), '></div> |
|
264 |
+ <div id="shd_smileybox"', ((empty($modSettings['shd_allow_ticket_smileys']) || !empty($context['shd_display'])) ? ' style="display:none;"' : ''), '></div>'; |
|
265 |
+ |
|
266 |
+ echo template_control_richedit($context['post_box_name'], 'shd_smileybox', 'shd_bbcbox'); |
|
267 |
+ |
|
268 |
+ template_ticket_attachments(); |
|
269 |
+ |
|
270 |
+ echo ' |
|
271 |
+ <br class="clear" /> |
|
272 |
+ <span class="smalltext"><br />', $context['browser']['is_firefox'] ? $txt['shortcuts_firefox'] : $txt['shortcuts'], '</span><br /> |
|
273 |
+ <input type="submit" value="', isset($editor_context['labels']['post_button']) ? $editor_context['labels']['post_button'] : $txt['post'], '" tabindex="', $context['tabindex']++, '" accesskey="s" class="button_submit" /> |
|
274 |
+ <input class="button_submit" type="submit" name="preview" value="', $txt['preview'], '" accesskey="p" tabindex="', $context['tabindex']++, '" />'; |
|
275 |
+ |
|
276 |
+ template_ticket_additional_options(); |
|
277 |
+} |
|
278 |
+ |
|
279 |
+function template_ticket_footer() |
|
280 |
+{ |
|
281 |
+ global $settings, $context, $txt; |
|
282 |
+ |
|
283 |
+ if ($settings['show_modify'] && !empty($context['ticket_form']['modified'])) |
|
284 |
+ { |
|
285 |
+ echo ' |
|
286 |
+ <div class="smalltext shd_modified" style="margin-top:20px;"> |
|
287 |
+ « <em>', $txt['last_edit'], ': ', $context['ticket_form']['modified']['time'], ' ', $txt['by'], ' ', $context['ticket_form']['modified']['link'], '</em> » |
|
288 |
+ </div>'; |
|
289 |
+ } |
|
290 |
+ |
|
291 |
+ echo ' |
|
292 |
+ </div> |
|
293 |
+ </div> |
|
294 |
+ <span class="botslice"><span></span></span> |
|
295 |
+ </div> |
|
296 |
+ </div> |
|
297 |
+ <br />'; |
|
298 |
+} |
|
299 |
+ |
|
300 |
+function template_preview() |
|
301 |
+{ |
|
302 |
+ global $context, $txt, $settings; |
|
303 |
+ |
|
304 |
+ if (!empty($context['ticket_form']['preview'])) |
|
305 |
+ { |
|
306 |
+ echo ' |
|
307 |
+ <div class="tborder"> |
|
308 |
+ <div class="title_bar grid_header"> |
|
309 |
+ <h3 class="titlebg"> |
|
310 |
+ <img src="', $settings['default_images_url'], '/simpledesk/preview.png" alt="x" /> |
|
311 |
+ ', !empty($context['ticket_form']['preview']['title']) ? $context['ticket_form']['preview']['title'] : $txt['preview'], ' |
|
312 |
+ </h3> |
|
313 |
+ </div> |
|
314 |
+ <div class="roundframe"> |
|
315 |
+ <div class="content"> |
|
316 |
+ ', $context['ticket_form']['preview']['body'], ' |
|
317 |
+ </div> |
|
318 |
+ </div> |
|
319 |
+ <span class="lowerframe"><span></span></span> |
|
320 |
+ </div> |
|
321 |
+ <br />'; |
|
322 |
+ } |
|
323 |
+} |
|
324 |
+ |
|
325 |
+function template_ticket_attachments() |
|
326 |
+{ |
|
327 |
+ global $context, $modSettings, $txt; |
|
328 |
+ if (empty($context['current_attachments']) && empty($context['ticket_form']['do_attach'])) |
|
329 |
+ return; |
|
330 |
+ |
|
331 |
+ echo ' |
|
332 |
+ <div class="information shd_reply_attachments" id="shd_attach_container"', !empty($context['shd_display']) ? ' style="display:none;"' : '', '>'; |
|
333 |
+ |
|
334 |
+ if (!empty($context['current_attachments'])) |
|
335 |
+ { |
|
336 |
+ echo ' |
|
337 |
+ <dl id="postAttachment"> |
|
338 |
+ <dt> |
|
339 |
+ ', $txt['attached'], ': |
|
340 |
+ </dt> |
|
341 |
+ <dd class="smalltext"> |
|
342 |
+ <input type="hidden" name="attach_del[]" value="0" /> |
|
343 |
+ ', $txt['uncheck_unwatchd_attach'], ': |
|
344 |
+ </dd>'; |
|
345 |
+ foreach ($context['current_attachments'] as $attachment) |
|
346 |
+ echo ' |
|
347 |
+ <dd class="smalltext"> |
|
348 |
+ <label for="attachment_', $attachment['id'], '"><input type="checkbox" id="attachment_', $attachment['id'], '" name="attach_del[]" value="', $attachment['id'], '"', empty($attachment['unchecked']) ? ' checked="checked"' : '', ' class="input_check" onclick="javascript:oAttach.checkActive();" /> ', $attachment['name'], '</label> |
|
349 |
+ </dd>'; |
|
350 |
+ echo ' |
|
351 |
+ </dl>'; |
|
352 |
+ } |
|
353 |
+ |
|
354 |
+ if (!empty($context['ticket_form']['do_attach'])) |
|
355 |
+ { |
|
356 |
+ // JS for our pretty widget |
|
357 |
+ echo ' |
|
358 |
+ <dl id="postAttachment2"> |
|
359 |
+ <dt> |
|
360 |
+ ', $txt['attach'], ': |
|
361 |
+ </dt> |
|
362 |
+ <dd class="smalltext"> |
|
363 |
+ <input type="file" size="60" name="attachment" id="shd_attach" class="input_file" /> |
|
364 |
+ <div id="shd_attachlist_container"></div> |
|
365 |
+ </dd>'; |
|
366 |
+ |
|
367 |
+ echo ' |
|
368 |
+ <dd class="smalltext">'; |
|
369 |
+ |
|
370 |
+ // Show some useful information such as allowed extensions, maximum size and amount of attachments allowed. |
|
371 |
+ if (!empty($modSettings['attachmentCheckExtensions'])) |
|
372 |
+ echo ' |
|
373 |
+ ', $txt['allowed_types'], ': ', $context['allowed_extensions'], '<br />'; |
|
374 |
+ |
|
375 |
+ if (!empty($context['attachment_restrictions'])) |
|
376 |
+ echo ' |
|
377 |
+ ', $txt['attach_restrictions'], ' ', implode(', ', $context['attachment_restrictions']), '<br />'; |
|
378 |
+ |
|
379 |
+ echo ' |
|
380 |
+ </dd> |
|
381 |
+ </dl> |
|
382 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
383 |
+ var oAttach = new shd_attach_select({ |
|
384 |
+ file_item: "shd_attach", |
|
385 |
+ file_container: "shd_attachlist_container", |
|
386 |
+ max: ', $context['ticket_form']['num_allowed_attachments'], ', |
|
387 |
+ message_txt_delete: ', JavaScriptEscape($txt['remove']); |
|
388 |
+ |
|
389 |
+ if (!empty($modSettings['attachmentExtensions']) && !empty($modSettings['attachmentCheckExtensions'])) |
|
390 |
+ { |
|
391 |
+ $ext = explode(',', $modSettings['attachmentExtensions']); |
|
392 |
+ foreach ($ext as $k => $v) |
|
393 |
+ $ext[$k] = JavaScriptEscape($v); |
|
394 |
+ |
|
395 |
+ echo ', |
|
396 |
+ message_ext_error: ', JavaScriptEscape(str_replace('{attach_exts}', $context['allowed_extensions'], $txt['shd_cannot_attach_ext'])), ', |
|
397 |
+ attachment_ext: [', implode(',', $ext), ']'; |
|
398 |
+ } |
|
399 |
+ |
|
400 |
+ echo ' |
|
401 |
+ }); |
|
402 |
+ // ]]></script>'; |
|
403 |
+ } |
|
404 |
+ |
|
405 |
+ echo ' |
|
406 |
+ </div>'; |
|
407 |
+} |
|
408 |
+ |
|
409 |
+function template_ticket_additional_options() |
|
410 |
+{ |
|
411 |
+ global $context, $options, $txt, $modSettings; |
|
412 |
+ echo ' |
|
413 |
+ <div id="postMoreOptions" class="smalltext"> |
|
414 |
+ <ul class="post_options"> |
|
415 |
+ <li><label for="check_back"><input type="checkbox" name="goback" id="check_back"', (!empty($context['ticket_form']['return_to_ticket']) || !empty($options['return_to_post']) ? ' checked="checked"' : ''), ' value="1" class="input_check" /> ', $txt['shd_back_to_ticket'], '</label></li>'; |
|
416 |
+ |
|
417 |
+ if (!empty($modSettings['shd_allow_ticket_smileys'])) |
|
418 |
+ echo ' |
|
419 |
+ <li><label for="disable_smileys"><input type="checkbox" name="no_smileys" id="disable_smileys"', (!empty($context['ticket_form']['disable_smileys']) ? ' checked="checked"' : ''), ' value="1" class="input_check" /> ', $txt['shd_disable_smileys_post'], '</label></li>'; |
|
420 |
+ |
|
421 |
+ echo ' |
|
422 |
+ </ul> |
|
423 |
+ </div>'; |
|
424 |
+} |
|
425 |
+ |
|
426 |
+function template_ticket_begin_replies() |
|
427 |
+{ |
|
428 |
+ global $context, $settings, $txt, $modSettings; |
|
429 |
+ |
|
430 |
+ echo ' |
|
431 |
+ <table width="100%"> |
|
432 |
+ <tr>'; |
|
433 |
+ |
|
434 |
+ // The attachments column |
|
435 |
+ if (!empty($context['ticket_attach']['ticket'])) |
|
436 |
+ { |
|
437 |
+ echo ' |
|
438 |
+ <td valign="top" width="25%"> |
|
439 |
+ <div class="tborder"> |
|
440 |
+ <div class="title_bar grid_header"> |
|
441 |
+ <h3 class="titlebg shd_attachmentcolumn"> |
|
442 |
+ <img src="', $settings['default_images_url'], '/simpledesk/attachments.png" alt="x" />', $txt['shd_ticket_attachments'], ' (', count($context['ticket_attach']['ticket']), ') |
|
443 |
+ </h3> |
|
444 |
+ </div> |
|
445 |
+ <div class="windowbg2 shd_attachmentcolumn"> |
|
446 |
+ <div class="shd_attachmentbox">'; |
|
447 |
+ |
|
448 |
+ foreach ($context['ticket_attach']['ticket'] as $attachment) |
|
449 |
+ { |
|
450 |
+ echo ' |
|
451 |
+ <div class="description attachment" id="attach', $attachment['id'], '"> |
|
452 |
+ <a href="#" title="', $txt['shd_ticket_delete'], '"><img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="shd_tinyicon shd_removeattachment" alt="', $txt['shd_ticket_delete'], '" /></a> |
|
453 |
+ <strong><a href="#">', $attachment['filename'], '</a></strong> |
|
454 |
+ <span class="smalltext"> |
|
455 |
+ (', $attachment['size'], ') - <a href="#ticket">', $txt['shd_ticket'], '</a> |
|
456 |
+ </span> |
|
457 |
+ </div>'; |
|
458 |
+ } |
|
459 |
+ |
|
460 |
+ echo ' |
|
461 |
+ </div> |
|
462 |
+ <span class="botslice"><span></span></span> |
|
463 |
+ </div> |
|
464 |
+ </div> |
|
465 |
+ </td>'; |
|
466 |
+ } |
|
467 |
+ |
|
468 |
+ // The replies column |
|
469 |
+ echo ' |
|
470 |
+ <td valign="top">'; |
|
471 |
+} |
|
472 |
+ |
|
473 |
+function template_ticket_do_replies() |
|
474 |
+{ |
|
475 |
+ global $context, $settings, $txt, $scripturl, $options, $modSettings, $reply_request; |
|
476 |
+ |
|
477 |
+ echo ' |
|
478 |
+ <div class="tborder"> |
|
479 |
+ <div class="title_bar grid_header"> |
|
480 |
+ <h3 class="titlebg"> |
|
481 |
+ <img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="x" /> ', $txt['shd_ticket_replies'], ' |
|
482 |
+ </h3> |
|
483 |
+ </div> |
|
484 |
+ <div class="roundframe" id="replies"> |
|
485 |
+ <div class="content">'; |
|
486 |
+ |
|
487 |
+ if (!empty($reply_request)) |
|
488 |
+ { |
|
489 |
+ while ($reply = $context['get_replies']()) |
|
490 |
+ { |
|
491 |
+ echo ' |
|
492 |
+ <div class="description shd_reply" id="reply', $reply['id'], '"> |
|
493 |
+ <span class="floatleft shd_posterinfo"> |
|
494 |
+ <strong class="shd_postername"> |
|
495 |
+ ', $reply['member']['link'], ' |
|
496 |
+ </strong> |
|
497 |
+ <br /> |
|
498 |
+ ', $reply['member']['group'], '<br class="shd_groupmargin" />'; |
|
499 |
+ |
|
500 |
+ if (!empty($settings['show_user_images']) && empty($options['show_no_avatars']) && !empty($reply['member']['avatar']['image'])) |
|
501 |
+ echo ' |
|
502 |
+ <div>', $reply['member']['avatar']['image'], '</div>'; |
|
503 |
+ |
|
504 |
+ if (!empty($reply['is_team'])) |
|
505 |
+ if (empty($modSettings['shd_use_staff_badge'])) |
|
506 |
+ echo '<br /> |
|
507 |
+ <img src="', $settings['default_images_url'] . '/simpledesk/staff.png" class="shd_smallicon" title="', $txt['shd_ticket_staff'], '" alt="', $txt['shd_ticket_staff'], '" />'; |
|
508 |
+ else |
|
509 |
+ echo '<br /> |
|
510 |
+ ', $reply['member']['group_stars']; |
|
511 |
+ |
|
512 |
+ echo ' |
|
513 |
+ </span> |
|
514 |
+ <div class="shd_replyarea"> |
|
515 |
+ <div class="smalltext"> |
|
516 |
+ <span class="floatright shd_ticketlinks">'; |
|
517 |
+ |
|
518 |
+ if ($context['can_quote']) |
|
519 |
+ echo ' |
|
520 |
+ <img src="', $settings['default_images_url'], '/simpledesk/quote.png" class="shd_smallicon" alt="*" /><a onclick="return oQuickReply.quote(', $reply['id'], ', \'', $context['session_id'], '\', \'', $context['session_var'], '\', true);" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';quote=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_quote_short'], '</a>'; |
|
521 |
+ |
|
522 |
+ echo ' |
|
523 |
+ </span> |
|
524 |
+ ', sprintf($txt['shd_reply_written'], $reply['time']), ' |
|
525 |
+ </div> |
|
526 |
+ <hr class="clearfix" /> |
|
527 |
+ ', $reply['body'], ' |
|
528 |
+ <br /><br />'; |
|
529 |
+ if ($settings['show_modify'] && !empty($reply['modified'])) |
|
530 |
+ { |
|
531 |
+ echo ' |
|
532 |
+ <div class="smalltext shd_modified" style="margin-top:20px;"> |
|
533 |
+ « <em>', $txt['last_edit'], ': ', $reply['modified']['time'], ' ', $txt['by'], ' ', $reply['modified']['link'], '</em> » |
|
534 |
+ </div>'; |
|
535 |
+ } |
|
536 |
+ |
|
537 |
+ if (!empty($context['ticket_attach']['reply'][$reply['id']])) |
|
538 |
+ { |
|
539 |
+ echo ' |
|
540 |
+ <div class="smalltext"> |
|
541 |
+ <strong>', $txt['shd_ticket_attachments'], '</strong><br /> |
|
542 |
+ <ul class="shd_replyattachments">'; |
|
543 |
+ |
|
544 |
+ foreach ($context['ticket_attach']['reply'][$reply['id']] as $attach) |
|
545 |
+ echo ' |
|
546 |
+ <li>', $attach['link'], '</li>'; |
|
547 |
+ |
|
548 |
+ echo ' |
|
549 |
+ </ul> |
|
550 |
+ </div>'; |
|
551 |
+ } |
|
552 |
+ |
|
553 |
+ echo ' |
|
554 |
+ </div> |
|
555 |
+ <br class="clear" /> |
|
556 |
+ </div>'; |
|
557 |
+ } |
|
558 |
+ } |
|
559 |
+ |
|
560 |
+ echo ' |
|
561 |
+ </div> |
|
562 |
+ </div> |
|
563 |
+ <span class="lowerframe"><span></span></span> |
|
564 |
+ </div>'; |
|
565 |
+} |
|
566 |
+ |
|
567 |
+function template_ticket_end_replies() |
|
568 |
+{ |
|
569 |
+ echo '</td>'; |
|
570 |
+ |
|
571 |
+ // Close the table |
|
572 |
+ echo ' |
|
573 |
+ </tr> |
|
574 |
+ </table>'; |
|
575 |
+} |
|
576 |
+ |
|
577 |
+function template_ticket_pageend() |
|
578 |
+{ |
|
579 |
+ // And finally, good night, sweet form |
|
580 |
+ echo ' |
|
581 |
+ </form>'; |
|
582 |
+} |
|
583 |
+?> |
|
0 | 584 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,168 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk ticket <-> topic template |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * This file handles gathering user options when moving a ticket to/from the helpdesk, from/to |
|
6 |
+ * a forum thread, specifically getting details like whether to send a PM to the user (including the PM contents), as well as if sending |
|
7 |
+ * to a board, which board. |
|
8 |
+ * |
|
9 |
+ * @package template |
|
10 |
+ * @since 1.0 |
|
11 |
+*/ |
|
12 |
+ |
|
13 |
+/** |
|
14 |
+ * Display a list of requirements for moving a ticket to a topic. |
|
15 |
+ * |
|
16 |
+ * When moving a ticket to the forum, certain information is required: the board to move to, whether to send the ticket starter a |
|
17 |
+ * personal message (and if so, the contents of the message) and what to do in the event there are deleted replies to deal with. |
|
18 |
+ * This function handles showing the form to the user. |
|
19 |
+ * |
|
20 |
+ * @see shd_tickettotopic() |
|
21 |
+ * @see shd_tickettotopic2() |
|
22 |
+ * |
|
23 |
+ * @since 1.0 |
|
24 |
+*/ |
|
25 |
+function template_shd_tickettotopic() |
|
26 |
+{ |
|
27 |
+ global $txt, $settings, $context, $scripturl, $modSettings; |
|
28 |
+ |
|
29 |
+ // Back to the helpdesk. |
|
30 |
+ echo ' |
|
31 |
+ <div class="floatleft"> |
|
32 |
+ ', template_button_strip(array($context['navigation']['back']), 'bottom'), ' |
|
33 |
+ </div><br class="clear" /><br />'; |
|
34 |
+ |
|
35 |
+ echo ' |
|
36 |
+ <div class="cat_bar grid_header"> |
|
37 |
+ <h3 class="catbg"> |
|
38 |
+ <img src="', $settings['default_images_url'] , '/simpledesk/tickettotopic.png" alt="*" /> |
|
39 |
+ ', $txt['shd_move_ticket_to_topic'], ' |
|
40 |
+ </h3> |
|
41 |
+ </div> |
|
42 |
+ <div class="roundframe"> |
|
43 |
+ <form action="', $scripturl, '?action=helpdesk;sa=tickettotopic2;ticket=', $context['ticket_id'], '" method="post" onsubmit="submitonce(this);"> |
|
44 |
+ <div class="content"> |
|
45 |
+ <dl class="settings"> |
|
46 |
+ <dt> |
|
47 |
+ <strong>', $txt['shd_ticket_board'], ':</strong> |
|
48 |
+ </dt> |
|
49 |
+ <dd> |
|
50 |
+ <select name="toboard">'; |
|
51 |
+ |
|
52 |
+ foreach ($context['categories'] as $category) |
|
53 |
+ { |
|
54 |
+ echo ' |
|
55 |
+ <optgroup label="', $category['name'], '">'; |
|
56 |
+ |
|
57 |
+ foreach ($category['boards'] as $board) |
|
58 |
+ echo ' |
|
59 |
+ <option value="', $board['id'], '"', $board['selected'] ? ' selected="selected"' : '', '>', $board['child_level'] > 0 ? str_repeat('==', $board['child_level']-1) . '=> ' : '', $board['name'], '</option>'; |
|
60 |
+ echo ' |
|
61 |
+ </optgroup>'; |
|
62 |
+ } |
|
63 |
+ |
|
64 |
+ echo ' |
|
65 |
+ </select> |
|
66 |
+ </dd> |
|
67 |
+ <dt> |
|
68 |
+ <strong>', $txt['shd_move_send_pm'], ':</strong> |
|
69 |
+ </dt> |
|
70 |
+ <dd> |
|
71 |
+ <input type="checkbox" name="send_pm" id="send_pm" checked="checked" onclick="document.getElementById(\'pm_message\').style.display = this.checked ? \'block\' : \'none\';" class="input_check" /> |
|
72 |
+ </dd> |
|
73 |
+ </dl> |
|
74 |
+ <fieldset id="pm_message"> |
|
75 |
+ <dl class="settings"> |
|
76 |
+ <dt> |
|
77 |
+ ', $txt['shd_move_why'], ' |
|
78 |
+ </dt> |
|
79 |
+ <dd> |
|
80 |
+ <textarea name="pm_content" rows="9" cols="70">', $txt['shd_move_default'], '</textarea> |
|
81 |
+ </dd> |
|
82 |
+ </dl> |
|
83 |
+ </fieldset>'; |
|
84 |
+ |
|
85 |
+ if (!empty($context['deleted_prompt'])) |
|
86 |
+ { |
|
87 |
+ echo ' |
|
88 |
+ <br /> |
|
89 |
+ <fieldset id="deleted_replies"> |
|
90 |
+ <dl class="settings"> |
|
91 |
+ <dt> |
|
92 |
+ ', $txt['shd_ticket_move_deleted'], ' |
|
93 |
+ </dt> |
|
94 |
+ <dd> |
|
95 |
+ <select name="deleted_replies"> |
|
96 |
+ <option value="abort">', $txt['shd_ticket_move_deleted_abort'], '</option> |
|
97 |
+ <option value="delete">', $txt['shd_ticket_move_deleted_delete'], '</option> |
|
98 |
+ <option value="undelete">', $txt['shd_ticket_move_deleted_undelete'], '</option> |
|
99 |
+ </select> |
|
100 |
+ </dd> |
|
101 |
+ </dl> |
|
102 |
+ </fieldset>'; |
|
103 |
+ } |
|
104 |
+ |
|
105 |
+ echo ' |
|
106 |
+ <input type="submit" value="', $txt['shd_move_ticket'], '" onclick="return submitThisOnce(this);" accesskey="s" class="button_submit" /> |
|
107 |
+ <input type="submit" name="cancel" value="', $txt['shd_cancel_ticket'], '" accesskey="c" class="button_submit" /> |
|
108 |
+ <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
|
109 |
+ <input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" /> |
|
110 |
+ </div> |
|
111 |
+ </form> |
|
112 |
+ </div> |
|
113 |
+ <span class="lowerframe"><span></span></span>'; |
|
114 |
+} |
|
115 |
+ |
|
116 |
+/** |
|
117 |
+ * Display a list of requirements for moving a topic to a ticket. |
|
118 |
+ * |
|
119 |
+ * When moving a ticket from the forum, only a little information is required; basically, whether to send a personal message (and what message) |
|
120 |
+ * to the topic/ticket starter or not. |
|
121 |
+ * |
|
122 |
+ * @see shd_topictoticket() |
|
123 |
+ * @see shd_topictoticket2() |
|
124 |
+ * |
|
125 |
+ * @since 1.0 |
|
126 |
+*/ |
|
127 |
+function template_shd_topictoticket() |
|
128 |
+{ |
|
129 |
+ global $txt, $settings, $context, $scripturl; |
|
130 |
+ echo ' |
|
131 |
+ <div class="cat_bar grid_header"> |
|
132 |
+ <h3 class="catbg"> |
|
133 |
+ <img src="', $settings['default_images_url'] , '/simpledesk/topictoticket.png" alt="*" /> |
|
134 |
+ ', $txt['shd_move_topic_to_ticket'], ' |
|
135 |
+ </h3> |
|
136 |
+ </div> |
|
137 |
+ <div class="roundframe"> |
|
138 |
+ <form action="', $scripturl, '?action=helpdesk;sa=topictoticket2;topic=', $context['topic_id'], '" method="post" onsubmit="submitonce(this);"> |
|
139 |
+ <div class="content"> |
|
140 |
+ <dl class="settings"> |
|
141 |
+ <dt> |
|
142 |
+ <strong>', $txt['shd_move_send_pm_topic'], ':</strong> |
|
143 |
+ </dt> |
|
144 |
+ <dd> |
|
145 |
+ <input type="checkbox" name="send_pm" id="send_pm" checked="checked" onclick="document.getElementById(\'pm_message\').style.display = this.checked ? \'block\' : \'none\';" class="input_check" /> |
|
146 |
+ </dd> |
|
147 |
+ </dl> |
|
148 |
+ <fieldset id="pm_message"> |
|
149 |
+ <dl class="settings"> |
|
150 |
+ <dt> |
|
151 |
+ ', $txt['shd_move_why_topic'], ' |
|
152 |
+ </dt> |
|
153 |
+ <dd> |
|
154 |
+ <textarea name="pm_content" rows="9" cols="70">', $txt['shd_move_default_topic'], '</textarea> |
|
155 |
+ </dd> |
|
156 |
+ </dl> |
|
157 |
+ </fieldset> |
|
158 |
+ <input type="submit" value="', $txt['shd_move_topic'], '" onclick="return submitThisOnce(this);" accesskey="s" class="button_submit" /> |
|
159 |
+ <input type="submit" name="cancel" value="', $txt['shd_cancel_topic'], '" accesskey="c" class="button_submit" /> |
|
160 |
+ <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> |
|
161 |
+ <input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" /> |
|
162 |
+ </div> |
|
163 |
+ </form> |
|
164 |
+ </div> |
|
165 |
+ <span class="lowerframe"><span></span></span>'; |
|
166 |
+} |
|
167 |
+ |
|
168 |
+?> |
|
0 | 169 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,478 @@ |
1 |
+<?php |
|
2 |
+// Version: 1.0 Felidae; SimpleDesk front page template |
|
3 |
+ |
|
4 |
+/** |
|
5 |
+ * This file handles displaying the blocks of tickets for the front page, as well as the slightly |
|
6 |
+ * customised views for the recycle bin and the list of resolved tickets. |
|
7 |
+ * |
|
8 |
+ * @package template |
|
9 |
+ * @since 1.0 |
|
10 |
+*/ |
|
11 |
+ |
|
12 |
+/** |
|
13 |
+ * Display the main helpdesk view of active tickets. |
|
14 |
+ * |
|
15 |
+ * This function steps through the blocks defined in SimpleDesk.php to display all the blocks that potentially would be visible, noting whether blocks have been collapsed or not, and calling to the sub-subtemplates to output collapsed and noncollapsed blocks. |
|
16 |
+ * |
|
17 |
+ * All the blocks here are defined in {@link shd_main_helpdesk()} (or {@link shd_view_block()} if viewing a single block) and data gathered in {@link shd_helpdesk_listing()}. |
|
18 |
+ * |
|
19 |
+ * @see template_collapsed_ticket_block() |
|
20 |
+ * @see template_ticket_block() |
|
21 |
+ * @since 1.0 |
|
22 |
+*/ |
|
23 |
+function template_main() |
|
24 |
+{ |
|
25 |
+ global $context, $txt, $settings, $scripturl; |
|
26 |
+ |
|
27 |
+ echo ' |
|
28 |
+ <div class="modbuttons clearfix margintop">'; |
|
29 |
+ |
|
30 |
+ template_button_strip($context['navigation'], 'bottom'); |
|
31 |
+ |
|
32 |
+ echo ' |
|
33 |
+ </div> |
|
34 |
+ <div id="admin_content"> |
|
35 |
+ <table width="100%" class="shd_main_hd"> |
|
36 |
+ <tr> |
|
37 |
+ <td valign="top"> |
|
38 |
+ <h3 class="titlebg"><span class="left"></span> |
|
39 |
+ ', $txt['shd_helpdesk'], ' |
|
40 |
+ </h3> |
|
41 |
+ <span class="upperframe"><span></span></span> |
|
42 |
+ <div class="roundframe"> |
|
43 |
+ <div class="shd_gototicket smalltext"> |
|
44 |
+ <form action="', $scripturl, '?action=helpdesk;sa=ticket" method="get"> |
|
45 |
+ ', $txt['shd_go_to_ticket'], ': |
|
46 |
+ <input type="hidden" name="action" value="helpdesk" /> |
|
47 |
+ <input type="hidden" name="sa" value="ticket" /> |
|
48 |
+ <input type="text" class="input_text" id="ticketJump" name="ticket" size="4" /> |
|
49 |
+ <input type="submit" class="button_submit" value="', $txt['shd_go'], '" onclick="shd_quickTicketJump(this.parentNode.ticketJump.value);" /> |
|
50 |
+ </form> |
|
51 |
+ </div> |
|
52 |
+ <div id="welcome"> |
|
53 |
+ <strong>', sprintf($txt['shd_welcome'], $context['user']['name']), '</strong><br /> |
|
54 |
+ ', $txt['shd_' . $context['shd_home_view'] . '_greeting'], ' |
|
55 |
+ </div> |
|
56 |
+ </div> |
|
57 |
+ <span class="lowerframe"><span></span></span> |
|
58 |
+ <br />'; |
|
59 |
+ |
|
60 |
+ // Start the ticket listing |
|
61 |
+ $blocks = array_keys($context['ticket_blocks']); |
|
62 |
+ foreach ($blocks as $block) |
|
63 |
+ { |
|
64 |
+ $context['current_block'] = $block; |
|
65 |
+ if (!empty($context['ticket_blocks'][$block]['count']) && $context['ticket_blocks'][$block]['count'] > 10) |
|
66 |
+ $context['block_link'] = $_REQUEST['sa'] == 'viewblock' ? $scripturl . '?action=helpdesk;sa=main' : $scripturl . '?action=helpdesk;sa=viewblock;block=' . $block . '#shd_block_' . $block; |
|
67 |
+ else |
|
68 |
+ $context['block_link'] = ''; |
|
69 |
+ |
|
70 |
+ if ($context['ticket_blocks'][$block]['collapsed']) |
|
71 |
+ template_collapsed_ticket_block(); |
|
72 |
+ else |
|
73 |
+ template_ticket_block(); |
|
74 |
+ } |
|
75 |
+ |
|
76 |
+ echo ' |
|
77 |
+ </td> |
|
78 |
+ </tr> |
|
79 |
+ </table> |
|
80 |
+ </div>'; |
|
81 |
+ |
|
82 |
+ //echo 'I\'m alive!!!!!!!!!!1111oneone'; - I had to save this :P |
|
83 |
+} |
|
84 |
+ |
|
85 |
+/** |
|
86 |
+ * Display the helpdesk view of resolved tickets. |
|
87 |
+ * |
|
88 |
+ * This function steps through the blocks defined in SimpleDesk.php to display all the block of closed items. |
|
89 |
+ * |
|
90 |
+ * All the blocks here are defined in {@link shd_closed_tickets()} and data gathered in {@link shd_helpdesk_listing()}. |
|
91 |
+ * |
|
92 |
+ * @see template_ticket_block() |
|
93 |
+ * @since 1.0 |
|
94 |
+*/ |
|
95 |
+function template_closedtickets() |
|
96 |
+{ |
|
97 |
+ global $context, $txt, $settings, $scripturl; |
|
98 |
+ |
|
99 |
+ echo ' |
|
100 |
+ <div class="modbuttons clearfix margintop">'; |
|
101 |
+ |
|
102 |
+ template_button_strip($context['navigation'], 'bottom'); |
|
103 |
+ |
|
104 |
+ echo ' |
|
105 |
+ </div> |
|
106 |
+ <div id="admin_content"> |
|
107 |
+ <table width="100%" class="shd_main_hd"> |
|
108 |
+ <tr>'; |
|
109 |
+ |
|
110 |
+ echo ' |
|
111 |
+ <td valign="top"> |
|
112 |
+ <h3 class="titlebg"><span class="left"></span> |
|
113 |
+ ', $txt['shd_helpdesk'], ' |
|
114 |
+ </h3> |
|
115 |
+ <span class="upperframe"><span></span></span> |
|
116 |
+ <div class="roundframe"> |
|
117 |
+ <div class="shd_gototicket smalltext"> |
|
118 |
+ <form action="', $scripturl, '?action=helpdesk" method="post"> |
|
119 |
+ ', $txt['shd_go_to_ticket'], ': |
|
120 |
+ <input type="text" name="ticket" size="4" /> |
|
121 |
+ <input type="submit" value="', $txt['shd_go'], '" /> |
|
122 |
+ <input type="hidden" name="sa" value="ticket" /> |
|
123 |
+ </form> |
|
124 |
+ </div> |
|
125 |
+ <div id="welcome"> |
|
126 |
+ <strong>', sprintf($txt['shd_welcome'], $context['user']['name']), '</strong><br /> |
|
127 |
+ ', $txt['shd_closed_' . $context['shd_home_view'] . '_greeting'], ' |
|
128 |
+ </div> |
|
129 |
+ </div> |
|
130 |
+ <span class="lowerframe"><span></span></span> |
|
131 |
+ <br />'; |
|
132 |
+ |
|
133 |
+ // Start the ticket listing |
|
134 |
+ $blocks = array_keys($context['ticket_blocks']); |
|
135 |
+ foreach ($blocks as $block) |
|
136 |
+ { |
|
137 |
+ $context['current_block'] = $block; |
|
138 |
+ template_ticket_block(); |
|
139 |
+ } |
|
140 |
+ |
|
141 |
+ echo ' |
|
142 |
+ </td> |
|
143 |
+ </tr> |
|
144 |
+ </table> |
|
145 |
+ </div>'; |
|
146 |
+} |
|
147 |
+ |
|
148 |
+/** |
|
149 |
+ * Display the helpdesk view of recycled and partly recycled tickets. |
|
150 |
+ * |
|
151 |
+ * This function steps through the blocks defined in SimpleDesk.php to display all the blocks that would be related; the list of deleted tickets, and the list of tickets with deleted replies in. |
|
152 |
+ * |
|
153 |
+ * All the blocks here are defined in {@link shd_recycle_bin()} and data gathered in {@link shd_helpdesk_listing()}. |
|
154 |
+ * |
|
155 |
+ * @see template_ticket_block() |
|
156 |
+ * @since 1.0 |
|
157 |
+*/ |
|
158 |
+function template_recyclebin() |
|
159 |
+{ |
|
160 |
+ global $context, $txt, $settings, $scripturl; |
|
161 |
+ |
|
162 |
+ echo ' |
|
163 |
+ <div class="modbuttons clearfix margintop">'; |
|
164 |
+ |
|
165 |
+ template_button_strip($context['navigation'], 'bottom'); |
|
166 |
+ |
|
167 |
+ echo ' |
|
168 |
+ </div> |
|
169 |
+ <div id="admin_content"> |
|
170 |
+ <table width="100%" class="shd_main_hd"> |
|
171 |
+ <tr>'; |
|
172 |
+ |
|
173 |
+ echo ' |
|
174 |
+ <td valign="top"> |
|
175 |
+ <h3 class="titlebg"><span class="left"></span> |
|
176 |
+ ', $txt['shd_helpdesk'], ' |
|
177 |
+ </h3> |
|
178 |
+ <span class="upperframe"><span></span></span> |
|
179 |
+ <div class="roundframe"> |
|
180 |
+ <div class="shd_gototicket smalltext"> |
|
181 |
+ <form action="', $scripturl, '?action=helpdesk" method="post"> |
|
182 |
+ ', $txt['shd_go_to_ticket'], ': |
|
183 |
+ <input type="text" name="ticket" size="4" /> |
|
184 |
+ <input type="submit" value="', $txt['shd_go'], '" /> |
|
185 |
+ <input type="hidden" name="sa" value="ticket" /> |
|
186 |
+ </form> |
|
187 |
+ </div> |
|
188 |
+ <div id="welcome"> |
|
189 |
+ <strong>', sprintf($txt['shd_welcome'], $context['user']['name']), '</strong><br /> |
|
190 |
+ ', $txt['shd_recycle_greeting'], ' |
|
191 |
+ </div> |
|
192 |
+ </div> |
|
193 |
+ <span class="lowerframe"><span></span></span> |
|
194 |
+ <br />'; |
|
195 |
+ |
|
196 |
+ // Loop through the crap... Uh, I mean the tickets! :) |
|
197 |
+ $blocks = array_keys($context['ticket_blocks']); |
|
198 |
+ foreach ($blocks as $block) |
|
199 |
+ { |
|
200 |
+ $context['current_block'] = $block; |
|
201 |
+ template_ticket_block(); |
|
202 |
+ } |
|
203 |
+ |
|
204 |
+ echo ' |
|
205 |
+ </td> |
|
206 |
+ </tr> |
|
207 |
+ </table> |
|
208 |
+ </div>'; |
|
209 |
+} |
|
210 |
+ |
|
211 |
+/** |
|
212 |
+ * Display a collapsed block. |
|
213 |
+ * |
|
214 |
+ * In the front page, you are able to force a given block to be displayed in its entirety. When that happens, the other blocks are collapsed, so that they are present but their principle content is not. |
|
215 |
+ * |
|
216 |
+ * @see template_ticket_block() |
|
217 |
+ * @since 1.0 |
|
218 |
+*/ |
|
219 |
+function template_collapsed_ticket_block() |
|
220 |
+{ |
|
221 |
+ global $context, $txt, $settings, $scripturl; |
|
222 |
+ |
|
223 |
+ echo ' |
|
224 |
+ <div class="tborder"> |
|
225 |
+ <h3 class="catbg"><span class="left"></span> |
|
226 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $context['ticket_blocks'][$context['current_block']]['block_icon'], '" alt="*" /> |
|
227 |
+ ', (empty($context['block_link']) ? '' : '<a href="' . $context['block_link'] . '">'), $context['ticket_blocks'][$context['current_block']]['title'], ' |
|
228 |
+ <span class="smalltext">(', $context['ticket_blocks'][$context['current_block']]['count'], ' ', ($context['ticket_blocks'][$context['current_block']]['count'] == 1 ? $txt['shd_count_ticket_1'] : $txt['shd_count_tickets']), ')</span>', (empty($context['block_link']) ? '' : '</a>'), ' |
|
229 |
+ </h3> |
|
230 |
+ </div> |
|
231 |
+ <br /> |
|
232 |
+ <br />'; |
|
233 |
+} |
|
234 |
+ |
|
235 |
+/** |
|
236 |
+ * Display an individual, non-collapsed block. |
|
237 |
+ * |
|
238 |
+ * Each front-page template uses this function to display a given block of tickets. It handles displaying the menu header, including ticket count, followed by all the different column types as listed in {@link shd_main_helpdesk()}, then to iterate through the ticket details to display each row (provided by {@link shd_helpdesk_listing()}. |
|
239 |
+ * |
|
240 |
+ * @see shd_main_helpdesk() |
|
241 |
+ * @see shd_helpdesk_listing() |
|
242 |
+ * @since 1.0 |
|
243 |
+*/ |
|
244 |
+function template_ticket_block() |
|
245 |
+{ |
|
246 |
+ global $context, $txt, $settings; |
|
247 |
+ // $context['ticket_blocks'] = array of arrays of ticket data |
|
248 |
+ // $context['current_block'] = the block to display now |
|
249 |
+ |
|
250 |
+ echo ' |
|
251 |
+ <div class="tborder"> |
|
252 |
+ <div class="cat_bar grid_header"> |
|
253 |
+ <h3 id="shd_block_', $context['current_block'], '" class="catbg"> |
|
254 |
+ ', !empty($context['ticket_blocks'][$context['current_block']]['page_index']) ? '<span class="floatright smalltext">'. $txt['pages'] . ': ' . $context['ticket_blocks'][$context['current_block']]['page_index'] . '</span>' : '', ' |
|
255 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $context['ticket_blocks'][$context['current_block']]['block_icon'], '" alt="*" /> |
|
256 |
+ ', (empty($context['block_link']) ? '' : '<a href="' . $context['block_link'] . '">'), $context['ticket_blocks'][$context['current_block']]['title'], ' |
|
257 |
+ <span class="smalltext">(', $context['ticket_blocks'][$context['current_block']]['count'], ' ', ($context['ticket_blocks'][$context['current_block']]['count'] == 1 ? $txt['shd_count_ticket_1'] : $txt['shd_count_tickets']), ')</span>', (empty($context['block_link']) ? '' : '</a>'), ' |
|
258 |
+ </h3> |
|
259 |
+ </div> |
|
260 |
+ |
|
261 |
+ <table class="shd_ticketlist" cellspacing="0" width="100%"> |
|
262 |
+ <tr class="titlebg">'; |
|
263 |
+ |
|
264 |
+ $block_width = 0; |
|
265 |
+ foreach ($context['ticket_blocks'][$context['current_block']]['columns'] as $column) |
|
266 |
+ { |
|
267 |
+ $block_width++; |
|
268 |
+ switch ($column) |
|
269 |
+ { |
|
270 |
+ case 'ticket_id': |
|
271 |
+ echo ' |
|
272 |
+ <td width="8%" colspan="2" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/ticket.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('ticketid', $txt['shd_ticket']), '</td>'; |
|
273 |
+ $block_width++; // is 2 blocks wide |
|
274 |
+ break; |
|
275 |
+ case 'ticket_name': |
|
276 |
+ echo ' |
|
277 |
+ <td width="15%" class="shd_nowrap">', template_shd_menu_header('ticketname', $txt['shd_ticket_name']), '</td>'; |
|
278 |
+ break; |
|
279 |
+ case 'starting_user': |
|
280 |
+ echo ' |
|
281 |
+ <td width="12%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/user.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('starter', $txt['shd_ticket_started_by']), '</td>'; |
|
282 |
+ break; |
|
283 |
+ case 'last_reply': |
|
284 |
+ echo ' |
|
285 |
+ <td width="20%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/staff.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('lastreply', $txt['shd_ticket_updated_by']), '</td>'; |
|
286 |
+ break; |
|
287 |
+ case 'assigned': |
|
288 |
+ echo ' |
|
289 |
+ <td width="12%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/staff.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('assigned', $txt['shd_ticket_assigned']), '</td>'; |
|
290 |
+ break; |
|
291 |
+ case 'status': |
|
292 |
+ echo ' |
|
293 |
+ <td width="17%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/status.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('starter', $txt['shd_ticket_status']), '</td>'; |
|
294 |
+ break; |
|
295 |
+ case 'urgency': |
|
296 |
+ echo ' |
|
297 |
+ <td width="8%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/urgency.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('urgency', $txt['shd_ticket_urgency']), '</td>'; |
|
298 |
+ break; |
|
299 |
+ case 'updated': |
|
300 |
+ echo ' |
|
301 |
+ <td width="22%" class="shd_nowrap"><img src="', $settings['default_images_url'], '/simpledesk/time.png" class="shd_smallicon" alt="" /> ', template_shd_menu_header('updated', $txt['shd_ticket_updated']), '</td>'; |
|
302 |
+ break; |
|
303 |
+ case 'replies': |
|
304 |
+ echo ' |
|
305 |
+ <td width="7%" class="shd_nowrap">', template_shd_menu_header('replies', $txt['shd_ticket_num_replies']), '</td>'; |
|
306 |
+ break; |
|
307 |
+ case 'allreplies': |
|
308 |
+ echo ' |
|
309 |
+ <td width="7%" class="shd_nowrap">', template_shd_menu_header('allreplies', $txt['shd_ticket_num_replies']), '</td>'; |
|
310 |
+ break; |
|
311 |
+ case 'actions': |
|
312 |
+ echo ' |
|
313 |
+ <td width="5%" class="shd_nowrap">', $txt['shd_actions'] , '</td>'; |
|
314 |
+ break; |
|
315 |
+ default: |
|
316 |
+ echo ' |
|
317 |
+ <td><td>'; |
|
318 |
+ break; |
|
319 |
+ } |
|
320 |
+ } |
|
321 |
+ |
|
322 |
+ echo ' |
|
323 |
+ </tr>'; |
|
324 |
+ |
|
325 |
+ if (empty($context['ticket_blocks'][$context['current_block']]['tickets'])) |
|
326 |
+ { |
|
327 |
+ echo ' |
|
328 |
+ <tr class="windowbg2"> |
|
329 |
+ <td colspan="', $block_width, '" class="shd_noticket">', $txt['shd_error_no_tickets'], '</td> |
|
330 |
+ </tr>'; |
|
331 |
+ } |
|
332 |
+ else |
|
333 |
+ { |
|
334 |
+ $use_bg2 = true; // start with windowbg2 to differentiate between that and titlebg |
|
335 |
+ foreach ($context['ticket_blocks'][$context['current_block']]['tickets'] as $ticket) |
|
336 |
+ { |
|
337 |
+ echo ' |
|
338 |
+ <tr class="', ($use_bg2 ? 'windowbg2' : 'windowbg'), '">'; |
|
339 |
+ |
|
340 |
+ foreach ($context['ticket_blocks'][$context['current_block']]['columns'] as $column) |
|
341 |
+ { |
|
342 |
+ switch ($column) |
|
343 |
+ { |
|
344 |
+ case 'ticket_id': |
|
345 |
+ $private_image = $ticket['private'] ? 'private.png' : 'public.png'; |
|
346 |
+ $private_txt = $ticket['private'] ? $txt['shd_ticket_private'] : $txt['shd_ticket_notprivate']; |
|
347 |
+ $unread_image = $ticket['is_unread'] ? 'unread.png' : 'read.png'; |
|
348 |
+ $unread_txt = $ticket['is_unread'] ? $txt['shd_ticket_new'] : $txt['shd_ticket_notnew']; |
|
349 |
+ echo ' |
|
350 |
+ <td width="1%" class="shd_nowrap"> |
|
351 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $unread_image, '" alt="', $unread_txt, '" title="', $unread_txt, '" /> |
|
352 |
+ <img src="', $settings['default_images_url'], '/simpledesk/', $private_image, '" alt="', $private_txt, '" title="', $private_txt, '" /> |
|
353 |
+ </td> |
|
354 |
+ <td width="4%" class="smalltext">', $ticket['display_id'], '</td>'; |
|
355 |
+ break; |
|
356 |
+ case 'ticket_name': |
|
357 |
+ echo ' |
|
358 |
+ <td class="smalltext">', $ticket['link'], '</td>'; |
|
359 |
+ break; |
|
360 |
+ case 'starting_user': |
|
361 |
+ echo ' |
|
362 |
+ <td class="smalltext">', $ticket['starter']['link'], '</td>'; |
|
363 |
+ break; |
|
364 |
+ case 'last_reply': |
|
365 |
+ echo ' |
|
366 |
+ <td class="smalltext">', $ticket['respondent']['link'], '</td>'; |
|
367 |
+ break; |
|
368 |
+ case 'assigned': |
|
369 |
+ echo ' |
|
370 |
+ <td class="smalltext">' . $ticket['assigned']['link'] . '</td>'; |
|
371 |
+ break; |
|
372 |
+ case 'status': |
|
373 |
+ echo ' |
|
374 |
+ <td class="smalltext">', $ticket['status']['label'], '</td>'; |
|
375 |
+ break; |
|
376 |
+ case 'urgency': |
|
377 |
+ echo ' |
|
378 |
+ <td class="smalltext">' . $ticket['urgency']['label'] . '</td>'; |
|
379 |
+ break; |
|
380 |
+ case 'updated': |
|
381 |
+ echo ' |
|
382 |
+ <td class="smalltext">', $ticket['last_update'], '</td>'; |
|
383 |
+ break; |
|
384 |
+ case 'replies': |
|
385 |
+ echo ' |
|
386 |
+ <td class="smalltext">', $ticket['num_replies'], '</td>'; |
|
387 |
+ break; |
|
388 |
+ case 'allreplies': |
|
389 |
+ echo ' |
|
390 |
+ <td class="smalltext">', $ticket['all_replies'], '</td>'; |
|
391 |
+ break; |
|
392 |
+ case 'actions': |
|
393 |
+ echo ' |
|
394 |
+ <td class="shd_nowrap">'; |
|
395 |
+ |
|
396 |
+ foreach ($ticket['actions'] as $action) |
|
397 |
+ echo ' |
|
398 |
+ ', $action; |
|
399 |
+ |
|
400 |
+ echo ' |
|
401 |
+ </td>'; |
|
402 |
+ |
|
403 |
+ break; |
|
404 |
+ default: |
|
405 |
+ echo ' |
|
406 |
+ <td><td>'; |
|
407 |
+ break; |
|
408 |
+ } |
|
409 |
+ } |
|
410 |
+ |
|
411 |
+ echo ' |
|
412 |
+ </tr>'; |
|
413 |
+ |
|
414 |
+ $use_bg2 = !$use_bg2; |
|
415 |
+ } |
|
416 |
+ } |
|
417 |
+ |
|
418 |
+ if (!empty($context['ticket_blocks'][$context['current_block']]['page_index'])) |
|
419 |
+ echo ' |
|
420 |
+ <tr class="titlebg"> |
|
421 |
+ <td colspan="', $block_width, '"><span class="floatright smalltext">', $txt['pages'], ': ', $context['ticket_blocks'][$context['current_block']]['page_index'], '</span></td> |
|
422 |
+ </tr>'; |
|
423 |
+ |
|
424 |
+ echo ' |
|
425 |
+ </table> |
|
426 |
+ </div> |
|
427 |
+ <br /><br />'; |
|
428 |
+} |
|
429 |
+ |
|
430 |
+/** |
|
431 |
+ * Makes a menu header clickable/sortable. |
|
432 |
+ * |
|
433 |
+ * Within the ticket blocks, it is possible to sort the blocks by column, and do so in a way that is retained as you manipulate individual blocks. Since this is transient (not pushed to the database) it needs to be recorded in the URL over time. |
|
434 |
+ * |
|
435 |
+ * @param string $header The identifier of the header to use here; related to {@link shd_helpdesk_listing()} |
|
436 |
+ * @param string $string The text string to use as the header text |
|
437 |
+ * |
|
438 |
+ * @return string The fully formed HTML fragment for the link, text and hint image |
|
439 |
+ * @see template_ticket_block() |
|
440 |
+ * @since 1.0 |
|
441 |
+*/ |
|
442 |
+function template_shd_menu_header($header, $string) |
|
443 |
+{ |
|
444 |
+ global $context, $scripturl, $settings; |
|
445 |
+ |
|
446 |
+ if (empty($context['ticket_blocks'][$context['current_block']]['tickets'])) |
|
447 |
+ return $string; // no sense doing any work if it's an empty block and thus not sortable! |
|
448 |
+ |
|
449 |
+ $link = ''; |
|
450 |
+ // Get the pages of existing items first |
|
451 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
452 |
+ { |
|
453 |
+ if (isset($_REQUEST['st_' . $block_key])) |
|
454 |
+ $link .= ';st_' . $block_key . '=' . $block['start']; |
|
455 |
+ } |
|
456 |
+ |
|
457 |
+ $direction = 'down'; |
|
458 |
+ // Now for sorting direction per block |
|
459 |
+ foreach ($context['ticket_blocks'] as $block_key => $block) |
|
460 |
+ { |
|
461 |
+ if (!$block['sort']['add_link'] && $block_key != $context['current_block']) |
|
462 |
+ continue; |
|
463 |
+ |
|
464 |
+ $link_direction = ($block_key == $context['current_block']) ? ($block['sort']['direction'] == 'asc' ? 'desc' : 'asc') : $block['sort']['direction']; |
|
465 |
+ |
|
466 |
+ $link .= ';so_' . $block_key . '=' . ($block_key != $context['current_block'] ? $block['sort']['item'] : $header) . '_' . $link_direction; |
|
467 |
+ } |
|
468 |
+ |
|
469 |
+ $html = '<a href="' . $scripturl . '?action=helpdesk;sa=' . $_REQUEST['sa'] . ($_REQUEST['sa'] == 'viewblock' ? ';block=' . $_REQUEST['block'] : '') . $link . '">' . $string . '</a> '; |
|
470 |
+ |
|
471 |
+ if ($context['ticket_blocks'][$context['current_block']]['sort']['item'] == $header) |
|
472 |
+ { |
|
473 |
+ $html .= '<img src="' . $settings['images_url'] . '/sort_' . ($context['ticket_blocks'][$context['current_block']]['sort']['direction'] == 'asc' ? 'down' : 'up') . '.gif" alt="" />'; |
|
474 |
+ } |
|
475 |
+ |
|
476 |
+ return $html; |
|
477 |
+} |
|
478 |
+?> |
|
0 | 479 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,89 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: uninstall-optional.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This script removes all the extraneous data if the user requests it be removed on uninstall. |
|
22 |
+ * |
|
23 |
+ * NOTE: This script is meant to run using the <samp><database></database></samp> elements of the package-info.xml file. The install |
|
24 |
+ * script, run through <samp><database></samp> elements would have set up the tables and so on. This script runs from |
|
25 |
+ * <samp><database></samp> during uninstallation only when the user requests that data should be cleared, so this script deals with it; |
|
26 |
+ * note that table removal will be dealt with by SMF itself because of <samp><database></samp> handling, so this is for things like |
|
27 |
+ * settings that are not covered in <samp><database></samp>. |
|
28 |
+ * |
|
29 |
+ * @package installer |
|
30 |
+ * @since 1.0 |
|
31 |
+ */ |
|
32 |
+ |
|
33 |
+/** |
|
34 |
+ * Before attempting to execute, this file attempts to load SSI.php to enable access to the database functions. |
|
35 |
+*/ |
|
36 |
+ |
|
37 |
+// If we have found SSI.php and we are outside of SMF, then we are running standalone. |
|
38 |
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF')) |
|
39 |
+{ |
|
40 |
+ require_once(dirname(__FILE__) . '/SSI.php'); |
|
41 |
+ db_extend('packages'); |
|
42 |
+} |
|
43 |
+// If we are outside SMF and can't find SSI.php, then throw an error |
|
44 |
+elseif (!defined('SMF')) |
|
45 |
+{ |
|
46 |
+ die('<b>Error:</b> Cannot uninstall - please verify you put this file in the same place as SMF\'s SSI.php.'); |
|
47 |
+} |
|
48 |
+ |
|
49 |
+$to_remove = array( |
|
50 |
+ 'shd_staff_badge', |
|
51 |
+ 'shd_display_avatar', |
|
52 |
+ 'shd_disable_action_log', |
|
53 |
+ 'shd_ticketnav_style', |
|
54 |
+ 'shd_allow_ticket_bbc', |
|
55 |
+ 'shd_allow_ticket_smileys', |
|
56 |
+ 'shd_enabled_bbc', |
|
57 |
+ 'shd_helpdesk_only', |
|
58 |
+ 'shd_attachments_mode', |
|
59 |
+ 'shd_disable_pm', |
|
60 |
+ 'shd_disable_mlist', |
|
61 |
+ 'shd_attachments_mode', |
|
62 |
+ 'shd_bbc', |
|
63 |
+ 'shd_staff_ticket_self', |
|
64 |
+ 'shd_admins_not_assignable', |
|
65 |
+ 'shd_privacy_display', |
|
66 |
+); |
|
67 |
+ |
|
68 |
+global $modSettings; |
|
69 |
+ |
|
70 |
+// Clear in-situ modsettings |
|
71 |
+foreach ($to_remove as $setting) |
|
72 |
+ if (isset($modSettings[$setting])) |
|
73 |
+ unset($modSettings[$setting]); |
|
74 |
+ |
|
75 |
+// Remove from the database; updateSettings can't actually remove them, it seems :( |
|
76 |
+$smcFunc['db_query']('', ' |
|
77 |
+ DELETE FROM {db_prefix}settings |
|
78 |
+ WHERE variable IN ({array_string:settings})', |
|
79 |
+ array( |
|
80 |
+ 'settings' => $to_remove, |
|
81 |
+ ) |
|
82 |
+); |
|
83 |
+ |
|
84 |
+// And tell SMF we've updated $modSettings |
|
85 |
+updateSettings(array( |
|
86 |
+ 'settings_updated' => time(), |
|
87 |
+)); |
|
88 |
+ |
|
89 |
+?> |
|
0 | 90 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,61 @@ |
1 |
+<?php |
|
2 |
+############################################################### |
|
3 |
+# Simple Desk Project - www.simpledesk.net # |
|
4 |
+############################################################### |
|
5 |
+# An advanced help desk modifcation built on SMF # |
|
6 |
+############################################################### |
|
7 |
+# # |
|
8 |
+# * Copyright 2010 - SimpleDesk.net # |
|
9 |
+# # |
|
10 |
+# This file and its contents are subject to the license # |
|
11 |
+# included with this distribution, license.txt, which # |
|
12 |
+# states that this software is New BSD Licensed. # |
|
13 |
+# Any questions, please contact SimpleDesk.net # |
|
14 |
+# # |
|
15 |
+############################################################### |
|
16 |
+# SimpleDesk Version: 1.0 Felidae # |
|
17 |
+# File Info: uninstall-required.php / 1.0 Felidae # |
|
18 |
+############################################################### |
|
19 |
+ |
|
20 |
+/** |
|
21 |
+ * This script removes all the extraneous data if the user requests it be removed on uninstall. |
|
22 |
+ * |
|
23 |
+ * NOTE: This script is meant to run using the <samp><code></code></samp> elements of our package-info.xml file. This is because |
|
24 |
+ * certain items in the database and within SMF will need to be removed regardless of whether the user wants to keep data or not, |
|
25 |
+ * for example SimpleDesk needs to be deactivated in the Core Features panel, which must be done regardless of whether the user |
|
26 |
+ * wanted to keep data or not during uninstallation. Future expansions may add items here, especially such as scheduled tasks. |
|
27 |
+ * |
|
28 |
+ * @package installer |
|
29 |
+ * @since 1.0 |
|
30 |
+ */ |
|
31 |
+ |
|
32 |
+/** |
|
33 |
+ * Before attempting to execute, this file attempts to load SSI.php to enable access to the database functions. |
|
34 |
+*/ |
|
35 |
+ |
|
36 |
+// If we have found SSI.php and we are outside of SMF, then we are running standalone. |
|
37 |
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF')) |
|
38 |
+{ |
|
39 |
+ require_once(dirname(__FILE__) . '/SSI.php'); |
|
40 |
+ db_extend('packages'); |
|
41 |
+} |
|
42 |
+// If we are outside SMF and can't find SSI.php, then throw an error |
|
43 |
+elseif (!defined('SMF')) |
|
44 |
+{ |
|
45 |
+ die('<b>Error:</b> Cannot uninstall - please verify you put this file in the same place as SMF\'s SSI.php.'); |
|
46 |
+} |
|
47 |
+ |
|
48 |
+// 1. Unchecking the option in Core Features. |
|
49 |
+ |
|
50 |
+global $modSettings; |
|
51 |
+$modSettings['helpdesk_active'] = false; |
|
52 |
+$features = implode(',', array_diff(explode(',', $modSettings['admin_features']), array('shd'))); |
|
53 |
+ |
|
54 |
+updateSettings( |
|
55 |
+ array( |
|
56 |
+ 'admin_features' => $features, |
|
57 |
+ ), |
|
58 |
+ true |
|
59 |
+); |
|
60 |
+ |
|
61 |
+?> |
|
0 | 62 |
\ No newline at end of file |
1 | 63 |