class.Controller_Ticket.php

Gary Mcgrath, 03/13/2015 05:13 am

Download (226 kB)

 
1
<?php
2
/**
3
 * ###############################################
4
 *
5
 * SWIFT Framework
6
 * _______________________________________________
7
 *
8
 * @author                Varun Shoor
9
 *
10
 * @package                SWIFT
11
 * @copyright        Copyright (c) 2001-2012, Kayako
12
 * @license                http://www.kayako.com/license
13
 * @link                http://www.kayako.com
14
 *
15
 * ###############################################
16
 */
17
18
/**
19
 * The View Ticket Controller
20
 *
21
 * @author Varun Shoor
22
 */
23
class Controller_Ticket extends Controller_staff
24
{
25
        // Core Constants
26
        const MENU_ID = 2;
27
        const NAVIGATION_ID = 1;
28
29
        /**
30
         * Constructor
31
         *
32
         * @author Varun Shoor
33
         * @return bool "true" on Success, "false" otherwise
34
         */
35
        public function __construct()
36
        {
37
                parent::__construct();
38
39
                $this->Load->Library('CustomField:CustomFieldRendererStaff');
40
                $this->Load->Library('CustomField:CustomFieldManager');
41
42
                $this->Language->Load('staff_ticketsmain');
43
                $this->Language->Load('staff_ticketsmanage');
44
45
                SWIFT_Ticket::LoadLanguageTable();
46
47
                return true;
48
        }
49
50
        /**
51
         * Destructor
52
         *
53
         * @author Varun Shoor
54
         * @return bool "true" on Success, "false" otherwise
55
         */
56
        public function __destruct()
57
        {
58
                parent::__destruct();
59
60
                return true;
61
        }
62
63
        /**
64
         * View a ticket
65
         *
66
         * @author Varun Shoor
67
         * @param int $_ticketID The Ticket ID
68
         * @param string $_listType (OPTIONAL) The List Type
69
         * @param int $_departmentID (OPTIONAL) The Department ID
70
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
71
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
72
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
73
         * @param int $_ticketLimitOffsetIncoming (OPTIONAL) The Incoming offset
74
         * @return bool "true" on Success, "false" otherwise
75
         * @throws SWIFT_Exception If the Class is not Loaded
76
         */
77
        public function View($_ticketID = '', $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1, $_ticketLimitOffset = 0, $_ticketLimitOffsetIncoming = -2) {
78
                $_SWIFT = SWIFT::GetInstance();
79
80
                if (!$this->GetIsClassLoaded()) {
81
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
82
83
                        return false;
84
                } else if (empty($_ticketID)) {
85
                        $this->Load->Controller('Manage')->Index();
86
87
                        return false;
88
                }
89
90
                $_ticketLimitOffsetIncoming = intval($_ticketLimitOffsetIncoming);
91
                if ($_ticketLimitOffsetIncoming != -2)
92
                {
93
                        $_ticketLimitOffset = $_ticketLimitOffsetIncoming;
94
                }
95
96
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
97
98
                // Did the object load up?
99
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
100
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
101
                                        self::NAVIGATION_ID);
102
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
103
                        $this->UserInterface->Footer();
104
105
                        return false;
106
                }
107
108
                // Check permission
109
                /*
110
                 * Improvement - Bishwanath Jha
111
                 *
112
                 * SWIFT-1339 Restrict staff to be able to view assigned tickets ONLY
113
                 *
114
                 * Comments : Check if restriction for Group (Can View unassigned Tickets, Can View All Tickets) is set?
115
                 */
116
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0' ||
117
                        ($_SWIFT_TicketObject->GetProperty('ownerstaffid') == 0 && $_SWIFT->Staff->GetPermission('staff_tcanviewunassign') == '0') ||
118
                        ($_SWIFT_TicketObject->GetProperty('ownerstaffid') != 0 && $_SWIFT_TicketObject->GetProperty('ownerstaffid') != $_SWIFT->Staff->GetStaffID() && $_SWIFT->Staff->GetPermission('staff_tcanviewall') == '0')
119
                ) {
120
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
121
                                        self::NAVIGATION_ID);
122
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
123
                        $this->UserInterface->Footer();
124
125
                        return false;
126
127
                }
128
129
                //Don't allow deleted ticket to be displayed
130
/*                if (!$_SWIFT_TicketObject->GetProperty('departmentid')) {
131
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
132
                                        self::NAVIGATION_ID);
133
                        $this->UserInterface->DisplayError($this->Language->Get('titleticketdeleted'), $this->Language->Get('msgticketdeleted'));
134
                        $this->UserInterface->Footer();
135
136
                        return false;
137
                }*/
138
139
                if (is_numeric($_ticketLimitOffset)) {
140
                        $_ticketLimitOffset = intval($_ticketLimitOffset);
141
                } else {
142
                        $_ticketLimitOffset = 0;
143
                }
144
145
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
146
                $_SWIFT_UserOrganizationObject = $_SWIFT_TicketObject->GetUserOrganizationObject();
147
148
                $_ticketLinkedTableContainer = SWIFT_TicketLinkedTable::RetrieveOnTicket($_SWIFT_TicketObject);
149
150
                SWIFT::Set('ticketurlsuffix', $_listType . '/' . $_departmentID . '/' . $_ticketStatusID . '/' . $_ticketTypeID . '/' . $_ticketLimitOffset);
151
152
                // Ticket Post Processing
153
                $_variableContainer = array();
154
                $_ticketPostCount = $_SWIFT_TicketObject->GetTicketPostCount();
155
156
                $_ticketPostOffset = intval($_ticketLimitOffset);
157
                $_ticketPostLimitCount = false;
158
                if ($this->Settings->Get('t_enpagin') == '1') {
159
                        $_ticketPostLimitCount = intval($this->Settings->Get('t_postlimit'));
160
                }
161
162
                $_ticketPostOrder = 'ASC';
163
                if ($this->Settings->Get('t_postorder') == 'desc') {
164
                        $_ticketPostOrder = 'DESC';
165
                }
166
167
                if ($_ticketPostOffset < 0) {
168
                        $_ticketPostOffset = 0;
169
170
                        $_ticketPostLimitCount = $_ticketPostCount;
171
                }
172
173
                $_ticketPostContainer = $_SWIFT_TicketObject->GetTicketPosts($_ticketPostOffset, $_ticketPostLimitCount, $_ticketPostOrder);
174
175
                $_participantsContainer = $_participantHTMLContainer = array();
176
                $_userImageUserIDList = $_staffImageUserIDList = array();
177
                foreach ($_ticketPostContainer as $_ticketPostID => $_SWIFT_TicketPostObject) {
178
                        if ($_SWIFT->Staff->GetPermission('staff_canviewusers') != '0' && $_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_Ticket::CREATOR_USER &&
179
                                        $_SWIFT_TicketPostObject->GetProperty('userid') != '0' && !in_array($_SWIFT_TicketPostObject->GetProperty('userid'), $_userImageUserIDList)) {
180
                                $_userImageUserIDList[] = $_SWIFT_TicketPostObject->GetProperty('userid');
181
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_Ticket::CREATOR_STAFF &&
182
                                        $_SWIFT_TicketPostObject->GetProperty('staffid') != '0' && !in_array($_SWIFT_TicketPostObject->GetProperty('staffid'), $_staffImageUserIDList)) {
183
                                $_staffImageUserIDList[] = $_SWIFT_TicketPostObject->GetProperty('staffid');
184
                        }
185
186
                        // Participants
187
                        $_userHash = md5($_SWIFT_TicketPostObject->GetProperty('creator') . ':' . $_SWIFT_TicketPostObject->GetProperty('userid') . ':' . $_SWIFT_TicketPostObject->GetProperty('fullname'));
188
                        $_staffHash = md5($_SWIFT_TicketPostObject->GetProperty('creator') . ':' . $_SWIFT_TicketPostObject->GetProperty('staffid') . ':' . $_SWIFT_TicketPostObject->GetProperty('fullname'));
189
                        if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_USER)
190
                        {
191
                                if (in_array($_userHash, $_participantsContainer))
192
                                {
193
                                        continue;
194
                                }
195
196
                                $_participantHTMLContainer[] = array($this->Language->Get('badgeuser'), $_SWIFT_TicketPostObject->GetProperty('fullname'));
197
198
                                $_participantsContainer[] = $_userHash;
199
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_STAFF) {
200
                                if (in_array($_staffHash, $_participantsContainer))
201
                                {
202
                                        continue;
203
                                }
204
205
                                $_participantHTMLContainer[] = array($this->Language->Get('badgestaff'), $_SWIFT_TicketPostObject->GetProperty('fullname'));
206
                                $_participantsContainer[] = $_staffHash;
207
208
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_THIRDPARTY) {
209
                                if (in_array($_userHash, $_participantsContainer))
210
                                {
211
                                        continue;
212
                                }
213
214
                                $_participantHTMLContainer[] = array($this->Language->Get('badgethirdparty'), $_SWIFT_TicketPostObject->GetProperty('fullname'));
215
                                $_participantsContainer[] = $_userHash;
216
217
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_CC || $_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_BCC) {
218
                                if (in_array($_userHash, $_participantsContainer))
219
                                {
220
                                        continue;
221
                                }
222
223
                                $_participantHTMLContainer[] = array($this->Language->Get('badgecc'), $_SWIFT_TicketPostObject->GetProperty('fullname'));
224
                                $_participantsContainer[] = $_userHash;
225
226
                        }
227
                }
228
229
                $_variableContainer = array('_ticketPostOffset' => $_ticketPostOffset, '_ticketPostLimitCount' => $_ticketPostLimitCount, '_ticketPostContainer' => $_ticketPostContainer,
230
                                '_userImageUserIDList' => $_userImageUserIDList, '_staffImageUserIDList' => $_staffImageUserIDList, '_ticketPostCount' => $_ticketPostCount);
231
232
233
                // Ratings
234
                $_ratingContainer = SWIFT_Rating::Retrieve(array(SWIFT_Rating::TYPE_TICKET), $_SWIFT->Staff, false, $_SWIFT_TicketObject->GetProperty('departmentid'));
235
236
                $this->View->RenderInfoBox($_SWIFT_TicketObject, $_SWIFT_UserObject, $_SWIFT_UserOrganizationObject);
237
                $this->View->RenderParticipantBox($_SWIFT_TicketObject, $_participantHTMLContainer);
238
                $this->View->RenderWorkflowBox($_SWIFT_TicketObject, $_ticketLinkedTableContainer);
239
240
                if ($_SWIFT->Staff->GetPermission('staff_canviewratings') != '0')
241
                {
242
                        SWIFT_RatingRenderer::RenderNavigationBox(array(SWIFT_Rating::TYPE_TICKET), $_SWIFT_TicketObject->GetTicketID(), '/Tickets/Ticket/Rating/' . $_SWIFT_TicketObject->GetTicketID(), $_ratingContainer);
243
                }
244
245
                $this->UserInterface->AddNavigationBox($this->Language->Get('quickfilter'), SWIFT_TicketViewRenderer::RenderTree($_listType, $_departmentID,
246
                                $_ticketStatusID, $_ticketTypeID));
247
                $this->UserInterface->Header(sprintf($this->Language->Get('viewticketext'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT_TicketObject->GetProperty('subject')),
248
                                self::MENU_ID, self::NAVIGATION_ID);
249
                $this->View->RenderTicket($_SWIFT_TicketObject, $_SWIFT_UserObject, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset, $_variableContainer);
250
                $this->UserInterface->Footer();
251
                return true;
252
        }
253
254
        /**
255
         * Print a ticket
256
         *
257
         * @author Parminder Singh
258
         * @param int $_ticketID The Ticket ID
259
         * @return bool "true" on Success, "false" otherwise
260
         * @throws SWIFT_Exception If the Class is not Loaded
261
         * @throws SWIFT_Exception if the ticket id is empty
262
         */
263
264
        public function PrintTicket($_ticketID) {
265
                $_SWIFT = SWIFT::GetInstance();
266
267
                if (!$this->GetIsClassLoaded()) {
268
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
269
                        return false;
270
                }else if (empty($_ticketID)) {
271
272
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
273
274
                        return false;
275
                }
276
277
278
                /*
279
                 * BUG FIX - Parminder Singh
280
                 *
281
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
282
                 *
283
                 * Comments: If current ticket id is merged with other tickets
284
                 */
285
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
286
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
287
                // Did the object load up?
288
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
289
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
290
                        return false;
291
                }
292
293
                // Check permission
294
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0') {
295
                        throw new SWIFT_Exception(SWIFT_NOPERMISSION);
296
                        return false;
297
298
                }
299
                $_staffCache = $this->Cache->Get('staffcache');
300
                $_departmentCache = $this->Cache->Get('departmentcache');
301
                $_ticketStatusCache = $this->Cache->Get('statuscache');
302
                $_ticketPriorityCache = $this->Cache->Get('prioritycache');
303
                $_ticketTypeCache = $this->Cache->Get('tickettypecache');
304
305
                /*
306
                 * BUG FIX - Varun Shoor
307
                 *
308
                 * SWIFT-1553 The Print function does not print the reply from top even if setting is correct
309
                 *
310
                 * Comments: None
311
                 */
312
313
                $_ticketPostOrder = 'ASC';
314
                if ($this->Settings->Get('t_postorder') == 'desc') {
315
                        $_ticketPostOrder = 'DESC';
316
                }
317
318
                $_ticketPostContainer = $_SWIFT_TicketObject->GetTicketPosts(false, false, $_ticketPostOrder);
319
                $_ticketPostArray = array();
320
                foreach ($_ticketPostContainer as $_ticketPostID => $_SWIFT_TicketPostObject) {
321
                        $_ticketPostArray[$_ticketPostID]['fullname'] = StripName(htmlspecialchars($_SWIFT_TicketPostObject->GetProperty('fullname')), 19);
322
                        $_designation = '';
323
                        if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_STAFF && isset($_staffCache[$_SWIFT_TicketPostObject->GetProperty('staffid')]) && !empty($_staffCache[$_SWIFT_TicketPostObject->GetProperty('staffid')]['designation'])) {
324
                                 $_designation = htmlspecialchars($_staffCache[$_SWIFT_TicketPostObject->GetProperty('staffid')]['designation']);
325
                        }elseif ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_USER && $_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetProperty('userdesignation') != '') {
326
                                $_designation = htmlspecialchars($_SWIFT_UserObject->GetProperty('userdesignation'));
327
                        }
328
329
                        $_ticketPostArray[$_ticketPostID]['designation'] = $_designation;
330
                        if ($_SWIFT_TicketPostObject->GetProperty('isthirdparty') == '1' || $_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_THIRDPARTY) {
331
                                $_creator = $this->Language->Get('badgethirdparty');
332
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_CC) {
333
                                $_creator = $this->Language->Get('badgecc');
334
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_BCC) {
335
                                $_creator = $this->Language->Get('badgebcc');
336
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_USER) {
337
                                $_creator = $this->Language->Get('badgeuser');
338
                        } else if ($_SWIFT_TicketPostObject->GetProperty('creator') == SWIFT_TicketPost::CREATOR_STAFF) {
339
                                $_creator = $this->Language->Get('badgestaff');
340
                        }
341
                        $_ticketPostArray[$_ticketPostID]['creator'] = $_creator;
342
                        $_ticketPostArray[$_ticketPostID]['contents'] = $_SWIFT_TicketPostObject->GetDisplayContents();
343
                        $_ticketPostArray[$_ticketPostID]['date'] = sprintf($this->Language->Get(IIF($_SWIFT_TicketPostObject->GetProperty('issurveycomment') == '1', 'tppostedonsurvey', 'tppostedon')), SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_SWIFT_TicketPostObject->GetProperty('dateline')));
344
                }
345
346
                $_departmentTitle = $this->Language->Get('na');
347
                if ($_SWIFT_TicketObject->GetProperty('departmentid') == '0') {
348
                        $_departmentTitle = $this->Language->Get('trash');
349
                } else if (isset($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')])) {
350
                        $_departmentTitle = $_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')]['title'];
351
                }
352
353
                $_ticketStatusContainer = false;
354
                if (isset($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')])) {
355
                        $_ticketStatusContainer = $_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')];
356
                        $_ticketStatusTitle = $_ticketStatusContainer['title'];
357
                } else {
358
                        $_ticketStatusTitle = $this->Language->Get('na');
359
                }
360
361
                $_ticketPriorityContainer = false;
362
                if (isset($_ticketPriorityCache[$_SWIFT_TicketObject->GetProperty('priorityid')])) {
363
                        $_ticketPriorityContainer = $_ticketPriorityCache[$_SWIFT_TicketObject->GetProperty('priorityid')];
364
                        $_ticketPriorityTitle = $_ticketPriorityContainer['title'];
365
                } else {
366
                        $_ticketPriorityTitle = $this->Language->Get('na');
367
                }
368
369
370
                $_ticketTypeContainer = false;
371
                if (isset($_ticketTypeCache[$_SWIFT_TicketObject->GetProperty('tickettypeid')])) {
372
                        $_ticketTypeContainer = $_ticketTypeCache[$_SWIFT_TicketObject->GetProperty('tickettypeid')];
373
                        $_ticketTypeTitle = $_ticketTypeContainer['title'];
374
                } else {
375
                        $_ticketTypeTitle = $this->Language->Get('na');
376
                }
377
378
                $_ticketOwnerContainer = false;
379
                if (isset($_staffCache[$_SWIFT_TicketObject->GetProperty('ownerstaffid')])) {
380
                        $_ticketOwnerContainer = $_staffCache[$_SWIFT_TicketObject->GetProperty('ownerstaffid')];
381
                        $_ticketOwnerTitle = $_ticketOwnerContainer['fullname'];
382
                } else if ($_SWIFT_TicketObject->GetProperty('ownerstaffid') == '0') {
383
                        $_ticketOwnerTitle = $this->Language->Get('unassigned2');
384
                } else {
385
                        $_ticketOwnerTitle = $this->Language->Get('na');
386
                }
387
388
                $_billingEntries = '';
389
                if ($_SWIFT_TicketObject->GetProperty('hasbilling') == '1' && $_SWIFT->Staff->GetPermission('staff_tcanviewbilling') != '0') {
390
                        $_totalTimeSpent = $_SWIFT_TicketObject->GetProperty('timeworked');
391
                        $_totalTimeBillable = $_SWIFT_TicketObject->GetProperty('timebilled');
392
                        $_billingEntries = '<div class="ticketbillinginfocontainer">';
393
                        $_billingEntries .= '<img src="' . SWIFT::Get('themepathimages') . 'icon_clock.png' . '" align="absmiddle" border="0" /> ' .
394
                                        '<b>' . $this->Language->Get('billtotalworked') . '</b> ' . SWIFT_Date::ColorTime($_totalTimeSpent, false, true) .
395
                                        '&nbsp;&nbsp;&nbsp;&nbsp;' .
396
                                        '<b>' . $this->Language->Get('billtotalbillable') . '</b> ' . SWIFT_Date::ColorTime($_totalTimeBillable, false, true);
397
                        $_billingEntries .= '</div>';
398
                }
399
400
                $_customFields = $this->CustomFieldRendererStaff->Render(SWIFT_CustomFieldRenderer::TYPE_STATIC, SWIFT_UserInterface::MODE_INSERT, array(SWIFT_CustomFieldGroup::GROUP_STAFFTICKET, SWIFT_CustomFieldGroup::GROUP_USERTICKET, SWIFT_CustomFieldGroup::GROUP_STAFFUSERTICKET), null, $_SWIFT_TicketObject->GetTicketID(), $_SWIFT_TicketObject->GetProperty('departmentid'), true,true);
401
402
                $this->Template->Assign('_companyName', SWIFT::Get('companyname'));
403
                $this->Template->Assign('_ticketID', $_SWIFT_TicketObject->GetTicketDisplayID());
404
                $this->Template->Assign('_ticketSubject', htmlspecialchars($_SWIFT_TicketObject->GetProperty('subject')));
405
                $this->Template->Assign('_departmentTitle', $_departmentTitle);
406
                $this->Template->Assign('_ticketStatusTitle', $_ticketStatusTitle);
407
                $this->Template->Assign('_ticketPriorityTitle', $_ticketPriorityTitle);
408
                $this->Template->Assign('_ticketTypeTitle', $_ticketTypeTitle);
409
                $this->Template->Assign('_ticketOwnerTitle', $_ticketOwnerTitle);
410
                $this->Template->Assign('_ticketDate', SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_SWIFT_TicketObject->GetProperty('dateline')));
411
                $this->Template->Assign('_ticketUpdated', SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_SWIFT_TicketObject->GetProperty('lastactivity')));
412
                $this->Template->Assign('_ticketPost', $_ticketPostArray);
413
                $this->Template->Assign('_customFields', $_customFields);
414
                $this->Template->Assign('_billingEntries', $_billingEntries);
415
416
417
418
                $this->Template->Render('printticket');
419
420
                return true;
421
        }
422
423
        /**
424
         * Delete a ticket post
425
         *
426
         * @author Varun Shoor
427
         * @param int $_ticketID The Ticket ID
428
         * @param int $_ticketPostID The Ticket Post ID
429
         * @param string $_listType (OPTIONAL) The List Type
430
         * @param int $_departmentID (OPTIONAL) The Department ID
431
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
432
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
433
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
434
         * @return bool "true" on Success, "false" otherwise
435
         * @throws SWIFT_Exception If the Class is not Loaded
436
         */
437
        public function DeletePost($_ticketID, $_ticketPostID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
438
                        $_ticketLimitOffset = 0) {
439
440
                $_SWIFT = SWIFT::GetInstance();
441
442
                if (!$this->GetIsClassLoaded()) {
443
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
444
445
                        return false;
446
                }
447
448
                /*
449
                 * BUG FIX - Parminder Singh
450
                 *
451
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
452
                 *
453
                 * Comments: If current ticket id is merged with other tickets
454
                 */
455
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
456
457
                // Did the object load up?
458
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
459
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
460
                }
461
462
                // Check permission
463
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcandeleteticketpost') == '0') {
464
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
465
                                        self::NAVIGATION_ID);
466
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
467
                        $this->UserInterface->Footer();
468
469
                        return false;
470
471
                }
472
473
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
474
                // Did the object load up?
475
                if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded()) {
476
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
477
                }
478
479
                if ($_SWIFT_TicketPostObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID() ||
480
                                $_SWIFT->Staff->GetPermission('staff_tcandeleteticketpost') == '0') {
481
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
482
                }
483
484
                // Create Audit Log
485
                $_logText = sprintf($_SWIFT->Language->Get('al_deleteticketpost'), $_SWIFT_TicketPostObject->GetProperty('fullname'),
486
                                $_SWIFT_TicketPostObject->GetProperty('email'));
487
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_DELETETICKETPOST,
488
                                $_logText, SWIFT_TicketAuditLog::VALUE_NONE, 0, '',
489
                                0, '');
490
491
                // Activity Log
492
                SWIFT_StaffActivityLog::AddToLog($_logText,
493
                                SWIFT_StaffActivityLog::ACTION_DELETE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
494
495
                $_SWIFT_TicketPostObject->Delete();
496
497
                $_SWIFT_TicketObject->RebuildProperties();
498
499
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
500
501
                return true;
502
        }
503
504
        /**
505
         * Edit a Ticket Post
506
         *
507
         * @author Varun Shoor
508
         * @param int $_ticketID The Ticket ID
509
         * @param int $_ticketPostID The Ticket Post ID
510
         * @param string $_listType (OPTIONAL) The List Type
511
         * @param int $_departmentID (OPTIONAL) The Department ID
512
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
513
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
514
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
515
         * @return bool "true" on Success, "false" otherwise
516
         * @throws SWIFT_Exception If the Class is not Loaded
517
         */
518
        public function EditPost($_ticketID, $_ticketPostID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
519
                        $_ticketLimitOffset = 0) {
520
521
                $_SWIFT = SWIFT::GetInstance();
522
523
                if (!$this->GetIsClassLoaded()) {
524
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
525
526
                        return false;
527
                }
528
529
                /*
530
                 * BUG FIX - Parminder Singh
531
                 *
532
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
533
                 *
534
                 * Comments: If current ticket id is merged with other tickets
535
                 */
536
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
537
538
                // Did the object load up?
539
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
540
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
541
                }
542
543
                // Check permission
544
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupaticketpost') == '0') {
545
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
546
                                        self::NAVIGATION_ID);
547
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
548
                        $this->UserInterface->Footer();
549
550
                        return false;
551
552
                }
553
554
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
555
                // Did the object load up?
556
                if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded()) {
557
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
558
                }
559
560
                if ($_SWIFT_TicketPostObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID() ||
561
                                $_SWIFT->Staff->GetPermission('staff_tcanupaticketpost') == '0') {
562
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
563
                }
564
565
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('editpost'), self::MENU_ID, self::NAVIGATION_ID);
566
                $this->View->RenderEditPost($_SWIFT_TicketObject, $_SWIFT_TicketPostObject, $_listType, $_departmentID,
567
                                $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
568
                $this->UserInterface->Footer();
569
570
                return true;
571
        }
572
573
574
        /**
575
         * Edit a ticket post (Submission)
576
         *
577
         * @author Varun Shoor
578
         * @param int $_ticketID The Ticket ID
579
         * @param int $_ticketPostID The Ticket Post ID
580
         * @param string $_listType (OPTIONAL) The List Type
581
         * @param int $_departmentID (OPTIONAL) The Department ID
582
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
583
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
584
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
585
         * @return bool "true" on Success, "false" otherwise
586
         * @throws SWIFT_Exception If the Class is not Loaded
587
         */
588
        public function EditPostSubmit($_ticketID, $_ticketPostID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
589
                        $_ticketLimitOffset = 0) {
590
591
                $_SWIFT = SWIFT::GetInstance();
592
593
                if (!$this->GetIsClassLoaded()) {
594
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
595
596
                        return false;
597
                }
598
599
                /*
600
                 * BUG FIX - Parminder Singh
601
                 *
602
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
603
                 *
604
                 * Comments: If current ticket id is merged with other tickets
605
                 */
606
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
607
608
                // Did the object load up?
609
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
610
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
611
                }
612
613
                // Check permission
614
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupaticketpost') == '0') {
615
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
616
                                        self::NAVIGATION_ID);
617
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
618
                        $this->UserInterface->Footer();
619
620
                        return false;
621
622
                }
623
624
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
625
                // Did the object load up?
626
                if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded()) {
627
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
628
                }
629
630
                if ($_SWIFT_TicketPostObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID() ||
631
                                $_SWIFT->Staff->GetPermission('staff_tcanupaticketpost') == '0') {
632
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
633
                }
634
635
                $_SWIFT_TicketPostObject->Update($_POST['postcontents'], $_SWIFT->Staff->GetStaffID());
636
637
                // Create Audit Log
638
                $_logText = sprintf($_SWIFT->Language->Get('al_updateticketpost'), $_SWIFT_TicketPostObject->GetProperty('fullname'),
639
                                $_SWIFT_TicketPostObject->GetProperty('email'));
640
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKETPOST,
641
                                $_logText, SWIFT_TicketAuditLog::VALUE_NONE, 0, '',
642
                                0, '');
643
644
                // Activity Log
645
                SWIFT_StaffActivityLog::AddToLog($_logText,
646
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
647
648
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
649
650
                return true;
651
        }
652
653
        /**
654
         * Retrieve an attachment
655
         *
656
         * @author Varun Shoor
657
         * @param int $_ticketID The Ticket ID
658
         * @param int $_attachmentID The Attachment ID
659
         * @return bool "true" on Success, "false" otherwise
660
         * @throws SWIFT_Exception If the Class is not Loaded
661
         */
662
        public function GetAttachment($_ticketID, $_attachmentID) {
663
664
                $_SWIFT = SWIFT::GetInstance();
665
666
                if (!$this->GetIsClassLoaded()) {
667
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
668
669
                        return false;
670
                }
671
672
                /*
673
                 * BUG FIX - Parminder Singh
674
                 *
675
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
676
                 *
677
                 * Comments: If current ticket id is merged with other tickets
678
                 */
679
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
680
681
                // Did the object load up?
682
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
683
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
684
                }
685
686
                // Check permission
687
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0') {
688
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
689
                                        self::NAVIGATION_ID);
690
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
691
                        $this->UserInterface->Footer();
692
693
                        return false;
694
695
                }
696
697
                $_SWIFT_AttachmentObject = new SWIFT_Attachment($_attachmentID);
698
                // Did the object load up?
699
                if (!$_SWIFT_AttachmentObject instanceof SWIFT_Attachment || !$_SWIFT_AttachmentObject->GetIsClassLoaded()) {
700
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
701
                }
702
703
                if ($_SWIFT_AttachmentObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID()) {
704
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
705
                }
706
707
                $_SWIFT_AttachmentObject->Dispatch();
708
709
                return true;
710
        }
711
712
713
        /**
714
         * SUBMISSION: General Tab
715
         *
716
         * @author Varun Shoor
717
         * @param int $_ticketID The Ticket ID
718
         * @param string $_listType (OPTIONAL) The List Type
719
         * @param int $_departmentID (OPTIONAL) The Department ID
720
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
721
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
722
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
723
         * @return bool "true" on Success, "false" otherwise
724
         * @throws SWIFT_Exception If the Class is not Loaded
725
         */
726
        public function GeneralSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
727
                        $_ticketLimitOffset = 0) {
728
729
                $_SWIFT = SWIFT::GetInstance();
730
731
                if (!$this->GetIsClassLoaded()) {
732
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
733
734
                        return false;
735
                }
736
737
                /*
738
                 * BUG FIX - Parminder Singh
739
                 *
740
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
741
                 *
742
                 * Comments: If current ticket id is merged with other tickets
743
                 */
744
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
745
                $_SWIFT_TicketObject->SetOldTicketProperties();
746
747
                // Did the object load up?
748
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
749
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
750
                }
751
752
                // Check permission
753
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
754
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
755
                                        self::NAVIGATION_ID);
756
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
757
                        $this->UserInterface->Footer();
758
759
                        return false;
760
761
                }
762
                /*
763
                 * BUG FIX - Nidhi Gupta
764
                 *
765
                 * SWIFT-839: Permission to restrict staff from moving tickets to departments they're not assigned to
766
                 *
767
                 * Comments: Added check for staff to move tickets in unassigned departments
768
                 */
769
                // Update Properties
770
                if ($_SWIFT->Staff->GetPermission('staff_tcanchangeunassigneddepartment') == '0') {
771
                        if ($_SWIFT_TicketObject->Get('departmentid') != $_POST['gendepartmentid'] && !in_array($_POST['gendepartmentid'], $_SWIFT->Staff->GetAssignedDepartments())) {
772
                                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
773
                                        self::NAVIGATION_ID);
774
                                $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
775
                                $this->UserInterface->Footer();
776
777
                                return false;
778
                        }
779
                }
780
781
782
                // Process Tags
783
                if ($_SWIFT->Staff->GetPermission('staff_canupdatetags') != '0')
784
                {
785
                        SWIFT_Tag::Process(SWIFT_TagLink::TYPE_TICKET, $_SWIFT_TicketObject->GetTicketID(),
786
                                        SWIFT_UserInterface::GetMultipleInputValues('tags'), $_SWIFT->Staff->GetStaffID());
787
                }
788
789
                // Update Properties
790
                if (isset($_POST['gendepartmentid']) && !empty($_POST['gendepartmentid'])) {
791
                        $_SWIFT_TicketObject->SetDepartment($_POST['gendepartmentid']);
792
                }
793
794
                if (isset($_POST['genownerstaffid'])) {
795
                        $_SWIFT_TicketObject->SetOwner($_POST['genownerstaffid']);
796
                }
797
798
                if (isset($_POST['gentickettypeid']) && !empty($_POST['gentickettypeid'])) {
799
                        $_SWIFT_TicketObject->SetType($_POST['gentickettypeid']);
800
                }
801
802
                if (isset($_POST['genticketstatusid']) && !empty($_POST['genticketstatusid'])) {
803
                        $_SWIFT_TicketObject->SetStatus($_POST['genticketstatusid']);
804
                }
805
806
                if (isset($_POST['genticketpriorityid']) && !empty($_POST['genticketpriorityid'])) {
807
                        $_SWIFT_TicketObject->SetPriority($_POST['genticketpriorityid']);
808
                }
809
810
                $_SWIFT_TicketObject->ProcessUpdatePool();
811
                SWIFT_TicketManager::RebuildCache();
812
813
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
814
815
                // Begin Hook: staff_ticket_general
816
                unset($_hookCode);
817
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_general')) ? eval($_hookCode) : false;
818
                // End Hook
819
820
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
821
822
                $_nextTicketID = false;
823
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
824
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
825
                }
826
827
                // Does the new department belong to this staff? if not, we need to jump him back to list!
828
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
829
                if (isset($_POST['gendepartmentid']) && !empty($_POST['gendepartmentid']) && !in_array($_POST['gendepartmentid'], $_assignedDepartmentIDList)) {
830
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
831
832
                        return true;
833
                }
834
835
                if ($_SWIFT_TicketObject->GetProperty('isresolved') == '1' && $_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
836
                {
837
                        $GLOBALS['_POST'] = $GLOBALS['_REQUEST'] = $GLOBALS['_GET'] = array();
838
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
839
                } else if ($_SWIFT_TicketObject->GetProperty('isresolved') == '1' && $_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
840
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
841
842
                } else if ($_SWIFT_TicketObject->GetProperty('isresolved') == '1' && $_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
843
                        $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
844
845
                } else if ($_SWIFT_TicketObject->GetProperty('isresolved') == '1' && $_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
846
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
847
                } else {
848
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
849
                }
850
851
852
                return true;
853
        }
854
855
856
        /**
857
         * Flag a Ticket
858
         *
859
         * @author Varun Shoor
860
         * @param int $_ticketID The Ticket ID
861
         * @param int $_ticketFlagType The Flag Type
862
         * @param string $_listType (OPTIONAL) The List Type
863
         * @param int $_departmentID (OPTIONAL) The Department ID
864
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
865
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
866
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
867
         * @return bool "true" on Success, "false" otherwise
868
         * @throws SWIFT_Exception If the Class is not Loaded
869
         */
870
        public function Flag($_ticketID, $_ticketFlagType, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
871
                        $_ticketLimitOffset = 0) {
872
873
                $_SWIFT = SWIFT::GetInstance();
874
875
                if (!$this->GetIsClassLoaded()) {
876
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
877
878
                        return false;
879
                }
880
881
                /*
882
                 * BUG FIX - Parminder Singh
883
                 *
884
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
885
                 *
886
                 * Comments: If current ticket id is merged with other tickets
887
                 */
888
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
889
890
                // Did the object load up?
891
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
892
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
893
                }
894
895
                // Check permission
896
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
897
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
898
                                        self::NAVIGATION_ID);
899
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
900
                        $this->UserInterface->Footer();
901
902
                        return false;
903
904
                }
905
906
                $_SWIFT_TicketFlagObject = new SWIFT_TicketFlag();
907
                $_ticketFlagContainer = $_SWIFT_TicketFlagObject->GetFlagContainer();
908
                if (!isset($_ticketFlagContainer[$_ticketFlagType]))
909
                {
910
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
911
                }
912
913
                $_SWIFT_TicketObject->SetFlag($_ticketFlagType);
914
915
                $_SWIFT_TicketObject->ProcessUpdatePool();
916
                SWIFT_TicketManager::RebuildCache();
917
918
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
919
920
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
921
922
                return true;
923
        }
924
925
926
        /**
927
         * Watch a Ticket
928
         *
929
         * @author Varun Shoor
930
         * @param int $_ticketID The Ticket ID
931
         * @param string $_listType (OPTIONAL) The List Type
932
         * @param int $_departmentID (OPTIONAL) The Department ID
933
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
934
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
935
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
936
         * @return bool "true" on Success, "false" otherwise
937
         * @throws SWIFT_Exception If the Class is not Loaded
938
         */
939
        public function Watch($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
940
                        $_ticketLimitOffset = 0) {
941
942
                $_SWIFT = SWIFT::GetInstance();
943
944
                if (!$this->GetIsClassLoaded()) {
945
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
946
947
                        return false;
948
                }
949
950
                /*
951
                 * BUG FIX - Parminder Singh
952
                 *
953
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
954
                 *
955
                 * Comments: If current ticket id is merged with other tickets
956
                 */
957
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
958
959
                // Did the object load up?
960
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
961
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
962
                }
963
964
                // Check permission
965
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
966
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
967
                                        self::NAVIGATION_ID);
968
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
969
                        $this->UserInterface->Footer();
970
971
                        return false;
972
973
                }
974
975
                $_departmentCache = $this->Cache->Get('departmentcache');
976
                $_ticketStatusCache = $this->Cache->Get('statuscache');
977
978
                $_departmentTitle = $_ticketStatusTitle = '';
979
                if (isset($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')])) {
980
                        $_departmentTitle = htmlspecialchars($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')]['title']);
981
                }
982
983
                if (isset($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')])) {
984
                        $_ticketStatusTitle = htmlspecialchars($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')]['title']);
985
                }
986
987
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('activitywatchticket'),
988
                                htmlspecialchars($_SWIFT_TicketObject->GetProperty('subject')), htmlspecialchars($_departmentTitle),
989
                                htmlspecialchars($_ticketStatusTitle), htmlspecialchars($_SWIFT_TicketObject->GetProperty('fullname'))),
990
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
991
992
                SWIFT_Ticket::Watch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
993
994
                $_SWIFT_TicketObject->ProcessUpdatePool();
995
                SWIFT_TicketManager::RebuildCache();
996
997
                // SWIFT-2285 Watching a ticket or adding a ticket watcher resets ticket due time
998
999
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1000
1001
                return true;
1002
        }
1003
1004
1005
        /**
1006
         * UnWatch a Ticket
1007
         *
1008
         * @author Varun Shoor
1009
         * @param int $_ticketID The Ticket ID
1010
         * @param string $_listType (OPTIONAL) The List Type
1011
         * @param int $_departmentID (OPTIONAL) The Department ID
1012
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1013
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1014
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1015
         * @return bool "true" on Success, "false" otherwise
1016
         * @throws SWIFT_Exception If the Class is not Loaded
1017
         */
1018
        public function UnWatch($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1019
                        $_ticketLimitOffset = 0) {
1020
1021
                $_SWIFT = SWIFT::GetInstance();
1022
1023
                if (!$this->GetIsClassLoaded()) {
1024
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1025
1026
                        return false;
1027
                }
1028
1029
                /*
1030
                 * BUG FIX - Parminder Singh
1031
                 *
1032
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1033
                 *
1034
                 * Comments: If current ticket id is merged with other tickets
1035
                 */
1036
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1037
1038
                // Did the object load up?
1039
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1040
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1041
                }
1042
1043
                // Check permission
1044
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
1045
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
1046
                                        self::NAVIGATION_ID);
1047
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
1048
                        $this->UserInterface->Footer();
1049
1050
                        return false;
1051
1052
                }
1053
1054
                $_departmentCache = $this->Cache->Get('departmentcache');
1055
                $_ticketStatusCache = $this->Cache->Get('statuscache');
1056
1057
                $_departmentTitle = $_ticketStatusTitle = '';
1058
                if (isset($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')])) {
1059
                        $_departmentTitle = htmlspecialchars($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')]['title']);
1060
                }
1061
1062
                if (isset($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')])) {
1063
                        $_ticketStatusTitle = htmlspecialchars($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')]['title']);
1064
                }
1065
1066
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('activityunwatchticket'),
1067
                                htmlspecialchars($_SWIFT_TicketObject->GetProperty('subject')), htmlspecialchars($_departmentTitle),
1068
                                htmlspecialchars($_ticketStatusTitle), htmlspecialchars($_SWIFT_TicketObject->GetProperty('fullname'))),
1069
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
1070
1071
                SWIFT_Ticket::UnWatch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
1072
1073
                $_SWIFT_TicketObject->ProcessUpdatePool();
1074
                SWIFT_TicketManager::RebuildCache();
1075
1076
                // SWIFT-2285 Watching a ticket or adding a ticket watcher resets ticket due time
1077
1078
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1079
1080
                return true;
1081
        }
1082
1083
1084
        /**
1085
         * Take a Ticket
1086
         *
1087
         * @author Varun Shoor
1088
         * @param int $_ticketID The Ticket ID
1089
         * @param string $_listType (OPTIONAL) The List Type
1090
         * @param int $_departmentID (OPTIONAL) The Department ID
1091
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1092
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1093
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1094
         * @return bool "true" on Success, "false" otherwise
1095
         * @throws SWIFT_Exception If the Class is not Loaded
1096
         */
1097
        public function Take($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1098
                        $_ticketLimitOffset = 0) {
1099
1100
                $_SWIFT = SWIFT::GetInstance();
1101
1102
                if (!$this->GetIsClassLoaded()) {
1103
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1104
1105
                        return false;
1106
                }
1107
1108
                /*
1109
                 * BUG FIX - Parminder Singh
1110
                 *
1111
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1112
                 *
1113
                 * Comments: If current ticket id is merged with other tickets
1114
                 */
1115
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1116
                $_SWIFT_TicketObject->SetOldTicketProperties();
1117
1118
                // Did the object load up?
1119
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1120
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1121
                }
1122
1123
                // Check permission
1124
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
1125
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
1126
                                        self::NAVIGATION_ID);
1127
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
1128
                        $this->UserInterface->Footer();
1129
1130
                        return false;
1131
1132
                }
1133
1134
                $_departmentCache = $this->Cache->Get('departmentcache');
1135
                $_ticketStatusCache = $this->Cache->Get('statuscache');
1136
1137
                $_departmentTitle = $_ticketStatusTitle = '';
1138
                if (isset($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')])) {
1139
                        $_departmentTitle = htmlspecialchars($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')]['title']);
1140
                }
1141
1142
                if (isset($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')])) {
1143
                        $_ticketStatusTitle = htmlspecialchars($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')]['title']);
1144
                }
1145
1146
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('activitytaketicket'),
1147
                                htmlspecialchars($_SWIFT_TicketObject->GetProperty('subject')), htmlspecialchars($_departmentTitle),
1148
                                htmlspecialchars($_ticketStatusTitle), htmlspecialchars($_SWIFT_TicketObject->GetProperty('fullname'))),
1149
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
1150
1151
                $_SWIFT_TicketObject->SetOwner($_SWIFT->Staff->GetStaffID());
1152
1153
                $_SWIFT_TicketObject->ProcessUpdatePool();
1154
                SWIFT_TicketManager::RebuildCache();
1155
1156
                /*
1157
                 * BUG FIX - Abhishek Mittal
1158
                 *
1159
                 * SWIFT-3616 Reply due time should not be reset when flagging a ticket
1160
                 *
1161
                 * Comments: Issue also persists when using "Take"
1162
                 */
1163
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
1164
1165
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1166
1167
                return true;
1168
        }
1169
1170
1171
        /**
1172
         * Take a Ticket
1173
         *
1174
         * @author Varun Shoor
1175
         * @param int $_ticketID The Ticket ID
1176
         * @param string $_listType (OPTIONAL) The List Type
1177
         * @param int $_departmentID (OPTIONAL) The Department ID
1178
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1179
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1180
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1181
         * @return bool "true" on Success, "false" otherwise
1182
         * @throws SWIFT_Exception If the Class is not Loaded
1183
         */
1184
        public function Surrender($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1185
                        $_ticketLimitOffset = 0) {
1186
1187
                $_SWIFT = SWIFT::GetInstance();
1188
1189
                if (!$this->GetIsClassLoaded()) {
1190
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1191
1192
                        return false;
1193
                }
1194
1195
                /*
1196
                 * BUG FIX - Parminder Singh
1197
                 *
1198
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1199
                 *
1200
                 * Comments: If current ticket id is merged with other tickets
1201
                 */
1202
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1203
                $_SWIFT_TicketObject->SetOldTicketProperties();
1204
1205
                // Did the object load up?
1206
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1207
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1208
                }
1209
1210
                // Check permission
1211
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
1212
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
1213
                                        self::NAVIGATION_ID);
1214
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
1215
                        $this->UserInterface->Footer();
1216
1217
                        return false;
1218
1219
                }
1220
1221
                $_departmentCache = $this->Cache->Get('departmentcache');
1222
                $_ticketStatusCache = $this->Cache->Get('statuscache');
1223
1224
                $_departmentTitle = $_ticketStatusTitle = '';
1225
                if (isset($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')])) {
1226
                        $_departmentTitle = htmlspecialchars($_departmentCache[$_SWIFT_TicketObject->GetProperty('departmentid')]['title']);
1227
                }
1228
1229
                if (isset($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')])) {
1230
                        $_ticketStatusTitle = htmlspecialchars($_ticketStatusCache[$_SWIFT_TicketObject->GetProperty('ticketstatusid')]['title']);
1231
                }
1232
1233
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('activitysurrenderticket'),
1234
                                htmlspecialchars($_SWIFT_TicketObject->GetProperty('subject')), htmlspecialchars($_departmentTitle),
1235
                                htmlspecialchars($_ticketStatusTitle), htmlspecialchars($_SWIFT_TicketObject->GetProperty('fullname'))),
1236
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
1237
1238
                $_SWIFT_TicketObject->SetOwner('0');
1239
1240
                $_SWIFT_TicketObject->ProcessUpdatePool();
1241
                SWIFT_TicketManager::RebuildCache();
1242
1243
                /*
1244
                 * BUG FIX - Abhishek Mittal
1245
                 *
1246
                 * SWIFT-3616 Reply due time should not be reset when flagging a ticket
1247
                 *
1248
                 * Comments: Issue also persists when using "Surrender"
1249
                 */
1250
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
1251
1252
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1253
1254
                return true;
1255
        }
1256
1257
        /**
1258
         * Render the New Ticket Dialog
1259
         *
1260
         * @author Varun Shoor
1261
         * @param int $_chatObjectID (OPTIONAL) The Chat Object ID
1262
         * @return bool "true" on Success, "false" otherwise
1263
         * @throws SWIFT_Exception If the Class is not Loaded
1264
         */
1265
        public function NewTicket($_chatObjectID = false) {
1266
                $_SWIFT = SWIFT::GetInstance();
1267
1268
                if (!$this->GetIsClassLoaded()) {
1269
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1270
1271
                        return false;
1272
                }
1273
1274
                // Check permission
1275
                if ($_SWIFT->Staff->GetPermission('staff_tcaninsertticket') == '0') {
1276
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('newticket'), self::MENU_ID,
1277
                                        self::NAVIGATION_ID);
1278
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
1279
                        $this->UserInterface->Footer();
1280
1281
                        return false;
1282
1283
                }
1284
1285
                if (is_numeric($_chatObjectID))
1286
                {
1287
                        $_chatObjectID = intval($_chatObjectID);
1288
                } else {
1289
                        $_chatObjectID = false;
1290
                }
1291
1292
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('newticket'), self::MENU_ID,
1293
                                self::NAVIGATION_ID);
1294
                $this->View->RenderNewTicketDialog($_chatObjectID);
1295
                $this->UserInterface->Footer();
1296
1297
                return true;
1298
        }
1299
1300
        /**
1301
         * Render the New Ticket Form
1302
         *
1303
         * @author Varun Shoor
1304
         * @return bool "true" on Success, "false" otherwise
1305
         * @throws SWIFT_Exception If the Class is not Loaded
1306
         */
1307
        public function NewTicketForm() {
1308
                $_SWIFT = SWIFT::GetInstance();
1309
1310
                if (!$this->GetIsClassLoaded()) {
1311
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1312
1313
                        return false;
1314
                }
1315
1316
                $_templateGroupCache = $this->Cache->Get('templategroupcache');
1317
1318
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
1319
1320
                // Check permission
1321
                if ($_SWIFT->Staff->GetPermission('staff_tcaninsertticket') == '0') {
1322
                        $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('newticket'), self::MENU_ID,
1323
                                        self::NAVIGATION_ID);
1324
                        $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
1325
                        $this->UserInterface->Footer();
1326
1327
                        return false;
1328
1329
                } else if (!isset($_POST['departmentid']) || !isset($_POST['tickettype']) || empty($_POST['departmentid']) || empty($_POST['tickettype'])) {
1330
                        $this->Load->NewTicket();
1331
1332
                        return false;
1333
                } else if (!in_array($_POST['departmentid'], $_assignedDepartmentIDList) && $_SWIFT->Settings->Get('t_restrictnewticket') == '1') {
1334
                        throw new SWIFT_Exception('No Permission to Department');
1335
                }
1336
1337
                $_finalTicketType = View_Ticket::TAB_NEWTICKET_EMAIL;
1338
                if ($_POST['tickettype'] == 'user')
1339
                {
1340
                        $_finalTicketType = View_Ticket::TAB_NEWTICKET_USER;
1341
                }
1342
1343
                /**
1344
                 * ---------------------------------------------
1345
                 * LIVE CHAT INTEGRATION
1346
                 * ---------------------------------------------
1347
                 */
1348
1349
                if (SWIFT_App::IsInstalled(APP_LIVECHAT) && isset($_POST['chatobjectid']) && !empty($_POST['chatobjectid']))
1350
                {
1351
                        SWIFT_Loader::LoadModel('Chat:Chat', APP_LIVECHAT);
1352
                        SWIFT_Loader::LoadModel('Chat:ChatQueue', APP_LIVECHAT);
1353
1354
                        $_SWIFT_ChatObject = false;
1355
                        try {
1356
                                $_SWIFT_ChatObject = new SWIFT_Chat($_POST['chatobjectid']);
1357
                        } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
1358
1359
                        }
1360
1361
                        if ($_SWIFT_ChatObject instanceof SWIFT_Chat && $_SWIFT_ChatObject->GetIsClassLoaded() && $_SWIFT_ChatObject->CanAccess($_SWIFT->Staff)) {
1362
                                /*
1363
                                 * BUG FIX - Varun Shoor
1364
                                 *
1365
                                 * SWIFT-1428 "Skip User Details" option when used while Tag Generation, throws an error while ticket creation from KD
1366
                                 *
1367
                                 * Comments: Falls back to staff email address if no user email is present
1368
                                 */
1369
                                $_userEmailAddress = $_SWIFT_ChatObject->GetProperty('useremail');
1370
                                if (empty($_userEmailAddress)) {
1371
                                        $_userEmailAddress = $_SWIFT->Staff->GetProperty('email');
1372
                                }
1373
1374
                                // Now attempt to load the data and integrate it into _POST
1375
                                $_chatDataArray = $_SWIFT_ChatObject->GetConversationArray();
1376
1377
                                $_conversation = $this->Language->Get('ntchatid') . $_SWIFT_ChatObject->GetProcessedChatID() . SWIFT_CRLF;
1378
                                $_conversation .= $this->Language->Get('ntchatuserfullname') . $_SWIFT_ChatObject->GetProperty('userfullname') . SWIFT_CRLF;
1379
                                $_conversation .= $this->Language->Get('ntchatuseremail') . $_userEmailAddress . SWIFT_CRLF;
1380
                                $_conversation .= $this->Language->Get('ntchatstafffullname') . $_SWIFT_ChatObject->GetProperty('staffname') . SWIFT_CRLF;
1381
                                $_conversation .= $this->Language->Get('ntchatdepartment') . $_SWIFT_ChatObject->GetProperty('departmenttitle') . SWIFT_CRLF . SWIFT_CRLF;
1382
1383
                                foreach ($_chatDataArray as $_val) {
1384
                                        if ($_val['type'] != SWIFT_ChatQueue::MESSAGE_SYSTEM && $_val['type'] != SWIFT_ChatQueue::MESSAGE_STAFF && $_val['type'] != SWIFT_ChatQueue::MESSAGE_CLIENT) {
1385
                                                continue;
1386
                                        }
1387
1388
                                        if ($this->Settings->Get('livechat_timestamps') == true) {
1389
                                                $_conversation .= '' . $_val['timestamp'] . ' ';
1390
                                        }
1391
1392
                                        if ($_val['type'] == SWIFT_ChatQueue::MESSAGE_SYSTEM) {
1393
                                                $_conversation .= '* ' . $_val['messagehtml'] . SWIFT_CRLF;
1394
                                        } else if ($_val['type'] == SWIFT_ChatQueue::MESSAGE_STAFF || $_val['type'] == SWIFT_ChatQueue::MESSAGE_CLIENT) {
1395
                                                $_conversation .= $_val['name'] . ': ' . $_val['messagehtml'] . SWIFT_CRLF;
1396
                                        }
1397
                                }
1398
1399
                                $_POST['newticketsubject'] = $_SWIFT_ChatObject->GetProperty('subject');
1400
                                $_POST['newticketcontents'] = nl2br($_conversation);
1401
                                $_POST['containertaginput_newticketto'] = array($_userEmailAddress);
1402
1403
                                // Do we need to load up the user?
1404
                                if ($_POST['tickettype'] == 'user' && $_SWIFT_ChatObject->GetProperty('chattype') == SWIFT_Chat::CHATTYPE_CLIENT) {
1405
                                        $_SWIFT_UserObject = false;
1406
                                        if ($_SWIFT_ChatObject->GetProperty('userid') != '0') {
1407
                                                // Attempt to load the user
1408
                                                try {
1409
                                                        $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_SWIFT_ChatObject->GetProperty('userid')));
1410
                                                } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
1411
1412
                                                        return false;
1413
                                                }
1414
                                        }
1415
1416
                                        // Couldnt load user from ID? attempt to load it from email
1417
                                        if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded()) {
1418
                                                // Do we have a valid template group?
1419
                                                $_userGroupID = false;
1420
1421
                                                if (isset($_templateGroupCache[$_SWIFT_ChatObject->GetProperty('tgroupid')])) {
1422
                                                        $_userGroupID = $_templateGroupCache[$_SWIFT_ChatObject->GetProperty('tgroupid')]['regusergroupid'];
1423
1424
                                                        // Go through the master group
1425
                                                } else {
1426
                                                        $_masterTemplateGroupID = SWIFT_TemplateGroup::GetDefaultGroupID();
1427
                                                        $_userGroupID = $_templateGroupCache[$_masterTemplateGroupID]['regusergroupid'];
1428
                                                }
1429
1430
                                                if (empty($_userGroupID)) {
1431
                                                        throw new SWIFT_Exception('Invalid User Group ID');
1432
                                                }
1433
1434
                                                $_userID = SWIFT_Ticket::GetOrCreateUserID($_SWIFT_ChatObject->GetProperty('userfullname'), $_userEmailAddress, $_userGroupID, false, false);
1435
1436
                                                $_POST['userid'] = $_SWIFT_ChatObject->GetProperty('userfullname');
1437
                                                $_POST['autocomplete_userid'] = $_userID;
1438
                                        } else {
1439
                                                $_POST['userid'] = $_SWIFT_UserObject->GetProperty('fullname');
1440
                                                $_POST['autocomplete_userid'] = $_SWIFT_UserObject->GetUserID();
1441
                                        }
1442
                                }
1443
                        }
1444
                }
1445
1446
1447
                $this->UserInterface->AddNavigationBox($this->Language->Get('quickfilter'), SWIFT_TicketViewRenderer::RenderTree('inbox', -1, -1, -1));
1448
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('newticket'), self::MENU_ID,
1449
                                self::NAVIGATION_ID);
1450
                $this->View->RenderNewTicket($_finalTicketType, intval($_POST['departmentid']));
1451
                $this->UserInterface->Footer();
1452
1453
                return true;
1454
        }
1455
1456
        /**
1457
         * Render the Billing tab for this Ticket
1458
         *
1459
         * @author Varun Shoor
1460
         * @param int $_ticketID The Ticket ID
1461
         * @param string $_listType (OPTIONAL) The List Type
1462
         * @param int $_departmentID (OPTIONAL) The Department ID
1463
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1464
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1465
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1466
         * @return bool "true" on Success, "false" otherwise
1467
         * @throws SWIFT_Exception If the Class is not Loaded
1468
         */
1469
        public function Billing($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1470
                        $_ticketLimitOffset = 0) {
1471
                $_SWIFT = SWIFT::GetInstance();
1472
1473
                if (!$this->GetIsClassLoaded()) {
1474
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1475
1476
                        return false;
1477
                }
1478
1479
1480
                /*
1481
                 * BUG FIX - Parminder Singh
1482
                 *
1483
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1484
                 *
1485
                 * Comments: If current ticket id is merged with other tickets
1486
                 */
1487
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1488
1489
                // Did the object load up?
1490
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1491
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1492
                }
1493
1494
                // Check permission
1495
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
1496
                        echo $this->Language->Get('msgnoperm');
1497
1498
                        return false;
1499
1500
                }
1501
1502
                SWIFT::Set('ticketurlsuffix', $_listType . '/' . $_departmentID . '/' . $_ticketStatusID . '/' . $_ticketTypeID . '/' . $_ticketLimitOffset);
1503
1504
                $this->View->RenderBilling($_SWIFT_TicketObject, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1505
1506
                return true;
1507
        }
1508
1509
        /**
1510
         * Render the Billing tab for user
1511
         *
1512
         * @author Varun Shoor
1513
         * @param int $_userID The User ID
1514
         * @return bool "true" on Success, "false" otherwise
1515
         * @throws SWIFT_Exception If the Class is not Loaded
1516
         */
1517
        public function BillingUser($_userID) {
1518
                if (!$this->GetIsClassLoaded()) {
1519
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1520
1521
                        return false;
1522
                }
1523
1524
                $_SWIFT = SWIFT::GetInstance();
1525
1526
                if (!$this->GetIsClassLoaded()) {
1527
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1528
1529
                        return false;
1530
                }
1531
1532
                $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_userID));
1533
1534
                // Did the object load up?
1535
                if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded()) {
1536
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1537
                }
1538
1539
                $this->View->RenderBillingUser($_SWIFT_UserObject);
1540
1541
                return true;
1542
        }
1543
1544
        /**
1545
         * Check to see if its a valid billing time (hh:mm)
1546
         *
1547
         * @author Varun Shoor
1548
         * @param string $_billingTime Check Billing Time
1549
         * @return bool "true" on Success, "false" otherwise
1550
         * @throws SWIFT_Exception If Invalid Data is Provided
1551
         */
1552
        static protected function IsValidBillingTime($_billingTime)
1553
        {
1554
                $_SWIFT = SWIFT::GetInstance();
1555
1556
                $_matches = array();
1557
1558
                if (!preg_match('@([\d]{2}):([\d]{2})@', $_billingTime, $_matches))
1559
                {
1560
                        return false;
1561
                }
1562
1563
                if (!intval($_matches[1]) && !intval($_matches[2]))
1564
                {
1565
                        return false;
1566
                }
1567
1568
                return true;
1569
        }
1570
1571
        /**
1572
         * Parse hh:mm and retrieve time in seconds
1573
         *
1574
         * @author Varun Shoor
1575
         * @param string $_billingTime Check Billing Time
1576
         * @return int The Billing Seconds
1577
         * @throws SWIFT_Exception If Invalid Data is Provided
1578
         */
1579
        static protected function GetBillingTime($_billingTime)
1580
        {
1581
                $_SWIFT = SWIFT::GetInstance();
1582
1583
                if (!self::IsValidBillingTime($_billingTime))
1584
                {
1585
                        return 0;
1586
                }
1587
1588
                if (!strpos($_billingTime, ':'))
1589
                {
1590
                        return 0;
1591
                }
1592
1593
                $_timeContainer = explode(':', $_billingTime);
1594
                if (count($_timeContainer) != 2)
1595
                {
1596
                        return 0;
1597
                }
1598
1599
                $_timeHours = intval($_timeContainer[0]);
1600
                $_timeMinutes = intval($_timeContainer[1]);
1601
1602
                $_finalSeconds = 0;
1603
                $_finalSeconds += $_timeHours * 3600;
1604
                $_finalSeconds += $_timeMinutes * 60;
1605
1606
                return $_finalSeconds;
1607
        }
1608
1609
        /**
1610
         * Render the Release tab for this Ticket
1611
         *
1612
         * @author Varun Shoor
1613
         * @param int $_ticketID The Ticket ID
1614
         * @param string $_listType (OPTIONAL) The List Type
1615
         * @param int $_departmentID (OPTIONAL) The Department ID
1616
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1617
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1618
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1619
         * @return bool "true" on Success, "false" otherwise
1620
         * @throws SWIFT_Exception If the Class is not Loaded
1621
         */
1622
        public function BillingSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1623
                        $_ticketLimitOffset = 0) {
1624
                $_SWIFT = SWIFT::GetInstance();
1625
1626
                if (!$this->GetIsClassLoaded()) {
1627
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1628
1629
                        return false;
1630
                }
1631
1632
1633
                /*
1634
                 * BUG FIX - Parminder Singh
1635
                 *
1636
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1637
                 *
1638
                 * Comments: If current ticket id is merged with other tickets
1639
                 */
1640
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1641
1642
                // Did the object load up?
1643
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1644
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1645
                }
1646
1647
                // Check permission
1648
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcaninsertbilling') == '0') {
1649
                        echo $this->Language->Get('msgnoperm');
1650
1651
                        return false;
1652
1653
                }
1654
1655
                // Try to load worker staff object
1656
                $_SWIFT_StaffObject_Worker = new SWIFT_Staff(new SWIFT_DataID($_POST['billingworkerstaffid']));
1657
                if (!$_SWIFT_StaffObject_Worker instanceof SWIFT_Staff || !$_SWIFT_StaffObject_Worker->GetIsClassLoaded())
1658
                {
1659
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1660
                }
1661
1662
                $_workDateline = GetDateFieldTimestamp('billworkdate');
1663
                $_billDateline = GetDateFieldTimestamp('billdate');
1664
1665
                if (empty($_POST['billingworkerstaffid']))
1666
                {
1667
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
1668
                } else if (empty($_workDateline) || empty($_billDateline)) {
1669
                        $this->UserInterface->Error($this->Language->Get('titleinvalidbilldate'), $this->Language->Get('msginvalidbilldate'));
1670
                } else {
1671
                        // Create the time worked entry
1672
                        $_SWIFT_TicketTimeTrackObject = SWIFT_TicketTimeTrack::Create($_SWIFT_TicketObject, $_SWIFT->Staff,
1673
                                        self::GetBillingTime($_POST['billingtimeworked']), self::GetBillingTime($_POST['billingtimebillable']),
1674
                                        $_POST['notecolor_billingnotes'], $_POST['billingnotes'], $_SWIFT_StaffObject_Worker, $_workDateline, $_billDateline);
1675
1676
                        // Update Custom Field Values
1677
                        $this->CustomFieldManager->Update(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_INSERT,
1678
                                        array(SWIFT_CustomFieldGroup::GROUP_TIMETRACK), SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_SWIFT_TicketTimeTrackObject->GetTicketTimeTrackID());
1679
                }
1680
1681
                // Begin Hook: staff_ticket_billing
1682
                unset($_hookCode);
1683
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_billing')) ? eval($_hookCode) : false;
1684
                // End Hook
1685
1686
                $_SWIFT_TicketObject->ProcessUpdatePool();
1687
                SWIFT_TicketManager::RebuildCache();
1688
1689
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
1690
                                $_SWIFT->Language->Get('al_ticketbilling'),
1691
                                SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
1692
1693
                /*
1694
                 * BUG FIX - Varun Shoor
1695
                 *
1696
                 * SWIFT-1102 Due time is being set again, if ticket updated with billing time
1697
                 *
1698
                 * Comments: Not required
1699
                 */
1700
//                $_SWIFT_TicketObject->ExecuteSLA();
1701
1702
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
1703
1704
                return true;
1705
        }
1706
1707
        /**
1708
         * Edit a billing entry
1709
         *
1710
         * @author Varun Shoor
1711
         * @param int $_ticketID The Ticket ID
1712
         * @param int $_ticketTimeTrackID The Ticket Time Track ID
1713
         * @return bool "true" on Success, "false" otherwise
1714
         * @throws SWIFT_Exception If the Class is not Loaded
1715
         */
1716
        public function EditBilling($_ticketID, $_ticketTimeTrackID)
1717
        {
1718
                $_SWIFT = SWIFT::GetInstance();
1719
1720
                if (!$this->GetIsClassLoaded())
1721
                {
1722
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1723
1724
                        return false;
1725
                } else if (empty($_ticketID)) {
1726
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1727
1728
                        return false;
1729
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdatebilling') == '0') {
1730
                        return false;
1731
                }
1732
1733
                /*
1734
                 * BUG FIX - Parminder Singh
1735
                 *
1736
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1737
                 *
1738
                 * Comments: If current ticket id is merged with other tickets
1739
                 */
1740
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1741
1742
                // Did the object load up?
1743
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1744
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1745
                }
1746
1747
                // Check permission
1748
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
1749
                        echo $this->Language->Get('msgnoperm');
1750
1751
                        return false;
1752
1753
                }
1754
1755
                $_SWIFT_TicketTimeTrackObject = new SWIFT_TicketTimeTrack(new SWIFT_DataID($_ticketTimeTrackID));
1756
                if (!$_SWIFT_TicketTimeTrackObject instanceof SWIFT_TicketTimeTrack || !$_SWIFT_TicketTimeTrackObject->GetIsClassLoaded())
1757
                {
1758
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1759
1760
                        return false;
1761
                }
1762
1763
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('editbilling'), self::MENU_ID, self::NAVIGATION_ID);
1764
                $this->View->RenderBillingForm(SWIFT_UserInterface::MODE_EDIT, $_SWIFT_TicketObject, $_SWIFT_TicketTimeTrackObject);
1765
                $this->UserInterface->Footer();
1766
1767
                return true;
1768
        }
1769
1770
        /**
1771
         * Edit a billing entry processor
1772
         *
1773
         * @author Varun Shoor
1774
         * @param int $_ticketID The Ticket ID
1775
         * @param int $_ticketTimeTrackID The Ticket Time Track ID
1776
         * @return bool "true" on Success, "false" otherwise
1777
         * @throws SWIFT_Exception If the Class is not Loaded
1778
         */
1779
        public function EditBillingSubmit($_ticketID, $_ticketTimeTrackID)
1780
        {
1781
                $_SWIFT = SWIFT::GetInstance();
1782
1783
                if (!$this->GetIsClassLoaded())
1784
                {
1785
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1786
1787
                        return false;
1788
                } else if (empty($_ticketID)) {
1789
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1790
1791
                        return false;
1792
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdatebilling') == '0') {
1793
                        return false;
1794
                }
1795
1796
                /*
1797
                 * BUG FIX - Parminder Singh
1798
                 *
1799
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1800
                 *
1801
                 * Comments: If current ticket id is merged with other tickets
1802
                 */
1803
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1804
1805
                // Did the object load up?
1806
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1807
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1808
                }
1809
1810
                // Check permission
1811
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
1812
                        echo $this->Language->Get('msgnoperm');
1813
1814
                        return false;
1815
                }
1816
1817
                $_SWIFT_TicketTimeTrackObject = new SWIFT_TicketTimeTrack(new SWIFT_DataID($_ticketTimeTrackID));
1818
                if (!$_SWIFT_TicketTimeTrackObject instanceof SWIFT_TicketTimeTrack || !$_SWIFT_TicketTimeTrackObject->GetIsClassLoaded())
1819
                {
1820
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1821
1822
                        return false;
1823
                }
1824
1825
                // Try to load worker staff object
1826
                $_SWIFT_StaffObject_Worker = new SWIFT_Staff(new SWIFT_DataID($_POST['ebillingworkerstaffid']));
1827
                if (!$_SWIFT_StaffObject_Worker instanceof SWIFT_Staff || !$_SWIFT_StaffObject_Worker->GetIsClassLoaded())
1828
                {
1829
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1830
                }
1831
1832
                $_workDateline = GetDateFieldTimestamp('ebillworkdate');
1833
                $_billDateline = GetDateFieldTimestamp('ebilldate');
1834
1835
                if (trim($_POST['ebillingtimeworked']) == '' || trim($_POST['ebillingtimebillable']) == '' || empty($_POST['ebillingworkerstaffid']))
1836
                {
1837
                        $this->UserInterface->DisplayError($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
1838
                } else if (empty($_workDateline) || empty($_billDateline)) {
1839
                        $this->UserInterface->DisplayError($this->Language->Get('titleinvalidbilldate'), $this->Language->Get('msginvalidbilldate'));
1840
                } else {
1841
                        $_SWIFT_TicketTimeTrackObject->Update(self::GetBillingTime($_POST['ebillingtimeworked']), self::GetBillingTime($_POST['ebillingtimebillable']),
1842
                                        $_POST['notecolor_ebillingnotes'], $_POST['ebillingnotes'], $_SWIFT_StaffObject_Worker, $_workDateline, $_billDateline, $_SWIFT->Staff);
1843
1844
                }
1845
1846
                /*
1847
                 * BUG FIX - Varun Shoor
1848
                 *
1849
                 * SWIFT-722 Modified Billing entry does not get updated on the ticket
1850
                 *
1851
                 * Comments: Rebuild the properties
1852
                 */
1853
                $_SWIFT_TicketObject->RebuildProperties();
1854
1855
                $_SWIFT_TicketObject->ProcessUpdatePool();
1856
                SWIFT_TicketManager::RebuildCache();
1857
1858
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
1859
                                $_SWIFT->Language->Get('al_updticketbilling'),
1860
                                SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
1861
1862
                // Update Custom Field Values
1863
                $this->CustomFieldManager->Update(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_EDIT,
1864
                                array(SWIFT_CustomFieldGroup::GROUP_TIMETRACK), SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_SWIFT_TicketTimeTrackObject->GetTicketTimeTrackID());
1865
1866
                $_SWIFT_TicketObject->RebuildProperties();
1867
1868
                echo $this->View->RenderBillingEntries($_SWIFT_TicketObject);
1869
1870
                return true;
1871
        }
1872
1873
        /**
1874
         * Delete Billing Processer
1875
         *
1876
         * @author Varun Shoor
1877
         * @param int $_ticketID The Ticket ID
1878
         * @param int $_ticketTimeTrackID The Ticket Time Track ID
1879
         * @return bool "true" on Success, "false" otherwise
1880
         * @throws SWIFT_Exception If the Class is not Loaded
1881
         */
1882
        public function DeleteBilling($_ticketID, $_ticketTimeTrackID)
1883
        {
1884
                $_SWIFT = SWIFT::GetInstance();
1885
1886
                if (!$this->GetIsClassLoaded())
1887
                {
1888
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1889
1890
                        return false;
1891
                } else if (empty($_ticketID)) {
1892
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1893
1894
                        return false;
1895
                } else if ($_SWIFT->Staff->GetPermission('staff_tcandeletebilling') == '0') {
1896
                        return false;
1897
                }
1898
1899
                /*
1900
                 * BUG FIX - Parminder Singh
1901
                 *
1902
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1903
                 *
1904
                 * Comments: If current ticket id is merged with other tickets
1905
                 */
1906
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1907
1908
                // Did the object load up?
1909
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1910
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1911
                }
1912
1913
                // Check permission
1914
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
1915
                        echo $this->Language->Get('msgnoperm');
1916
1917
                        return false;
1918
1919
                }
1920
1921
                $_SWIFT_TicketTimeTrackObject = new SWIFT_TicketTimeTrack(new SWIFT_DataID($_ticketTimeTrackID));
1922
                if (!$_SWIFT_TicketTimeTrackObject instanceof SWIFT_TicketTimeTrack || !$_SWIFT_TicketTimeTrackObject->GetIsClassLoaded())
1923
                {
1924
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1925
1926
                        return false;
1927
                }
1928
1929
                $_SWIFT_TicketTimeTrackObject->Delete();
1930
1931
                echo $this->View->RenderBillingEntries($_SWIFT_TicketObject);
1932
1933
                $_SWIFT_TicketObject->RebuildProperties();
1934
1935
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
1936
                        $_SWIFT->Language->Get('al_delbilling'),
1937
                        SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
1938
1939
                return true;
1940
        }
1941
1942
        /**
1943
         * Render the Forward tab for this Ticket
1944
         *
1945
         * @author Varun Shoor
1946
         * @param int $_ticketID The Ticket ID
1947
         * @param string $_listType (OPTIONAL) The List Type
1948
         * @param int $_departmentID (OPTIONAL) The Department ID
1949
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
1950
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
1951
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
1952
         * @return bool "true" on Success, "false" otherwise
1953
         * @throws SWIFT_Exception If the Class is not Loaded
1954
         */
1955
        public function Forward($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
1956
                        $_ticketLimitOffset = 0) {
1957
                if (!$this->GetIsClassLoaded()) {
1958
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1959
1960
                        return false;
1961
                }
1962
1963
                $_SWIFT = SWIFT::GetInstance();
1964
1965
                if (!$this->GetIsClassLoaded()) {
1966
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1967
1968
                        return false;
1969
                }
1970
1971
                /*
1972
                 * BUG FIX - Parminder Singh
1973
                 *
1974
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
1975
                 *
1976
                 * Comments: If current ticket id is merged with other tickets
1977
                 */
1978
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
1979
1980
                // Did the object load up?
1981
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
1982
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1983
                }
1984
1985
                // Check permission
1986
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanforward') == '0') {
1987
                        echo $this->Language->Get('msgnoperm');
1988
1989
                        return false;
1990
1991
                }
1992
1993
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
1994
1995
                SWIFT::Set('ticketurlsuffix', $_listType . '/' . $_departmentID . '/' . $_ticketStatusID . '/' . $_ticketTypeID . '/' . $_ticketLimitOffset);
1996
1997
                $this->View->RenderForward($_SWIFT_TicketObject, $_SWIFT_UserObject, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID,
1998
                        $_ticketLimitOffset);
1999
2000
                return true;
2001
        }
2002
2003
        /**
2004
         * Render the FollowUp tab for this Ticket
2005
         *
2006
         * @author Varun Shoor
2007
         * @param int $_ticketID The Ticket ID
2008
         * @param string $_listType (OPTIONAL) The List Type
2009
         * @param int $_departmentID (OPTIONAL) The Department ID
2010
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2011
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2012
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2013
         * @param int $_prefix (OPTIONAL) Whether its an inline display
2014
         * @return bool "true" on Success, "false" otherwise
2015
         * @throws SWIFT_Exception If the Class is not Loaded
2016
         */
2017
        public function FollowUp($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2018
                        $_ticketLimitOffset = 0, $_prefix = '') {
2019
                if (!$this->GetIsClassLoaded()) {
2020
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2021
2022
                        return false;
2023
                }
2024
2025
                $_SWIFT = SWIFT::GetInstance();
2026
2027
                if (!$this->GetIsClassLoaded()) {
2028
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2029
2030
                        return false;
2031
                }
2032
2033
                /*
2034
                 * BUG FIX - Parminder Singh
2035
                 *
2036
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2037
                 *
2038
                 * Comments: If current ticket id is merged with other tickets
2039
                 */
2040
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2041
2042
                // Did the object load up?
2043
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2044
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2045
                }
2046
2047
                // Check permission
2048
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanfollowup') == '0') {
2049
                        echo $this->Language->Get('msgnoperm');
2050
2051
                        return false;
2052
2053
                }
2054
2055
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
2056
2057
                $_finalPrefix = 'fu';
2058
                $_isInline = false;
2059
                if (!empty($_prefix) && strlen($_prefix) == '2')
2060
                {
2061
                        $_finalPrefix = $_prefix;
2062
                        $_isInline = true;
2063
                }
2064
2065
                $this->View->RenderFollowUp($_SWIFT_TicketObject, $_SWIFT_UserObject, $_finalPrefix, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID,
2066
                        $_ticketLimitOffset, $_isInline);
2067
2068
                return true;
2069
        }
2070
2071
        /**
2072
         * Follow-Up Submission Processor
2073
         *
2074
         * @author Varun Shoor
2075
         * @param int $_ticketID The Ticket ID
2076
         * @param string $_listType (OPTIONAL) The List Type
2077
         * @param int $_departmentID (OPTIONAL) The Department ID
2078
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2079
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2080
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2081
         * @return bool "true" on Success, "false" otherwise
2082
         * @throws SWIFT_Exception If the Class is not Loaded
2083
         */
2084
        public function FollowUpSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2085
                        $_ticketLimitOffset = 0) {
2086
                if (!$this->GetIsClassLoaded()) {
2087
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2088
2089
                        return false;
2090
                }
2091
2092
                $_SWIFT = SWIFT::GetInstance();
2093
2094
                if (!$this->GetIsClassLoaded()) {
2095
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2096
2097
                        return false;
2098
                }
2099
2100
                /*
2101
                 * BUG FIX - Parminder Singh
2102
                 *
2103
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2104
                 *
2105
                 * Comments: If current ticket id is merged with other tickets
2106
                 */
2107
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2108
2109
                // Did the object load up?
2110
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2111
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2112
                }
2113
2114
                // Check permission
2115
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanfollowup') == '0') {
2116
                        echo $this->Language->Get('msgnoperm');
2117
2118
                        return false;
2119
2120
                }
2121
                /*
2122
                 * BUG FIX - Nidhi Gupta
2123
                 *
2124
                 * SWIFT-839: Permission to restrict staff from moving tickets to departments they're not assigned to
2125
                 *
2126
                 * Comments: Added check for staff to move tickets in unassigned departments
2127
                 */
2128
                if ($_SWIFT->Staff->GetPermission('staff_tcanchangeunassigneddepartment') == '0') {
2129
                        if ($_SWIFT_TicketObject->Get('departmentid') != $_POST['fudepartmentid'] && !in_array($_POST['fudepartmentid'], $_SWIFT->Staff->GetAssignedDepartments())) {
2130
                                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
2131
                                        self::NAVIGATION_ID);
2132
                                $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
2133
                                $this->UserInterface->Footer();
2134
2135
                                return false;
2136
                        }
2137
                }
2138
2139
                $this->_ProcessFollowUp($_SWIFT_TicketObject, 'fu');
2140
2141
                // Begin Hook: staff_ticket_followup
2142
                unset($_hookCode);
2143
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_followup')) ? eval($_hookCode) : false;
2144
                // End Hook
2145
2146
                SWIFT_TicketManager::RebuildCache();
2147
2148
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
2149
                        $_SWIFT->Language->Get('al_createfollowup'),
2150
                        SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
2151
2152
                // Activity Log
2153
                SWIFT_StaffActivityLog::AddToLog($_SWIFT->Language->Get('al_createfollowup'),
2154
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
2155
2156
                /**
2157
                 * BUG FIX - Ravi Sharma
2158
                 *
2159
                 * SWIFT-3151: Due time gets reset when follow up is added on ticket.
2160
                 *
2161
                 * Comments: None.
2162
                 */
2163
                if (isset($_POST['fudochangeproperties']))
2164
                {
2165
                        $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
2166
                }
2167
2168
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2169
2170
                return true;
2171
        }
2172
2173
        /**
2174
         * Delete Follow-Up Processer
2175
         *
2176
         * @author Varun Shoor
2177
         * @param int $_ticketID The Ticket ID
2178
         * @param int $_ticketFollowUpID The Ticket FollowUp ID
2179
         * @return bool "true" on Success, "false" otherwise
2180
         * @throws SWIFT_Exception If the Class is not Loaded
2181
         */
2182
        public function DeleteFollowUp($_ticketID, $_ticketFollowUpID)
2183
        {
2184
                $_SWIFT = SWIFT::GetInstance();
2185
2186
                if (!$this->GetIsClassLoaded())
2187
                {
2188
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2189
2190
                        return false;
2191
                } else if (empty($_ticketID)) {
2192
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2193
2194
                        return false;
2195
                } else if ($_SWIFT->Staff->GetPermission('staff_tcandeletefollowup') == '0') {
2196
                        return false;
2197
                }
2198
2199
                /*
2200
                 * BUG FIX - Parminder Singh
2201
                 *
2202
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2203
                 *
2204
                 * Comments: If current ticket id is merged with other tickets
2205
                 */
2206
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2207
2208
                // Did the object load up?
2209
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2210
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2211
                }
2212
2213
                // Check permission
2214
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
2215
                        echo $this->Language->Get('msgnoperm');
2216
2217
                        return false;
2218
2219
                }
2220
2221
                $_SWIFT_TicketFollowUpObject = new SWIFT_TicketFollowUp(new SWIFT_DataID($_ticketFollowUpID));
2222
                if (!$_SWIFT_TicketFollowUpObject instanceof SWIFT_TicketFollowUp || !$_SWIFT_TicketFollowUpObject->GetIsClassLoaded())
2223
                {
2224
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2225
2226
                        return false;
2227
                }
2228
2229
                $_SWIFT_TicketFollowUpObject->Delete();
2230
2231
                $_SWIFT_TicketObject->RebuildProperties();
2232
2233
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
2234
                        $_SWIFT->Language->Get('al_delfollowup'),
2235
                        SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
2236
2237
                $this->Load->Method('View', $_ticketID);
2238
2239
                return true;
2240
        }
2241
2242
        /**
2243
         * Render the Release tab for this Ticket
2244
         *
2245
         * @author Varun Shoor
2246
         * @param int $_ticketID The Ticket ID
2247
         * @param string $_listType (OPTIONAL) The List Type
2248
         * @param int $_departmentID (OPTIONAL) The Department ID
2249
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2250
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2251
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2252
         * @return bool "true" on Success, "false" otherwise
2253
         * @throws SWIFT_Exception If the Class is not Loaded
2254
         */
2255
        public function Release($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2256
                        $_ticketLimitOffset = 0) {
2257
                if (!$this->GetIsClassLoaded()) {
2258
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2259
2260
                        return false;
2261
                }
2262
2263
                $_SWIFT = SWIFT::GetInstance();
2264
2265
                if (!$this->GetIsClassLoaded()) {
2266
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2267
2268
                        return false;
2269
                }
2270
2271
                /*
2272
                 * BUG FIX - Parminder Singh
2273
                 *
2274
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2275
                 *
2276
                 * Comments: If current ticket id is merged with other tickets
2277
                 */
2278
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2279
2280
                // Did the object load up?
2281
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2282
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2283
                }
2284
2285
                // Check permission
2286
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanrelease') == '0') {
2287
                        echo $this->Language->Get('msgnoperm');
2288
2289
                        return false;
2290
2291
                }
2292
2293
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
2294
2295
                $this->View->RenderRelease($_SWIFT_TicketObject, $_SWIFT_UserObject, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID,
2296
                        $_ticketLimitOffset);
2297
2298
                return true;
2299
        }
2300
2301
        /**
2302
         * Render the Release tab for this Ticket
2303
         *
2304
         * @author Varun Shoor
2305
         * @param int $_ticketID The Ticket ID
2306
         * @param string $_listType (OPTIONAL) The List Type
2307
         * @param int $_departmentID (OPTIONAL) The Department ID
2308
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2309
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2310
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2311
         * @return bool "true" on Success, "false" otherwise
2312
         * @throws SWIFT_Exception If the Class is not Loaded
2313
         */
2314
        public function ReleaseSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2315
                        $_ticketLimitOffset = 0) {
2316
                if (!$this->GetIsClassLoaded()) {
2317
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2318
2319
                        return false;
2320
                }
2321
2322
                $_SWIFT = SWIFT::GetInstance();
2323
2324
                if (!$this->GetIsClassLoaded()) {
2325
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2326
2327
                        return false;
2328
                }
2329
2330
                /*
2331
                 * BUG FIX - Parminder Singh
2332
                 *
2333
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2334
                 *
2335
                 * Comments: If current ticket id is merged with other tickets
2336
                 */
2337
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2338
2339
                // Did the object load up?
2340
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2341
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2342
                }
2343
2344
                // Check permission
2345
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanrelease') == '0') {
2346
                        echo $this->Language->Get('msgnoperm');
2347
2348
                        return false;
2349
2350
                }
2351
2352
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
2353
                /*
2354
                 * BUG FIX - Nidhi Gupta
2355
                 *
2356
                 * SWIFT-839: Permission to restrict staff from moving tickets to departments they're not assigned to
2357
                 *
2358
                 * Comments: Added check for staff to move tickets in unassigned departments
2359
                 */
2360
                if ($_SWIFT->Staff->GetPermission('staff_tcanchangeunassigneddepartment') == '0') {
2361
                        if ($_SWIFT_TicketObject->Get('departmentid') != $_POST['reldepartmentid'] && !in_array($_POST['reldepartmentid'], $_SWIFT->Staff->GetAssignedDepartments())) {
2362
                                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
2363
                                        self::NAVIGATION_ID);
2364
                                $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
2365
                                $this->UserInterface->Footer();
2366
2367
                                return false;
2368
                        }
2369
                }
2370
2371
2372
                // Process Tags
2373
                if ($_SWIFT->Staff->GetPermission('staff_canupdatetags') != '0')
2374
                {
2375
                        SWIFT_Tag::Process(SWIFT_TagLink::TYPE_TICKET, $_SWIFT_TicketObject->GetTicketID(),
2376
                                        SWIFT_UserInterface::GetMultipleInputValues('reltags'), $_SWIFT->Staff->GetStaffID());
2377
                }
2378
2379
                // Update Properties
2380
                if (isset($_POST['reldepartmentid']) && !empty($_POST['reldepartmentid'])) {
2381
                        $_SWIFT_TicketObject->SetDepartment($_POST['reldepartmentid']);
2382
                }
2383
2384
                if (isset($_POST['relownerstaffid'])) {
2385
                        $_SWIFT_TicketObject->SetOwner($_POST['relownerstaffid']);
2386
                }
2387
2388
                if (isset($_POST['reltickettypeid']) && !empty($_POST['reltickettypeid'])) {
2389
                        $_SWIFT_TicketObject->SetType($_POST['reltickettypeid']);
2390
                }
2391
2392
                if (isset($_POST['relticketstatusid']) && !empty($_POST['relticketstatusid'])) {
2393
                        $_SWIFT_TicketObject->SetStatus($_POST['relticketstatusid']);
2394
                }
2395
2396
                if (isset($_POST['relticketpriorityid']) && !empty($_POST['relticketpriorityid'])) {
2397
                        $_SWIFT_TicketObject->SetPriority($_POST['relticketpriorityid']);
2398
                }
2399
2400
                if (isset($_POST['releaseticketnotes']) && trim($_POST['releaseticketnotes']) != '') {
2401
                        /*
2402
                         * BUG FIX - Varun Shoor
2403
                         *
2404
                         * SWIFT-738 New ticket notification does not work if the note is added from the Release tab
2405
                         *
2406
                         * Comments: Trigger notification event
2407
                         */
2408
2409
                        $_SWIFT_TicketObject->NotificationManager->SetEvent('newticketnotes');
2410
2411
                        $_staffName = $_SWIFT->Staff->GetProperty('fullname');
2412
                        $_staffEmail = $_SWIFT->Staff->GetProperty('email');
2413
2414
                        $_SWIFT_TicketObject->SetWatcherProperties($_staffName, sprintf($_SWIFT->Language->Get('watcherprefix'), $_staffName, $_staffEmail) . SWIFT_CRLF . $_POST['releaseticketnotes']);
2415
2416
                        $_SWIFT_TicketObject->CreateNote($_SWIFT_UserObject, $_POST['releaseticketnotes'], $_POST['notecolor_releaseticketnotes'], $_POST['releasenotetype']);
2417
                }
2418
2419
                $_dueDateline = GetDateFieldTimestamp('releasedue');
2420
                $_resolutionDueDateline = GetDateFieldTimestamp('releaseresolutiondue');
2421
2422
                // Due Dateline
2423
                if (!empty($_dueDateline) && gmdate('d M Y h:i A', $_dueDateline) != gmdate('d M Y h:i A', $_SWIFT_TicketObject->GetProperty('duetime'))) {
2424
                        $_SWIFT_TicketObject->SetDue($_dueDateline);
2425
2426
                // We need to clear it?
2427
                } else if (empty($_dueDateline) && $_SWIFT_TicketObject->GetProperty('duetime') != '0') {
2428
                        $_SWIFT_TicketObject->ClearOverdue();
2429
                }
2430
2431
                // Resolution Due Dateline
2432
                if (!empty($_resolutionDueDateline) && gmdate('d M Y h:i A', $_resolutionDueDateline) != gmdate('d M Y h:i A', $_SWIFT_TicketObject->GetProperty('resolutionduedateline'))) {
2433
                        $_SWIFT_TicketObject->SetResolutionDue($_resolutionDueDateline);
2434
2435
                // We need to clear it?
2436
                } else if (empty($_resolutionDueDateline) && $_SWIFT_TicketObject->GetProperty('resolutionduedateline') != '0') {
2437
                        $_SWIFT_TicketObject->ClearResolutionDue();
2438
                }
2439
2440
                // Time tracking stuff
2441
                if (!empty($_POST['relbillingtimeworked']) || !empty($_POST['relbillingtimebillable']))
2442
                {
2443
                        // Create the time worked entry
2444
                        $_SWIFT_TicketTimeTrackObject = SWIFT_TicketTimeTrack::Create($_SWIFT_TicketObject, $_SWIFT->Staff,
2445
                                        self::GetBillingTime($_POST['relbillingtimeworked']), self::GetBillingTime($_POST['relbillingtimebillable']),
2446
                                        1, '', $_SWIFT->Staff, DATENOW, DATENOW);
2447
                }
2448
2449
                // Begin Hook: staff_ticket_release
2450
                unset($_hookCode);
2451
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_release')) ? eval($_hookCode) : false;
2452
                // End Hook
2453
2454
                $_SWIFT_TicketObject->ProcessUpdatePool();
2455
                $_SWIFT_TicketObject->RebuildProperties();
2456
                SWIFT_TicketManager::RebuildCache();
2457
2458
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
2459
2460
                $_nextTicketID = false;
2461
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
2462
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
2463
                }
2464
2465
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
2466
2467
                // Does the new department belong to this staff? if not, we need to jump him back to list!
2468
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
2469
                if (isset($_POST['resdepartmentid']) && !empty($_POST['resdepartmentid']) && !in_array($_POST['resdepartmentid'], $_assignedDepartmentIDList)) {
2470
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
2471
                } else {
2472
                        if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
2473
                        {
2474
                                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2475
                        } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
2476
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
2477
2478
                        } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
2479
                                $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
2480
2481
                        } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
2482
                                if (!empty($_nextTicketID))
2483
                                {
2484
                                        $this->Load->Method('View', $_nextTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2485
                                } else {
2486
                                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
2487
                                }
2488
                        }
2489
                }
2490
2491
                return true;
2492
        }
2493
2494
        /**
2495
         * Render the Edit tab for this Ticket
2496
         *
2497
         * @author Varun Shoor
2498
         * @param int $_ticketID The Ticket ID
2499
         * @param string $_listType (OPTIONAL) The List Type
2500
         * @param int $_departmentID (OPTIONAL) The Department ID
2501
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2502
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2503
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2504
         * @return bool "true" on Success, "false" otherwise
2505
         * @throws SWIFT_Exception If the Class is not Loaded
2506
         */
2507
        public function Edit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2508
                        $_ticketLimitOffset = 0) {
2509
                if (!$this->GetIsClassLoaded()) {
2510
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2511
2512
                        return false;
2513
                }
2514
2515
                $_SWIFT = SWIFT::GetInstance();
2516
2517
                if (!$this->GetIsClassLoaded()) {
2518
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2519
2520
                        return false;
2521
                }
2522
2523
                /*
2524
                 * BUG FIX - Parminder Singh
2525
                 *
2526
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2527
                 *
2528
                 * Comments: If current ticket id is merged with other tickets
2529
                 */
2530
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2531
2532
                // Did the object load up?
2533
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2534
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2535
                }
2536
2537
                // Check permission
2538
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
2539
                        echo $this->Language->Get('msgnoperm');
2540
2541
                        return false;
2542
2543
                }
2544
2545
                $this->View->RenderEdit($_SWIFT_TicketObject, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2546
2547
                return true;
2548
        }
2549
2550
        /**
2551
         * Edit Tab Submission
2552
         *
2553
         * @author Varun Shoor
2554
         * @param int $_ticketID The Ticket ID
2555
         * @param string $_listType (OPTIONAL) The List Type
2556
         * @param int $_departmentID (OPTIONAL) The Department ID
2557
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
2558
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
2559
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
2560
         * @return bool "true" on Success, "false" otherwise
2561
         * @throws SWIFT_Exception If the Class is not Loaded
2562
         */
2563
        public function EditSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
2564
                        $_ticketLimitOffset = 0) {
2565
                if (!$this->GetIsClassLoaded()) {
2566
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2567
2568
                        return false;
2569
                }
2570
2571
                $_SWIFT = SWIFT::GetInstance();
2572
2573
                if (!$this->GetIsClassLoaded()) {
2574
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2575
2576
                        return false;
2577
                }
2578
2579
                /*
2580
                 * BUG FIX - Parminder Singh
2581
                 *
2582
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2583
                 *
2584
                 * Comments: If current ticket id is merged with other tickets
2585
                 */
2586
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2587
2588
                // Did the object load up?
2589
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2590
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2591
                }
2592
2593
                // Check permission
2594
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
2595
                        echo $this->Language->Get('msgnoperm');
2596
2597
                        return false;
2598
2599
                }
2600
2601
                /**
2602
                * BUG FIX: Parminder Singh
2603
                *
2604
                * SWIFT-1745: Regular expression during editing custom field
2605
                *
2606
                * Comments: Added Custom Field Check
2607
                */
2608
2609
                $_customFieldCheckResult = $this->CustomFieldManager->Check(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_EDIT,
2610
                                array(SWIFT_CustomFieldGroup::GROUP_STAFFTICKET, SWIFT_CustomFieldGroup::GROUP_USERTICKET, SWIFT_CustomFieldGroup::GROUP_STAFFUSERTICKET), SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_SWIFT_TicketObject->GetProperty('departmentid'));
2611
                if ($_customFieldCheckResult[0] == false)
2612
                {
2613
                        SWIFT::Alert($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
2614
2615
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2616
2617
                        return false;
2618
                }
2619
2620
                /*
2621
                 * BUG FIX - Varun Shoor
2622
                 *
2623
                 * SWIFT-590 Changes made to the user details in Staff CP are not effective (even though the Staff CP shows the updated information)
2624
                 * SWIFT-953 User Organization does not get updated while changing the user details in ticket
2625
                 *
2626
                 * Comments: Changing the original fix because it did not have a provision for creating users in case one didnt exist.
2627
                 */
2628
                $_userGroupID = SWIFT_UserGroup::RetrieveDefaultUserGroupID(SWIFT_UserGroup::TYPE_REGISTERED);
2629
2630
                /*
2631
                 * BUG FIX - Varun Shoor
2632
                 *
2633
                 * SWIFT-1434 Editing and adding a space in the ticket recipient field of a ticket, help desk fails to read the address and shows a blank page while reply
2634
                 *
2635
                 * Comments: None
2636
                 */
2637
                $_editEmail = trim($_POST['editemail']);
2638
                if (!IsEmailValid($_editEmail)) {
2639
                        $_editEmail = $_SWIFT_TicketObject->GetProperty('email');
2640
                }
2641
2642
                // Update Properties
2643
                $_SWIFT_TicketObject->Update($_POST['editsubject'], $_POST['editfullname'], $_editEmail);
2644
2645
                /*
2646
                 * BUG FIX - Simaranjit Singh
2647
                 *
2648
                 * SWIFT-2759: Error when editing tickets and further bug with creating user accounts
2649
                 *
2650
                 * Comments: None
2651
                 */
2652
                $_userID = SWIFT_Ticket::GetOrCreateUserID($_editEmail, $_editEmail, $_userGroupID);
2653
2654
                /*
2655
                 * BUG FIX - Varun Shoor
2656
                 *
2657
                 * SWIFT-1864 After editing the full name of a ticket from the Edit tab, it still shows the old full name of user on ticket.
2658
                 *
2659
                 */
2660
                SWIFT_TicketPost::UpdateFullnameAndEmailOnTicketUser($_SWIFT_TicketObject->GetTicketID(), $_SWIFT_TicketObject->GetProperty('userid'), $_userID, $_POST['editfullname'], $_editEmail);
2661
2662
                if (!empty($_userID) && $_userID != $_SWIFT_TicketObject->GetProperty('userid')) {
2663
                        $_SWIFT_TicketObject->UpdateUser($_userID);
2664
                }
2665
2666
                // Update the Ticket SLA Plan
2667
                if ($_POST['editticketslaplanid'] != $_SWIFT_TicketObject->GetProperty('ticketslaplanid') && $_POST['editticketslaplanid'] != '0') {
2668
                        try {
2669
                                $_SWIFT_SLAPlanObject = new SWIFT_SLA(new SWIFT_DataID($_POST['editticketslaplanid']));
2670
2671
                                $_SWIFT_TicketObject->SetSLA($_SWIFT_SLAPlanObject);
2672
                        } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
2673
2674
                                return false;
2675
                        }
2676
                } else if ($_POST['editticketslaplanid'] == '0' && $_SWIFT_TicketObject->GetProperty('ticketslaplanid') != '0') {
2677
                        $_SWIFT_TicketObject->ClearSLA();
2678
                }
2679
2680
                // Update Recipients
2681
                SWIFT_TicketRecipient::DeleteOnTicket(array($_SWIFT_TicketObject->GetTicketID()));
2682
2683
                $_thirdPartyEmailContainer = self::GetSanitizedEmailList('editthirdparty');
2684
                $_ccEmailContainer = self::GetSanitizedEmailList('editcc');
2685
                $_bccEmailContainer = self::GetSanitizedEmailList('editbcc');
2686
2687
                if (_is_array($_thirdPartyEmailContainer)) {
2688
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_THIRDPARTY, $_thirdPartyEmailContainer);
2689
                }
2690
2691
                if (_is_array($_ccEmailContainer)) {
2692
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_CC, $_ccEmailContainer);
2693
                }
2694
2695
                if (_is_array($_bccEmailContainer)) {
2696
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_BCC, $_bccEmailContainer);
2697
                }
2698
2699
                // Update Custom Field Values
2700
                $this->CustomFieldManager->Update(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_EDIT,
2701
                                array(SWIFT_CustomFieldGroup::GROUP_STAFFTICKET, SWIFT_CustomFieldGroup::GROUP_USERTICKET, SWIFT_CustomFieldGroup::GROUP_STAFFUSERTICKET),
2702
                                SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_SWIFT_TicketObject->GetTicketID(), $_SWIFT_TicketObject->GetProperty('departmentid'));
2703
2704
                $_SWIFT_TicketObject->ProcessUpdatePool();
2705
2706
                /*
2707
                 * BUG FIX - Ravi Sharma
2708
                 *
2709
                 * SWIFT-3212 Due time resets on updating the ticket from edit tab
2710
                 *
2711
                 * Comments: None
2712
                 */
2713
                if ($_SWIFT_TicketObject->GetProperty('isresolved') != '1')
2714
                {
2715
                        /*
2716
                         * Bug Fix - Mansi Wason
2717
                         *
2718
                         * SWIFT- 3835 "Incorrect SLA plan gets linked with the ticket when ticket is moved from a resolved status to unresolved status."
2719
                         *
2720
                         * comment - By clicking on 'Edit' tab and without making any changes if we 'Update' the ticket. This will lead to reset of the 'Reply Due' time which should not be the case.
2721
                         */
2722
2723
                        $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
2724
                }
2725
2726
                // Do we have to merge it?
2727
                if (!empty($_POST['mergeticketid'])) {
2728
                        $_SWIFT_TicketObject_Merge = false;
2729
                        $_POST['mergeticketid'] = Clean($_POST['mergeticketid']);
2730
                        if (is_numeric($_POST['mergeticketid'])) {
2731
                                $_SWIFT_TicketObject_Merge = new SWIFT_Ticket(new SWIFT_DataID($_POST['mergeticketid']));
2732
                        } else {
2733
                                $_ticketID_Merge = SWIFT_Ticket::GetTicketIDFromMask($_POST['mergeticketid']);
2734
                                if (!empty($_ticketID_Merge)) {
2735
                                        $_SWIFT_TicketObject_Merge = new SWIFT_Ticket(new SWIFT_DataID($_ticketID_Merge));
2736
                                }
2737
                        }
2738
2739
                        if ($_SWIFT_TicketObject_Merge instanceof SWIFT_Ticket && $_SWIFT_TicketObject_Merge->GetIsClassLoaded()) {
2740
                                SWIFT_Ticket::Merge(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT_TicketObject_Merge->GetTicketID(), $_SWIFT->Staff->GetStaffID());
2741
                                SWIFT::Info($this->Language->Get('titleeditmergesuccess'), $this->Language->Get('msgeditmergesuccess'));
2742
2743
                                $_ticketID = $_SWIFT_TicketObject_Merge->GetTicketID();
2744
                                $_departmentID = $_SWIFT_TicketObject_Merge->GetProperty('departmentid');
2745
                                $_ticketStatusID = $_SWIFT_TicketObject_Merge->GetProperty('ticketstatusid');
2746
                                $_ticketTypeID = $_SWIFT_TicketObject_Merge->GetProperty('tickettypeid');
2747
                                $_ticketLimitOffset = -1;
2748
                        } else {
2749
                                SWIFT::Alert($this->Language->Get('titleeditmergefailed'), $this->Language->Get('msgeditmergefailed'));
2750
                        }
2751
                }
2752
2753
                // Begin Hook: staff_ticket_edit
2754
                unset($_hookCode);
2755
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_edit')) ? eval($_hookCode) : false;
2756
                // End Hook
2757
2758
                SWIFT_TicketManager::RebuildCache();
2759
2760
                /*
2761
                 * BUG FIX - Parminder Singh
2762
                 *
2763
                 * SWIFT-2392: While adding more than one CC email address in a ticket, CC users list do not get updated in ticket
2764
                 *
2765
                 * Comments: $_POST, $_REQUEST and $_GET contains old values so making them empty
2766
                 */
2767
                $GLOBALS['_POST'] = $GLOBALS['_REQUEST'] = $GLOBALS['_GET'] = array();
2768
                $GLOBALS['_POST']['isajax'] = true;
2769
2770
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
2771
2772
                return true;
2773
        }
2774
2775
        /**
2776
         * Retrieve the Sanitized Email List
2777
         *
2778
         * @author Varun Shoor
2779
         *
2780
         * @param string $_fieldName The Field Name
2781
         * @param bool   $_isCheckbox
2782
         *
2783
         * @return array
2784
         */
2785
        static protected function GetSanitizedEmailList($_fieldName, $_isCheckbox = false) {
2786
                $_SWIFT = SWIFT::GetInstance();
2787
2788
                $_emailContainer = array();
2789
2790
                $_postEmailValues = SWIFT_UserInterface::GetMultipleInputValues($_fieldName, $_isCheckbox);
2791
                if (_is_array($_postEmailValues))
2792
                {
2793
                        foreach ($_postEmailValues as $_key => $_val)
2794
                        {
2795
                                if (IsEmailValid($_val))
2796
                                {
2797
                                        $_emailContainer[] = $_val;
2798
                                }
2799
                        }
2800
                }
2801
                return $_emailContainer;
2802
        }
2803
2804
        /**
2805
         * Render the Audit Log for this Ticket
2806
         *
2807
         * @author Varun Shoor
2808
         * @param int $_ticketID The Ticket ID
2809
         * @return bool "true" on Success, "false" otherwise
2810
         * @throws SWIFT_Exception If the Class is not Loaded
2811
         */
2812
        public function AuditLog($_ticketID) {
2813
                if (!$this->GetIsClassLoaded()) {
2814
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2815
2816
                        return false;
2817
                }
2818
2819
                $_SWIFT = SWIFT::GetInstance();
2820
2821
                if (!$this->GetIsClassLoaded()) {
2822
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2823
2824
                        return false;
2825
                }
2826
2827
                /*
2828
                 * BUG FIX - Parminder Singh
2829
                 *
2830
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2831
                 *
2832
                 * Comments: If current ticket id is merged with other tickets
2833
                 */
2834
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2835
2836
                // Did the object load up?
2837
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2838
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2839
                }
2840
2841
                // Check permission
2842
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewauditlog') == '0') {
2843
                        echo $this->Language->Get('msgnoperm');
2844
2845
                        return false;
2846
2847
                }
2848
2849
                $this->View->RenderAuditLog($_SWIFT_TicketObject);
2850
2851
                return true;
2852
        }
2853
2854
        /**
2855
         * Render the History for this Ticket
2856
         *
2857
         * @author Varun Shoor
2858
         * @param int $_ticketID The Ticket ID
2859
         * @return bool "true" on Success, "false" otherwise
2860
         * @throws SWIFT_Exception If the Class is not Loaded
2861
         */
2862
        public function History($_ticketID) {
2863
                if (!$this->GetIsClassLoaded()) {
2864
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2865
2866
                        return false;
2867
                }
2868
2869
                $_SWIFT = SWIFT::GetInstance();
2870
2871
                if (!$this->GetIsClassLoaded()) {
2872
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2873
2874
                        return false;
2875
                }
2876
2877
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2878
2879
                // Did the object load up?
2880
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2881
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2882
                }
2883
2884
                // Check permission
2885
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0') {
2886
                        echo $this->Language->Get('msgnoperm');
2887
2888
                        return false;
2889
2890
                }
2891
2892
                $this->View->RenderHistory($_SWIFT_TicketObject);
2893
2894
                return true;
2895
        }
2896
2897
        /**
2898
         * Render the History for this Ticket
2899
         *
2900
         * @author Varun Shoor
2901
         * @param int $_ticketID The Ticket ID
2902
         * @return bool "true" on Success, "false" otherwise
2903
         * @throws SWIFT_Exception If the Class is not Loaded
2904
         */
2905
        public function HistoryUser($_userID) {
2906
                $_SWIFT = SWIFT::GetInstance();
2907
2908
                if (!$this->GetIsClassLoaded()) {
2909
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2910
2911
                        return false;
2912
                }
2913
2914
                $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_userID));
2915
2916
                // Did the object load up?
2917
                if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded()) {
2918
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2919
                }
2920
2921
                $this->View->RenderHistory($_SWIFT_UserObject);
2922
2923
                return true;
2924
        }
2925
2926
        /**
2927
         * Render the History for this Ticket based on a list of emails
2928
         *
2929
         * @author Varun Shoor
2930
         * @param string $_baseData The Base64 Encoded Data
2931
         * @return bool "true" on Success, "false" otherwise
2932
         * @throws SWIFT_Exception If the Class is not Loaded
2933
         */
2934
        public function HistoryEmails($_baseData) {
2935
                $_SWIFT = SWIFT::GetInstance();
2936
2937
                if (!$this->GetIsClassLoaded()) {
2938
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2939
2940
                        return false;
2941
                }
2942
2943
                $_finalEmailList = array();
2944
2945
                parse_str(base64_decode($_baseData), $_dataContainer);
2946
2947
                if (isset($_dataContainer['email']) && _is_array($_dataContainer['email']))
2948
                {
2949
                        foreach ($_dataContainer['email'] as $_email)
2950
                        {
2951
                                if (IsEmailValid($_email) && !in_array($_email, $_finalEmailList))
2952
                                {
2953
                                        $_finalEmailList[] = $_email;
2954
                                }
2955
                        }
2956
                }
2957
2958
                $this->View->RenderHistory($_finalEmailList);
2959
2960
                return true;
2961
        }
2962
2963
        /**
2964
         * Render the Add Note form for this Ticket
2965
         *
2966
         * @author Varun Shoor
2967
         * @param int $_ticketID The Ticket ID
2968
         * @return bool "true" on Success, "false" otherwise
2969
         * @throws SWIFT_Exception If the Class is not Loaded
2970
         */
2971
        public function AddNote($_ticketID) {
2972
                if (!$this->GetIsClassLoaded()) {
2973
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2974
2975
                        return false;
2976
                }
2977
2978
                $_SWIFT = SWIFT::GetInstance();
2979
2980
                if (!$this->GetIsClassLoaded()) {
2981
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
2982
2983
                        return false;
2984
                }
2985
2986
                /*
2987
                 * BUG FIX - Parminder Singh
2988
                 *
2989
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
2990
                 *
2991
                 * Comments: If current ticket id is merged with other tickets
2992
                 */
2993
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
2994
2995
                // Did the object load up?
2996
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
2997
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
2998
                }
2999
3000
                // Check permission
3001
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcaninsertticketnote') == '0') {
3002
                        echo $this->Language->Get('msgnoperm');
3003
3004
                        return false;
3005
                }
3006
3007
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
3008
3009
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('addnote'), self::MENU_ID, self::NAVIGATION_ID);
3010
                $this->View->RenderNoteForm(SWIFT_UserInterface::MODE_INSERT, $_SWIFT_TicketObject, null, $_SWIFT_UserObject);
3011
                $this->UserInterface->Footer();
3012
3013
                return true;
3014
        }
3015
3016
        /**
3017
         * Render the Add Note form for this Ticket
3018
         *
3019
         * @author Varun Shoor
3020
         * @param int $_ticketID The Ticket ID
3021
         * @return bool "true" on Success, "false" otherwise
3022
         * @throws SWIFT_Exception If the Class is not Loaded
3023
         */
3024
        public function AddNoteSubmit($_ticketID) {
3025
                if (!$this->GetIsClassLoaded()) {
3026
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3027
3028
                        return false;
3029
                }
3030
3031
                $_SWIFT = SWIFT::GetInstance();
3032
3033
                if (!$this->GetIsClassLoaded()) {
3034
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3035
3036
                        return false;
3037
                }
3038
3039
                /*
3040
                 * BUG FIX - Parminder Singh
3041
                 *
3042
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3043
                 *
3044
                 * Comments: If current ticket id is merged with other tickets
3045
                 */
3046
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3047
3048
                // Did the object load up?
3049
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3050
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3051
                }
3052
3053
                // Check permission
3054
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcaninsertticketnote') == '0') {
3055
                        echo $this->Language->Get('msgnoperm');
3056
3057
                        return false;
3058
                }
3059
3060
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
3061
3062
                // Notification Event
3063
                $_SWIFT_TicketObject->NotificationManager->SetEvent('newticketnotes');
3064
3065
                $_staffName = $_SWIFT->Staff->GetProperty('fullname');
3066
                $_staffEmail = $_SWIFT->Staff->GetProperty('email');
3067
3068
                $_SWIFT_TicketObject->SetWatcherProperties($_staffName, sprintf($_SWIFT->Language->Get('watcherprefix'), $_staffName, $_staffEmail) . SWIFT_CRLF . $_POST['ticketnotes']);
3069
3070
                $_forStaffID = false;
3071
                if (isset($_POST['forstaffid'])) {
3072
                        $_forStaffID = intval($_POST['forstaffid']);
3073
                }
3074
3075
                if (isset($_POST['ticketnotes']) && trim($_POST['ticketnotes']) != '') {
3076
                        $_SWIFT_TicketObject->CreateNote($_SWIFT_UserObject, $_POST['ticketnotes'], $_POST['notecolor_ticketnotes'], $_POST['notetype'], $_forStaffID);
3077
                }
3078
3079
                echo $this->View->RenderNotes($_SWIFT_TicketObject, $_SWIFT_UserObject);
3080
3081
                return true;
3082
        }
3083
3084
        /**
3085
         * Edit a note
3086
         *
3087
         * @author Varun Shoor
3088
         * @param int $_ticketID The Ticket ID
3089
         * @param int $_ticketNoteID The Ticket Note ID
3090
         * @return bool "true" on Success, "false" otherwise
3091
         * @throws SWIFT_Exception If the Class is not Loaded
3092
         */
3093
        public function EditNote($_ticketID, $_ticketNoteID)
3094
        {
3095
                $_SWIFT = SWIFT::GetInstance();
3096
3097
                if (!$this->GetIsClassLoaded())
3098
                {
3099
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3100
3101
                        return false;
3102
                } else if (empty($_ticketID)) {
3103
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3104
3105
                        return false;
3106
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdateticketnote') == '0') {
3107
                        return false;
3108
                }
3109
3110
                /*
3111
                 * BUG FIX - Parminder Singh
3112
                 *
3113
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3114
                 *
3115
                 * Comments: If current ticket id is merged with other tickets
3116
                 */
3117
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3118
3119
                // Did the object load up?
3120
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3121
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3122
                }
3123
3124
                // Check permission
3125
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3126
                        echo $this->Language->Get('msgnoperm');
3127
3128
                        return false;
3129
3130
                }
3131
3132
                $_SWIFT_TicketNoteObject = new SWIFT_TicketNote($_ticketNoteID);
3133
                if (!$_SWIFT_TicketNoteObject instanceof SWIFT_TicketNote || !$_SWIFT_TicketNoteObject->GetIsClassLoaded())
3134
                {
3135
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3136
3137
                        return false;
3138
                }
3139
3140
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('editnote'), self::MENU_ID, self::NAVIGATION_ID);
3141
                $this->View->RenderNoteForm(SWIFT_UserInterface::MODE_EDIT, $_SWIFT_TicketObject, $_SWIFT_TicketNoteObject);
3142
                $this->UserInterface->Footer();
3143
3144
                return true;
3145
        }
3146
3147
        /**
3148
         * Edit a note processor
3149
         *
3150
         * @author Varun Shoor
3151
         * @param int $_ticketID The Ticket ID
3152
         * @param int $_ticketNoteID The Ticket Note ID
3153
         * @return bool "true" on Success, "false" otherwise
3154
         * @throws SWIFT_Exception If the Class is not Loaded
3155
         */
3156
        public function EditNoteSubmit($_ticketID, $_ticketNoteID)
3157
        {
3158
                $_SWIFT = SWIFT::GetInstance();
3159
3160
                if (!$this->GetIsClassLoaded())
3161
                {
3162
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3163
3164
                        return false;
3165
                } else if (empty($_ticketID)) {
3166
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3167
3168
                        return false;
3169
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdateticketnote') == '0') {
3170
                        return false;
3171
                }
3172
3173
                /*
3174
                 * BUG FIX - Parminder Singh
3175
                 *
3176
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3177
                 *
3178
                 * Comments: If current ticket id is merged with other tickets
3179
                 */
3180
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3181
3182
                // Did the object load up?
3183
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3184
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3185
                }
3186
3187
                // Check permission
3188
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3189
                        echo $this->Language->Get('msgnoperm');
3190
3191
                        return false;
3192
                }
3193
3194
                $_SWIFT_TicketNoteObject = new SWIFT_TicketNote($_ticketNoteID);
3195
                if (!$_SWIFT_TicketNoteObject instanceof SWIFT_TicketNote || !$_SWIFT_TicketNoteObject->GetIsClassLoaded())
3196
                {
3197
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3198
3199
                        return false;
3200
                }
3201
3202
                // Edit notes
3203
                if (trim($_POST['ticketnotes']) != '')
3204
                {
3205
                        $_SWIFT_TicketNoteObject->Update($_SWIFT->Staff->GetStaffID(), $_SWIFT->Staff->GetProperty('fullname'), $_POST['ticketnotes'], intval($_POST['notecolor_ticketnotes']));
3206
                }
3207
3208
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
3209
3210
                echo $this->View->RenderNotes($_SWIFT_TicketObject, $_SWIFT_UserObject);
3211
3212
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_NEWNOTE,
3213
                        $_SWIFT->Language->Get('al_updatenote'),
3214
                        SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
3215
3216
                return true;
3217
        }
3218
3219
        /**
3220
         * Delete Note Processer
3221
         *
3222
         * @author Varun Shoor
3223
         * @param int $_ticketID The Ticket ID
3224
         * @param int $_ticketNoteID The Ticket Note ID
3225
         * @return bool "true" on Success, "false" otherwise
3226
         * @throws SWIFT_Exception If the Class is not Loaded
3227
         */
3228
        public function DeleteNote($_ticketID, $_ticketNoteID)
3229
        {
3230
                $_SWIFT = SWIFT::GetInstance();
3231
3232
                if (!$this->GetIsClassLoaded())
3233
                {
3234
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3235
3236
                        return false;
3237
                } else if (empty($_ticketID)) {
3238
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3239
3240
                        return false;
3241
                } else if ($_SWIFT->Staff->GetPermission('staff_tcandeleteticketnote') == '0') {
3242
                        return false;
3243
                }
3244
3245
                /*
3246
                 * BUG FIX - Parminder Singh
3247
                 *
3248
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3249
                 *
3250
                 * Comments: If current ticket id is merged with other tickets
3251
                 */
3252
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3253
3254
                // Did the object load up?
3255
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3256
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3257
                }
3258
3259
                // Check permission
3260
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3261
                        echo $this->Language->Get('msgnoperm');
3262
3263
                        return false;
3264
3265
                }
3266
3267
                $_SWIFT_TicketNoteObject = new SWIFT_TicketNote($_ticketNoteID);
3268
                if (!$_SWIFT_TicketNoteObject instanceof SWIFT_TicketNote || !$_SWIFT_TicketNoteObject->GetIsClassLoaded())
3269
                {
3270
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3271
3272
                        return false;
3273
                }
3274
3275
3276
                $_SWIFT_TicketNoteObject->Delete();
3277
3278
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
3279
3280
                echo $this->View->RenderNotes($_SWIFT_TicketObject, $_SWIFT_UserObject);
3281
3282
                $_SWIFT_TicketObject->RebuildProperties();
3283
3284
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_NEWNOTE,
3285
                        $_SWIFT->Language->Get('al_deletenote'),
3286
                        SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
3287
3288
                return true;
3289
        }
3290
3291
        /**
3292
         * Execute a workflow action
3293
         *
3294
         * @author Varun Shoor
3295
         * @param int $_ticketID The Ticket ID
3296
         * @param int $_ticketWorkflowID The Ticket Workflow ID
3297
         * @param string $_listType (OPTIONAL) The List Type
3298
         * @param int $_departmentID (OPTIONAL) The Department ID
3299
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
3300
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
3301
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
3302
         * @return bool "true" on Success, "false" otherwise
3303
         * @throws SWIFT_Exception If the Class is not Loaded
3304
         */
3305
        public function ExecuteWorkflow($_ticketID, $_ticketWorkflowID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1,
3306
                        $_ticketTypeID = -1, $_ticketLimitOffset = 0)
3307
        {
3308
                $_SWIFT = SWIFT::GetInstance();
3309
3310
                if (!$this->GetIsClassLoaded())
3311
                {
3312
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3313
3314
                        return false;
3315
                } else if (empty($_ticketID)) {
3316
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3317
3318
                        return false;
3319
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanworkflow') == '0') {
3320
                        return false;
3321
                }
3322
3323
                /*
3324
                 * BUG FIX - Parminder Singh
3325
                 *
3326
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3327
                 *
3328
                 * Comments: If current ticket id is merged with other tickets
3329
                 */
3330
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3331
3332
                // Did the object load up?
3333
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3334
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3335
                }
3336
3337
                // Check permission
3338
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3339
                        echo $this->Language->Get('msgnoperm');
3340
3341
                        return false;
3342
                }
3343
3344
                // Attempt to load the workflow object
3345
                $_SWIFT_TicketWorkflowObject = new SWIFT_TicketWorkflow(new SWIFT_DataID($_ticketWorkflowID));
3346
                if (!$_SWIFT_TicketWorkflowObject instanceof SWIFT_TicketWorkflow || !$_SWIFT_TicketWorkflowObject->GetIsClassLoaded()) {
3347
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3348
                }
3349
3350
                $_ticketLinkedTableContainer = SWIFT_TicketLinkedTable::RetrieveOnTicket($_SWIFT_TicketObject);
3351
3352
                // Make sure this workflow is available to the current ticket
3353
                $_proceedWithWorkflow = false;
3354
                if (isset($_ticketLinkedTableContainer[SWIFT_TicketLinkedTable::LINKTYPE_WORKFLOW])) {
3355
                        foreach ($_ticketLinkedTableContainer[SWIFT_TicketLinkedTable::LINKTYPE_WORKFLOW] as $_ticketLinkedTableID => $_ticketLinkedTableValue) {
3356
                                if ($_ticketLinkedTableValue['linktypeid'] == $_ticketWorkflowID) {
3357
                                        $_proceedWithWorkflow = true;
3358
                                }
3359
                        }
3360
                }
3361
3362
                if ($_proceedWithWorkflow) {
3363
                        $_SWIFT_TicketWorkflowObject->ExecuteActions($_SWIFT_TicketObject);
3364
                }
3365
3366
                $_SWIFT_TicketObject->ProcessUpdatePool();
3367
                SWIFT_TicketManager::RebuildCache();
3368
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
3369
3370
                // Trash?
3371
                if ($_SWIFT_TicketObject->GetProperty('departmentid') == '0') {
3372
                        $_departmentID = 0;
3373
                        $_ticketStatusID = -1;
3374
                        $_ticketTypeID = -1;
3375
3376
                // Department Changed?
3377
                } else if ($_SWIFT_TicketObject->GetProperty('departmentid') != $_departmentID && $_departmentID != -1) {
3378
                        $_departmentID = intval($_SWIFT_TicketObject->GetProperty('departmentid'));
3379
                        $_ticketStatusID = -1;
3380
                        $_ticketTypeID = -1;
3381
                }
3382
3383
                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3384
3385
                // Execute notifications
3386
                if ($_proceedWithWorkflow) {
3387
                        $_workflowNotificationContainer = SWIFT_TicketWorkflowNotification::RetrieveOnWorkflow($_ticketWorkflowID);
3388
                        foreach ($_workflowNotificationContainer as $_ticketWorkflowNotificationID => $_ticketWorkflowNotificationContainer) {
3389
                                $_notificationSubject = $_ticketWorkflowNotificationContainer['subject'];
3390
                                $_notificationContents = $_ticketWorkflowNotificationContainer['notificationcontents'];
3391
3392
                                $_notificationType = false;
3393
                                switch ($_ticketWorkflowNotificationContainer['notificationtype']) {
3394
                                        case SWIFT_TicketWorkflowNotification::TYPE_USER:
3395
                                                $_notificationType = SWIFT_TicketNotification::TYPE_USER;
3396
                                                break;
3397
3398
                                        case SWIFT_TicketWorkflowNotification::TYPE_USERORGANIZATION:
3399
                                                $_notificationType = SWIFT_TicketNotification::TYPE_USERORGANIZATION;
3400
                                                break;
3401
3402
                                        case SWIFT_TicketWorkflowNotification::TYPE_STAFF:
3403
                                                $_notificationType = SWIFT_TicketNotification::TYPE_STAFF;
3404
                                                break;
3405
3406
                                        case SWIFT_TicketWorkflowNotification::TYPE_TEAM:
3407
                                                $_notificationType = SWIFT_TicketNotification::TYPE_TEAM;
3408
                                                break;
3409
3410
                                        case SWIFT_TicketWorkflowNotification::TYPE_DEPARTMENT:
3411
                                                $_notificationType = SWIFT_TicketNotification::TYPE_DEPARTMENT;
3412
                                                break;
3413
3414
                                        default:
3415
                                                break;
3416
                                }
3417
3418
                                $_SWIFT_TicketObject->Notification->Dispatch($_notificationType, array(), $_notificationSubject, $_notificationContents);
3419
                        }
3420
                }
3421
3422
                return true;
3423
        }
3424
3425
        /**
3426
         * Ticket Jump Processor (Prev/Next)
3427
         *
3428
         * @author Varun Shoor
3429
         * @param int $_ticketID The Ticket ID
3430
         * @param string $_listType (OPTIONAL) The List Type
3431
         * @param int $_departmentID (OPTIONAL) The Department ID
3432
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
3433
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
3434
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
3435
         * @return bool "true" on Success, "false" otherwise
3436
         * @throws SWIFT_Exception If the Class is not Loaded
3437
         */
3438
        public function Jump($_jumpType, $_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
3439
                        $_ticketLimitOffset = 0)
3440
        {
3441
                $_SWIFT = SWIFT::GetInstance();
3442
3443
                if (!$this->GetIsClassLoaded())
3444
                {
3445
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3446
3447
                        return false;
3448
                } else if (empty($_ticketID)) {
3449
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3450
3451
                        return false;
3452
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0') {
3453
                        return false;
3454
                }
3455
3456
                /*
3457
                 * BUG FIX - Parminder Singh
3458
                 *
3459
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3460
                 *
3461
                 * Comments: If current ticket id is merged with other tickets
3462
                 */
3463
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3464
3465
                // Did the object load up?
3466
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3467
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3468
                }
3469
3470
                // Check permission
3471
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3472
                        echo $this->Language->Get('msgnoperm');
3473
3474
                        return false;
3475
                }
3476
3477
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
3478
3479
                $_jumpTicketID = 0;
3480
                if ($_jumpType == 'next')
3481
                {
3482
                        $_jumpTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3483
                } else {
3484
                        $_jumpTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'previous', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3485
                }
3486
3487
                if (!empty($_jumpTicketID))
3488
                {
3489
                        $this->Load->Method('View', $_jumpTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3490
                } else {
3491
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3492
                }
3493
3494
                return true;
3495
        }
3496
3497
        /**
3498
         * Ticket Reply Submission Processor
3499
         *
3500
         * @author Varun Shoor
3501
         * @param int $_ticketID The Ticket ID
3502
         * @param string $_listType (OPTIONAL) The List Type
3503
         * @param int $_departmentID (OPTIONAL) The Department ID
3504
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
3505
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
3506
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
3507
         * @return bool "true" on Success, "false" otherwise
3508
         * @throws SWIFT_Exception If the Class is not Loaded
3509
         */
3510
        public function ReplySubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
3511
                        $_ticketLimitOffset = 0)
3512
        {
3513
                $_SWIFT = SWIFT::GetInstance();
3514
3515
                if (!$this->GetIsClassLoaded())
3516
                {
3517
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3518
3519
                        return false;
3520
                } else if (empty($_ticketID)) {
3521
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3522
3523
                        return false;
3524
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanreply') == '0') {
3525
                        return false;
3526
                }
3527
3528
                $_emailQueueCache = $this->Cache->Get('queuecache');
3529
                $_templateGroupCache = $this->Cache->Get('templategroupcache');
3530
3531
                /*
3532
                 * BUG FIX - Parminder Singh
3533
                 *
3534
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3535
                 *
3536
                 * Comments: If current ticket id is merged with other tickets
3537
                 */
3538
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3539
3540
                // Did the object load up?
3541
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3542
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3543
                }
3544
3545
                // Check permission
3546
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3547
                        echo $this->Language->Get('msgnoperm');
3548
3549
                        return false;
3550
                }
3551
                /*
3552
                 * BUG FIX - Nidhi Gupta
3553
                 *
3554
                 * SWIFT-839: Permission to restrict staff from moving tickets to departments they're not assigned to
3555
                 *
3556
                 * Comments: Added check for staff to move tickets in unassigned departments
3557
                 */
3558
                if ($_SWIFT->Staff->GetPermission('staff_tcanchangeunassigneddepartment') == '0') {
3559
                        if ((isset($_POST['replydepartmentid']) && !in_array($_POST['replydepartmentid'], $_SWIFT->Staff->GetAssignedDepartments()))
3560
                                || (isset($_POST['redepartmentid']) && !in_array($_POST['redepartmentid'], $_SWIFT->Staff->GetAssignedDepartments())))
3561
                        {
3562
                                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
3563
                                        self::NAVIGATION_ID);
3564
                                $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
3565
                                $this->UserInterface->Footer();
3566
3567
                                return false;
3568
                        }
3569
                }
3570
3571
3572
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
3573
3574
                $_nextTicketID = false;
3575
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
3576
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3577
                }
3578
3579
                $this->_ProcessDispatchTab($_SWIFT_TicketObject, 'reply');
3580
3581
                $_dontSendEmail = false;
3582
                if (!isset($_POST['optreply_sendemail']) || (isset($_POST['optreply_sendmail']) && $_POST['optreply_sendmail'] != '1'))
3583
                {
3584
                        $_dontSendEmail = true;
3585
                }
3586
3587
                $_isPrivate = false;
3588
                if (isset($_POST['optreply_private']) && $_POST['optreply_private'] == '1')
3589
                {
3590
                        $_dontSendEmail = true;
3591
                        $_isPrivate = true;
3592
                }
3593
3594
                $_isHTML = true;
3595
        $_POST['replycontents'] = self::SmartReply($_SWIFT_TicketObject, $_POST['replycontents']);
3596
3597
                $_fromEmailAddress = self::_GetDispatchFromEmail('reply');
3598
                $_emailQueueID = 0;
3599
                if (isset($_POST['replyfrom']) && $_POST['replyfrom'] > 0 && isset($_emailQueueCache['list'][$_POST['replyfrom']]))
3600
                {
3601
                        $_emailQueueID = $_POST['replyfrom'];
3602
                }
3603
3604
                $_SWIFT_TicketObject->UpdateQueue($_emailQueueID);
3605
3606
                $_SWIFT_TicketPostObject = false;
3607
                if (isset($_POST['replycontents']) && trim($_POST['replycontents']) != '' && (!isset($_POST['optreply_createasuser']) || $_POST['optreply_createasuser'] == '0'))
3608
                {
3609
                        $_SWIFT_TicketPostObject = SWIFT_TicketPost::CreateStaff($_SWIFT_TicketObject, $_SWIFT->Staff, SWIFT_Ticket::CREATIONMODE_STAFFCP, $_POST['replycontents'],
3610
                                        '', $_dontSendEmail, $_isHTML, $_fromEmailAddress, $_isPrivate);
3611
                        $_ticketPostID = $_SWIFT_TicketPostObject->GetTicketPostID();
3612
3613
                } else if (isset($_POST['replycontents']) && trim($_POST['replycontents']) != '' && isset($_POST['optreply_createasuser']) && $_POST['optreply_createasuser'] == '1') {
3614
3615
                        $_emailQueueID = $_SWIFT_TicketObject->GetProperty('emailqueueid');
3616
3617
                        $_emailQueueContainer = false;
3618
                        if (isset($_emailQueueCache['list'][$_emailQueueID]))
3619
                        {
3620
                                $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
3621
                        }
3622
3623
                        $_templateGroupID = SWIFT_TemplateGroup::GetDefaultGroupID();
3624
3625
                        if (_is_array($_emailQueueContainer) && isset($_templateGroupCache[$_emailQueueContainer['tgroupid']]))
3626
                        {
3627
                                $_templateGroupID = $_emailQueueContainer['tgroupid'];
3628
                        }
3629
3630
                        $_templateGroupContainer = $_templateGroupCache[$_templateGroupID];
3631
3632
                        $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
3633
                        if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded())
3634
                        {
3635
                                $_userID = SWIFT_Ticket::GetOrCreateUserID($_SWIFT_TicketObject->GetProperty('fullname'), $_SWIFT_TicketObject->GetProperty('email'), $_templateGroupContainer['regusergroupid']);
3636
                                $_SWIFT_TicketObject->UpdateUser($_userID);
3637
                                $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_userID));
3638
                        }
3639
3640
                        $_ticketPostID = SWIFT_TicketPost::CreateClient($_SWIFT_TicketObject, $_SWIFT_UserObject, SWIFT_Ticket::CREATIONMODE_STAFFCP,
3641
                                        $_POST['replycontents'], '', SWIFT_TicketPost::CREATOR_USER, $_isHTML, false, array());
3642
                        $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
3643
                }
3644
3645
                SWIFT_TicketPostLock::DeleteOnTicket(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff->GetStaffID());
3646
3647
                if ($_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && isset($_POST['optreply_createasuser']) && $_POST['optreply_createasuser'] == '1')
3648
                {
3649
                        $_SWIFT_TicketObject->ProcessPostAttachments($_SWIFT_TicketPostObject, 'replyattachments');
3650
                }
3651
3652
                if (isset($_POST['optreply_watch']) && $_POST['optreply_watch'] == '1')
3653
                {
3654
                        SWIFT_Ticket::Watch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
3655
                } else {
3656
                        SWIFT_Ticket::UnWatch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
3657
                }
3658
3659
                $this->_ProcessFollowUp($_SWIFT_TicketObject, 're');
3660
3661
                // Begin Hook: staff_ticket_reply
3662
                unset($_hookCode);
3663
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_reply')) ? eval($_hookCode) : false;
3664
                // End Hook
3665
3666
                if ($_isPrivate == false)
3667
                {
3668
                        $_SWIFT_TicketObject->ProcessUpdatePool();
3669
                        SWIFT_TicketManager::RebuildCache();
3670
                        /**
3671
                         * BUG FIX - Ravi Sharma
3672
                         *
3673
                         * SWIFT-3333: Due time gets reapplied while replying the ticket, if Due time is already cleared from the ticket
3674
                         *
3675
                         * Comments: None.
3676
                         */
3677
                        if($_SWIFT_TicketObject->GetProperty('duetime') != '0')
3678
                        {
3679
                                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
3680
                        }
3681
                }
3682
3683
3684
                // Activity Log
3685
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('log_newreply'), $_SWIFT_TicketObject->GetTicketDisplayID()),
3686
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
3687
3688
                // Do we need to add a macro
3689
                $_addMacro = false;
3690
                if (isset($_POST['optreply_addmacro']) && $_POST['optreply_addmacro'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded())
3691
                {
3692
                        $_addMacro = true;
3693
                }
3694
3695
                // Do we need to add a KB article
3696
                $_addKBArticle = false;
3697
                if (isset($_POST['optreply_addkb']) && $_POST['optreply_addkb'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded() && SWIFT_App::IsInstalled(APP_KNOWLEDGEBASE))
3698
                {
3699
                        $_addKBArticle = true;
3700
                }
3701
3702
                // Does the new department belong to this staff? if not, we need to jump him back to list!
3703
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
3704
                if (isset($_POST['replydepartmentid']) && !empty($_POST['replydepartmentid']) && !in_array($_POST['replydepartmentid'], $_assignedDepartmentIDList)) {
3705
                        if ($_addMacro)
3706
                        {
3707
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3708
                        } else if ($_addKBArticle) {
3709
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3710
                        } else {
3711
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3712
                        }
3713
3714
                        return true;
3715
                }
3716
3717
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
3718
                {
3719
                        if ($_addMacro)
3720
                        {
3721
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3722
                        } else if ($_addKBArticle) {
3723
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', $_departmentID, $_ticketStatusID, $_ticketTypeID);
3724
                        } else {
3725
                                $GLOBALS['_POST'] = $GLOBALS['_REQUEST'] = $GLOBALS['_GET'] = array();
3726
                                $GLOBALS['_POST']['isajax'] = true;
3727
3728
                                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3729
                        }
3730
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
3731
                        if ($_addMacro)
3732
                        {
3733
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3734
                        } else if ($_addKBArticle) {
3735
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3736
                        } else {
3737
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3738
                        }
3739
3740
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
3741
                        if ($_addMacro)
3742
                        {
3743
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', -1, -1, -1, $_addKBArticle);
3744
                        } else if ($_addKBArticle) {
3745
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', -1, -1, -1);
3746
                        } else {
3747
                                $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
3748
                        }
3749
3750
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
3751
                        if (!empty($_nextTicketID))
3752
                        {
3753
                                $GLOBALS['_POST'] = $GLOBALS['_REQUEST'] = $GLOBALS['_GET'] = array();
3754
                                $GLOBALS['_POST']['isajax'] = true;
3755
3756
                                $this->Load->Method('View', $_nextTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3757
                        } else {
3758
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3759
                        }
3760
                }
3761
3762
                return true;
3763
        }
3764
3765
        /**
3766
         * Ticket Forward Submission Processor
3767
         *
3768
         * @author Varun Shoor
3769
         * @param int $_ticketID The Ticket ID
3770
         * @param string $_listType (OPTIONAL) The List Type
3771
         * @param int $_departmentID (OPTIONAL) The Department ID
3772
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
3773
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
3774
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
3775
         * @return bool "true" on Success, "false" otherwise
3776
         * @throws SWIFT_Exception If the Class is not Loaded
3777
         */
3778
        public function ForwardSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
3779
                        $_ticketLimitOffset = 0)
3780
        {
3781
                $_SWIFT = SWIFT::GetInstance();
3782
3783
                if (!$this->GetIsClassLoaded())
3784
                {
3785
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
3786
3787
                        return false;
3788
                } else if (empty($_ticketID)) {
3789
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3790
3791
                        return false;
3792
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanforward') == '0') {
3793
                        return false;
3794
                }
3795
3796
                /*
3797
                 * BUG FIX - Parminder Singh
3798
                 *
3799
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
3800
                 *
3801
                 * Comments: If current ticket id is merged with other tickets
3802
                 */
3803
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
3804
3805
                // Did the object load up?
3806
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
3807
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
3808
                }
3809
3810
                // Check permission
3811
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
3812
                        echo $this->Language->Get('msgnoperm');
3813
3814
                        return false;
3815
                }
3816
                /*
3817
                 * BUG FIX - Nidhi Gupta
3818
                 *
3819
                 * SWIFT-839: Permission to restrict staff from moving tickets to departments they're not assigned to
3820
                 *
3821
                 * Comments: Added check for staff to move tickets in unassigned departments
3822
                 */
3823
                if ($_SWIFT->Staff->GetPermission('staff_tcanchangeunassigneddepartment') == '0') {
3824
                        if ((isset($_POST['forwarddepartmentid']) && !in_array($_POST['forwarddepartmentid'], $_SWIFT->Staff->GetAssignedDepartments()))
3825
                                || (isset($_POST['frdepartmentid']) && !in_array($_POST['frdepartmentid'], $_SWIFT->Staff->GetAssignedDepartments())))
3826
                        {
3827
                                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('viewticket'), self::MENU_ID,
3828
                                        self::NAVIGATION_ID);
3829
                                $this->UserInterface->DisplayError($this->Language->Get('titlenoperm'), $this->Language->Get('msgnoperm'));
3830
                                $this->UserInterface->Footer();
3831
3832
                                return false;
3833
                        }
3834
                }
3835
3836
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
3837
3838
                $_nextTicketID = false;
3839
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
3840
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3841
                }
3842
3843
                $_destinationEmailContainer = self::GetSanitizedEmailList('forwardto');
3844
                if (!_is_array($_destinationEmailContainer))
3845
                {
3846
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3847
3848
                        return false;
3849
                }
3850
3851
                $_destinationEmailAddress = $_destinationEmailContainer[0];
3852
3853
                $this->_ProcessDispatchTab($_SWIFT_TicketObject, 'forward');
3854
3855
                $_ticketRecipientContainer = SWIFT_TicketRecipient::RetrieveOnTicket($_SWIFT_TicketObject);
3856
                if ((!isset($_ticketRecipientContainer[SWIFT_TicketRecipient::TYPE_THIRDPARTY]) ||
3857
                                (isset($_ticketRecipientContainer[SWIFT_TicketRecipient::TYPE_THIRDPARTY]) && !in_array($_destinationEmailAddress, $_ticketRecipientContainer[SWIFT_TicketRecipient::TYPE_THIRDPARTY])))
3858
                                && isset($_POST['optforward_addrecipients']) && is_array($_POST['optforward_addrecipients']) && in_array($_destinationEmailAddress, $_POST['optforward_addrecipients']))
3859
                {
3860
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_THIRDPARTY, array($_destinationEmailAddress));
3861
                }
3862
3863
                $_dontSendEmail = false;
3864
                if (!isset($_POST['optforward_sendemail']) || (isset($_POST['optforward_sendmail']) && $_POST['optforward_sendmail'] != '1'))
3865
                {
3866
                        $_dontSendEmail = true;
3867
                }
3868
3869
                $_isPrivate = false;
3870
                if (isset($_POST['optforward_private']) && $_POST['optforward_private'] == '1')
3871
                {
3872
                        $_dontSendEmail = true;
3873
                        $_isPrivate = true;
3874
                }
3875
3876
                $_isHTML = true;
3877
3878
        $_POST['forwardcontents'] = self::SmartReply($_SWIFT_TicketObject, $_POST['forwardcontents']);
3879
3880
                $_fromEmailAddress = self::_GetDispatchFromEmail('forward');
3881
3882
                $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
3883
                $_emailQueueID = 0;
3884
                if ($_POST['forwardfrom'] > 0 && isset($_emailQueueCache['list'][$_POST['forwardfrom']]))
3885
                {
3886
                        $_emailQueueID = $_POST['forwardfrom'];
3887
                }
3888
3889
                $_SWIFT_TicketObject->UpdateQueue($_emailQueueID);
3890
3891
                $_SWIFT_TicketPostObject = false;
3892
                if ($_POST['forwardcontents'] != '')
3893
                {
3894
                        /*
3895
                        * BUG FIX - Ravi Sharma
3896
                        *
3897
                        * SWIFT-3402 Edit Subject Field option should be available on ticket forwarding page.
3898
                        */
3899
                        $_ticketPostID = SWIFT_TicketPost::CreateForward($_SWIFT_TicketObject, $_SWIFT->Staff, SWIFT_Ticket::CREATIONMODE_STAFFCP, $_POST['forwardcontents'], $_POST['forwardsubject'], $_destinationEmailAddress, false, $_isHTML, $_fromEmailAddress, $_isPrivate);
3900
3901
                        $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
3902
                }
3903
3904
                if (isset($_POST['optforward_watch']) && $_POST['optforward_watch'] == '1')
3905
                {
3906
                        SWIFT_Ticket::Watch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
3907
                } else {
3908
                        SWIFT_Ticket::UnWatch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
3909
                }
3910
3911
                $this->_ProcessFollowUp($_SWIFT_TicketObject, 'fr');
3912
3913
                // Begin Hook: staff_ticket_forward
3914
                unset($_hookCode);
3915
                ($_hookCode = SWIFT_Hook::Execute('staff_ticket_forward')) ? eval($_hookCode) : false;
3916
                // End Hook
3917
3918
                if ($_isPrivate == false)
3919
                {
3920
                        $_SWIFT_TicketObject->ProcessUpdatePool();
3921
                        SWIFT_TicketManager::RebuildCache();
3922
                }
3923
3924
3925
                // Activity Log
3926
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('log_forward'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_destinationEmailAddress),
3927
                                SWIFT_StaffActivityLog::ACTION_UPDATE, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
3928
3929
                // Do we need to add a macro
3930
                $_addMacro = false;
3931
                if (isset($_POST['optforward_addmacro']) && $_POST['optforward_addmacro'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded())
3932
                {
3933
                        $_addMacro = true;
3934
                }
3935
3936
                // Do we need to add a KB article
3937
                $_addKBArticle = false;
3938
                if (isset($_POST['optforward_addkb']) && $_POST['optforward_addkb'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded() && SWIFT_App::IsInstalled(APP_KNOWLEDGEBASE))
3939
                {
3940
                        $_addKBArticle = true;
3941
                }
3942
3943
                // Does the new department belong to this staff? if not, we need to jump him back to list!
3944
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
3945
                if (isset($_POST['forwarddepartmentid']) && !empty($_POST['forwarddepartmentid']) && !in_array($_POST['forwarddepartmentid'], $_assignedDepartmentIDList)) {
3946
                        if ($_addMacro)
3947
                        {
3948
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3949
                        } else if ($_addKBArticle) {
3950
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3951
                        } else {
3952
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3953
                        }
3954
3955
                        return true;
3956
                }
3957
3958
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
3959
                {
3960
                        if ($_addMacro)
3961
                        {
3962
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3963
                        } else if ($_addKBArticle) {
3964
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', $_departmentID, $_ticketStatusID, $_ticketTypeID);
3965
                        } else {
3966
                                $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3967
                        }
3968
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
3969
                        if ($_addMacro)
3970
                        {
3971
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_addKBArticle);
3972
                        } else if ($_addKBArticle) {
3973
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3974
                        } else {
3975
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3976
                        }
3977
3978
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
3979
                        if ($_addMacro)
3980
                        {
3981
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', '-1', '-1', '-1', $_addKBArticle);
3982
                        } else if ($_addKBArticle) {
3983
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', '-1', '-1', '-1');
3984
                        } else {
3985
                                $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
3986
                        }
3987
3988
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
3989
                        if (!empty($_nextTicketID))
3990
                        {
3991
                                $this->Load->Method('View', $_nextTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
3992
                        } else {
3993
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
3994
                        }
3995
3996
                }
3997
3998
3999
4000
                return true;
4001
        }
4002
4003
        /**
4004
         * Retrieve the From Email Address for Dispatch Tab
4005
         *
4006
         * @author Varun Shoor
4007
         * @param string $_tabType The Tab Type
4008
         * @return string The From Email Address
4009
         * @throws SWIFT_Exception If Invalid Data is Provided
4010
         */
4011
        static protected function _GetDispatchFromEmail($_tabType)
4012
        {
4013
                $_SWIFT = SWIFT::GetInstance();
4014
4015
                $_fromEmailAddress = '';
4016
4017
                $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
4018
4019
                if (isset($_POST[$_tabType . 'from']))
4020
                {
4021
                        if ($_POST[$_tabType . 'from'] == '-1')
4022
                        {
4023
                                $_fromEmailAddress = $_SWIFT->Staff->GetProperty('email');
4024
                        } else if ($_POST[$_tabType . 'from'] == '0') {
4025
                                $_fromEmailAddress = $_SWIFT->Settings->Get('general_returnemail');
4026
                        } else if (isset($_emailQueueCache['list'][$_POST[$_tabType . 'from']])) {
4027
                                if (!empty($_emailQueueCache['list'][$_POST[$_tabType . 'from']]['customfromemail'])) {
4028
                                        $_fromEmailAddress = $_emailQueueCache['list'][$_POST[$_tabType . 'from']]['customfromemail'];
4029
                                } else {
4030
                                        $_fromEmailAddress = $_emailQueueCache['list'][$_POST[$_tabType . 'from']]['email'];
4031
                                }
4032
                        }
4033
                }
4034
4035
                return $_fromEmailAddress;
4036
        }
4037
4038
        /**
4039
         * Processes the common actions associated in Reply/Forward tabs.
4040
         *
4041
         * @author Varun Shoor
4042
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
4043
         * @param string $_tabType The Tab Type
4044
         * @return bool "true" on Success, "false" otherwise
4045
         * @throws SWIFT_Exception If the Class is not Loaded
4046
         */
4047
        protected function _ProcessDispatchTab(SWIFT_Ticket $_SWIFT_TicketObject, $_tabType)
4048
        {        $_SWIFT = SWIFT::GetInstance();
4049
4050
                if (!$this->GetIsClassLoaded())
4051
                {
4052
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4053
4054
                        return false;
4055
                } else if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
4056
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4057
                }
4058
4059
                // Process the notes
4060
                $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
4061
4062
                if (isset($_POST[$_tabType . 'ticketnotes']) && trim($_POST[$_tabType . 'ticketnotes']) != '') {
4063
                        /*
4064
                         * BUG FIX - Saloni Dhall
4065
                         *
4066
                         * SWIFT-1278 "New Ticket Note" notification does not work, when Note is added while replying the ticket
4067
                         *
4068
                         * Comments: Trigger notification event
4069
                         */
4070
                        $_SWIFT_TicketObject->NotificationManager->SetEvent('newticketnotes');
4071
4072
                        $_staffName = $_SWIFT->Staff->GetProperty('fullname');
4073
                        $_staffEmail = $_SWIFT->Staff->GetProperty('email');
4074
4075
                        $_SWIFT_TicketObject->SetWatcherProperties($_staffName, sprintf($_SWIFT->Language->Get('watcherprefix'), $_staffName, $_staffEmail) . SWIFT_CRLF . $_POST[$_tabType . 'ticketnotes']);
4076
                        $_SWIFT_TicketObject->CreateNote($_SWIFT_UserObject, $_POST[$_tabType . 'ticketnotes'],
4077
                                        $_POST['notecolor_' . $_tabType . 'ticketnotes'], $_POST[$_tabType . 'notetype'], false);
4078
                }
4079
4080
                // Process Ticket Priorities
4081
                $_departmentField = $_tabType . 'departmentid';
4082
                $_ownerField = $_tabType . 'ownerstaffid';
4083
                $_ticketTypeField = $_tabType . 'tickettypeid';
4084
                $_ticketStatusField = $_tabType . 'ticketstatusid';
4085
                $_ticketPriorityField = $_tabType . 'ticketpriorityid';
4086
4087
                if (isset($_POST[$_departmentField]) && $_POST[$_departmentField] != '0' &&
4088
                                $_POST[$_departmentField] != $_SWIFT_TicketObject->GetProperty('departmentid'))
4089
                {
4090
                        $_SWIFT_TicketObject->SetDepartment($_POST[$_departmentField]);
4091
                }
4092
4093
                if (isset($_POST[$_ownerField]) && $_POST[$_ownerField] != $_SWIFT_TicketObject->GetProperty('ownerstaffid'))
4094
                {
4095
                        $_SWIFT_TicketObject->SetOwner($_POST[$_ownerField]);
4096
                }
4097
4098
                if (isset($_POST[$_ticketTypeField]) && $_POST[$_ticketTypeField] != $_SWIFT_TicketObject->GetProperty('tickettypeid'))
4099
                {
4100
                        $_SWIFT_TicketObject->SetType($_POST[$_ticketTypeField]);
4101
                }
4102
4103
                if (isset($_POST[$_ticketStatusField]) && $_POST[$_ticketStatusField] != $_SWIFT_TicketObject->GetProperty('ticketstatusid'))
4104
                {
4105
                        $_SWIFT_TicketObject->SetStatus($_POST[$_ticketStatusField]);
4106
                }
4107
4108
                if (isset($_POST[$_ticketPriorityField]) && $_POST[$_ticketPriorityField] != $_SWIFT_TicketObject->GetProperty('priorityid'))
4109
                {
4110
                        $_SWIFT_TicketObject->SetPriority($_POST[$_ticketPriorityField]);
4111
                }
4112
4113
                // Update Tags
4114
                if ($_SWIFT->Staff->GetPermission('staff_canupdatetags') != '0') {
4115
                        SWIFT_Tag::Process(SWIFT_TagLink::TYPE_TICKET, $_SWIFT_TicketObject->GetTicketID(),
4116
                                SWIFT_UserInterface::GetMultipleInputValues($_tabType . 'tags'), $_SWIFT->Staff->GetStaffID());
4117
                }
4118
4119
                // Update Recipients
4120
                SWIFT_TicketRecipient::DeleteOnTicket(array($_SWIFT_TicketObject->GetTicketID()), true);
4121
4122
                $_ccEmailContainer          = self::GetSanitizedEmailList($_tabType . 'cc');
4123
                $_bccEmailContainer         = self::GetSanitizedEmailList($_tabType . 'bcc');
4124
                $_destinationEmailContainer = self::GetSanitizedEmailList($_tabType . 'to');
4125
                /*
4126
                 * BUG FIX - Mansi Wason
4127
                 *
4128
             * SWIFT-1618 If we forward a ticket to more than one e-mail address, mail will be received at first address only
4129
                 *
4130
             * Comments: Add multiple To: address to CC: list, except first To: email address, which would be marked as it is.
4131
                 */
4132
                array_shift($_destinationEmailContainer);
4133
4134
                $_ccEmailContainer         = !empty($_destinationEmailContainer) ? array_merge($_ccEmailContainer, $_destinationEmailContainer) : $_ccEmailContainer;
4135
                $_thirdpartyEmailContainer = array();
4136
4137
                $_checkboxCCEmailContainer  = self::GetSanitizedEmailList($_tabType . 'cc', true);
4138
                $_checkboxBCCEmailContainer = self::GetSanitizedEmailList($_tabType . 'bcc', true);
4139
4140
                $_ignoreCCEmailList = $_ignoreBCCEmailList = array();
4141
4142
                if (_is_array($_destinationEmailContainer) && count($_destinationEmailContainer) > 1) {
4143
                        foreach ($_destinationEmailContainer as $_key => $_emailAddress) {
4144
                                if ($_key == 0) {
4145
                                        continue;
4146
                                }
4147
4148
                                if (!in_array($_emailAddress, $_ccEmailContainer)) {
4149
                                        if ($_tabType == 'forward' && isset($_POST['optforward_addrecipients']) && is_array($_POST['optforward_addrecipients'])
4150
                                                && in_array($_emailAddress, $_POST['optforward_addrecipients'])
4151
                                        ) {
4152
                                                $_thirdpartyEmailContainer[] = $_emailAddress;
4153
                                        } else if ($_tabType != 'forward') {
4154
                                                $_ccEmailContainer[] = $_emailAddress;
4155
                                        }
4156
                                }
4157
                        }
4158
                }
4159
4160
                if (_is_array($_ccEmailContainer)) {
4161
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_CC, $_ccEmailContainer);
4162
4163
                        foreach ($_ccEmailContainer as $_emailAddress)
4164
                        {
4165
                                $_checkHash = md5('taginputcheck_' . $_tabType . 'cc' . $_emailAddress);
4166
4167
                                // Is it an existing entry AND the user didnt check it?
4168
                                if (isset($_POST[$_checkHash]) && !in_array($_emailAddress, $_checkboxCCEmailContainer))
4169
                                {
4170
                                        $_ignoreCCEmailList[] = $_emailAddress;
4171
                                }
4172
                        }
4173
4174
                }
4175
4176
                /*
4177
                 * BUG FIX - Varun Shoor
4178
                 *
4179
                 * SWIFT-1100 Forwarding a ticket to more than one email adds the 2nd address or further in CC list instead of third party
4180
                 *
4181
                 */
4182
                if (_is_array($_thirdpartyEmailContainer)) {
4183
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_THIRDPARTY, $_thirdpartyEmailContainer);
4184
4185
                        foreach ($_thirdpartyEmailContainer as $_emailAddress)
4186
                        {
4187
                                $_ccEmailContainer[] = $_emailAddress;
4188
                        }
4189
                }
4190
4191
4192
                if (_is_array($_bccEmailContainer)) {
4193
                        SWIFT_TicketRecipient::Create($_SWIFT_TicketObject, SWIFT_TicketRecipient::TYPE_BCC, $_bccEmailContainer);
4194
4195
                        foreach ($_bccEmailContainer as $_emailAddress)
4196
                        {
4197
                                $_checkHash = md5('taginputcheck_' . $_tabType . 'bcc' . $_emailAddress);
4198
4199
                                // Is it an existing entry AND the user didnt check it?
4200
                                if (isset($_POST[$_checkHash]) && !in_array($_emailAddress, $_checkboxBCCEmailContainer))
4201
                                {
4202
                                        $_ignoreBCCEmailList[] = $_emailAddress;
4203
                                }
4204
                        }
4205
                }
4206
4207
                SWIFT::Set('_ignoreCCEmail', $_ignoreCCEmailList);
4208
                SWIFT::Set('_ignoreBCCEmail', $_ignoreBCCEmailList);
4209
4210
                // Process Options
4211
                $_dueDateline = GetDateFieldTimestamp($_tabType . 'due');
4212
                $_resolutionDueDateline = GetDateFieldTimestamp($_tabType . 'resolutiondue');
4213
4214
                // Due Dateline
4215
                if (!empty($_dueDateline) && $_SWIFT_TicketObject->GetProperty('duetime') != '0' && gmdate('d M Y h:i A', $_dueDateline) != gmdate('d M Y h:i A', $_SWIFT_TicketObject->GetProperty('duetime'))) {
4216
                        $_SWIFT_TicketObject->SetDue($_dueDateline);
4217
4218
                // We need to clear it?
4219
                } else if ($_tabType != 'newticket' && empty($_dueDateline) && $_SWIFT_TicketObject->GetProperty('duetime') != '0') {
4220
                        /*
4221
                         * BUG FIX - Bishwanath Jha
4222
                         *
4223
                         * SWIFT-2078: SLA plan is not applied correctly when ticket status is changed with staff reply
4224
                         *
4225
                         * Comments: Added this method to execute on shutdown. which allow SLA calculation first then clear overdue time.
4226
                         */
4227
                        register_shutdown_function(array($_SWIFT_TicketObject, 'ClearOverdue'));
4228
                }
4229
4230
                // Resolution Due Dateline
4231
                if (!empty($_resolutionDueDateline) && gmdate('d M Y h:i A', $_resolutionDueDateline) != gmdate('d M Y h:i A', $_SWIFT_TicketObject->GetProperty('resolutionduedateline')) && $_SWIFT_TicketObject->GetProperty('isresolved') != '1') {
4232
                        $_SWIFT_TicketObject->SetResolutionDue($_resolutionDueDateline);
4233
4234
                // We need to clear it?
4235
                } else if ($_tabType != 'newticket' && empty($_resolutionDueDateline) && $_SWIFT_TicketObject->GetProperty('resolutionduedateline') != '0') {
4236
                        $_SWIFT_TicketObject->ClearResolutionDue();
4237
                }
4238
4239
                // Process Draft
4240
                if ($_SWIFT_TicketObject->GetProperty('hasdraft') == '1')
4241
                {
4242
                        SWIFT_TicketDraft::DeleteOnTicket(array($_SWIFT_TicketObject->GetTicketID()));
4243
4244
                        $_SWIFT_TicketObject->ClearHasDraft();
4245
                }
4246
4247
                // Time tracking stuff
4248
                if (!empty($_POST[$_tabType . 'billingtimeworked']) || !empty($_POST[$_tabType . 'billingtimebillable']))
4249
                {
4250
                        // Create the time worked entry
4251
                        $_SWIFT_TicketTimeTrackObject = SWIFT_TicketTimeTrack::Create($_SWIFT_TicketObject, $_SWIFT->Staff,
4252
                                        self::GetBillingTime($_POST[$_tabType . 'billingtimeworked']), self::GetBillingTime($_POST[$_tabType . 'billingtimebillable']),
4253
                                        1, '', $_SWIFT->Staff, DATENOW, DATENOW);
4254
                }
4255
4256
                return true;
4257
        }
4258
4259
        /**
4260
         * Ticket Save as Draft
4261
         *
4262
         * @author Varun Shoor
4263
         * @param int $_ticketID The Ticket ID
4264
         * @param string $_listType (OPTIONAL) The List Type
4265
         * @param int $_departmentID (OPTIONAL) The Department ID
4266
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
4267
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
4268
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
4269
         * @return bool "true" on Success, "false" otherwise
4270
         * @throws SWIFT_Exception If the Class is not Loaded
4271
         */
4272
        public function SaveAsDraft($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
4273
                        $_ticketLimitOffset = 0)
4274
        {
4275
                $_SWIFT = SWIFT::GetInstance();
4276
4277
                if (!$this->GetIsClassLoaded())
4278
                {
4279
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4280
4281
                        return false;
4282
                } else if (empty($_ticketID)) {
4283
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4284
4285
                        return false;
4286
                } else if ($_SWIFT->Staff->GetPermission('staff_tcansaveasdraft') == '0') {
4287
                        return false;
4288
                }
4289
4290
                /*
4291
                 * BUG FIX - Parminder Singh
4292
                 *
4293
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
4294
                 *
4295
                 * Comments: If current ticket id is merged with other tickets
4296
                 */
4297
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
4298
4299
                // Did the object load up?
4300
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
4301
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4302
                }
4303
4304
                // Check permission
4305
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
4306
                        echo $this->Language->Get('msgnoperm');
4307
4308
                        return false;
4309
                }
4310
4311
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
4312
4313
                $_nextTicketID = false;
4314
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
4315
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
4316
                }
4317
4318
                $this->_ProcessDispatchTab($_SWIFT_TicketObject, 'reply');
4319
4320
                // Save as Draft
4321
                if (trim($_POST['replycontents']) == '')
4322
                {
4323
                        SWIFT_TicketDraft::DeleteOnTicket(array($_SWIFT_TicketObject->GetTicketID()));
4324
                        $_SWIFT_TicketObject->ClearHasDraft();
4325
                } else {
4326
                        SWIFT_TicketDraft::CreateIfNotExists($_SWIFT_TicketObject, $_SWIFT->Staff, $_POST['replycontents']);
4327
                }
4328
4329
                if (isset($_POST['optreply_watch']) && $_POST['optreply_watch'] == '1')
4330
                {
4331
                        SWIFT_Ticket::Watch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
4332
                } else {
4333
                        SWIFT_Ticket::UnWatch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
4334
                }
4335
4336
                $_SWIFT_TicketObject->ProcessUpdatePool();
4337
                SWIFT_TicketManager::RebuildCache();
4338
4339
                // Does the new department belong to this staff? if not, we need to jump him back to list!
4340
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
4341
                if (isset($_POST['replydepartmentid']) && !empty($_POST['replydepartmentid']) && !in_array($_POST['replydepartmentid'], $_assignedDepartmentIDList)) {
4342
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
4343
4344
                        return true;
4345
                }
4346
4347
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
4348
                {
4349
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
4350
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
4351
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
4352
4353
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
4354
                        $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
4355
4356
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
4357
                        if (!empty($_nextTicketID))
4358
                        {
4359
                                $this->Load->Method('View', $_nextTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
4360
                        } else {
4361
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
4362
                        }
4363
4364
                }
4365
4366
                return true;
4367
        }
4368
4369
        /**
4370
         * New Ticket Submission Processor
4371
         *
4372
         * @author Varun Shoor
4373
         * @param string $_ticketType The Ticket Type
4374
         * @return bool "true" on Success, "false" otherwise
4375
         * @throws SWIFT_Exception If the Class is not Loaded
4376
         */
4377
        public function NewTicketSubmit($_ticketType)
4378
        {
4379
                $_SWIFT = SWIFT::GetInstance();
4380
4381
                if (!$this->GetIsClassLoaded())
4382
                {
4383
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4384
4385
                        return false;
4386
                } else if ($_ticketType != 'sendmail' && $_ticketType != 'user') {
4387
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4388
                } else if ($_SWIFT->Staff->GetPermission('staff_tcaninsertticket') == '0') {
4389
                        return false;
4390
                }
4391
4392
                /**
4393
                 * ---------------------------------------------
4394
                 * Begin Error Checking
4395
                 * ---------------------------------------------
4396
                 */
4397
                $_POST['tickettype'] = $_ticketType;
4398
4399
                $_POST['departmentid'] = $_POST['newticketdepartmentid'];
4400
4401
                if (trim($_POST['newticketsubject']) == '' || trim($_POST['newticketcontents']) == '')
4402
                {
4403
4404
                        $this->UserInterface->CheckFields('newticketsubject', 'newticketcontents');
4405
4406
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
4407
4408
                        $this->Load->NewTicketForm();
4409
4410
                        return false;
4411
4412
                // Only check TO field for the Send Mail Option
4413
                } else if ($_ticketType == 'sendmail' && (!SWIFT_UserInterface::GetMultipleInputValues('newticketto') ||
4414
                                !_is_array(SWIFT_UserInterface::GetMultipleInputValues('newticketto')) || !$this->_CheckPOSTEmailContainer('newticketto'))) {
4415
4416
                        SWIFT::ErrorField('newticketto');
4417
4418
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
4419
4420
                        $this->Load->NewTicketForm();
4421
4422
                        return false;
4423
4424
                // Check sanity of all properties
4425
                } else if (!isset($_POST['newticketdepartmentid']) || empty($_POST['newticketdepartmentid']) ||
4426
                                !isset($_POST['newticketticketstatusid']) || empty($_POST['newticketticketstatusid']) ||
4427
                                !isset($_POST['newticketownerstaffid']) ||
4428
                                !isset($_POST['newtickettickettypeid']) || empty($_POST['newtickettickettypeid']) ||
4429
                                !isset($_POST['newticketticketpriorityid']) || empty($_POST['newticketticketpriorityid'])) {
4430
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
4431
4432
                        $this->Load->NewTicketForm();
4433
4434
                        return false;
4435
4436
                // Check User ID
4437
                } else if ($_ticketType == 'user' && (!isset($_POST['autocomplete_userid']) || empty($_POST['autocomplete_userid']))) {
4438
                        SWIFT::ErrorField('userid');
4439
4440
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
4441
4442
                        $this->Load->NewTicketForm();
4443
4444
                        return false;
4445
4446
                }
4447
4448
                // Custom Field Check
4449
                $_customFieldCheckResult = $this->CustomFieldManager->Check(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_INSERT,
4450
                                array(SWIFT_CustomFieldGroup::GROUP_STAFFTICKET, SWIFT_CustomFieldGroup::GROUP_STAFFUSERTICKET), SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_POST['newticketdepartmentid']);
4451
                if ($_customFieldCheckResult[0] == false)
4452
                {
4453
                        call_user_func_array(array('SWIFT', 'ErrorField'), $_customFieldCheckResult[1]);
4454
4455
                        $this->UserInterface->Error($this->Language->Get('titlefieldempty'), $this->Language->Get('msgfieldempty'));
4456
4457
                        $this->Load->NewTicketForm();
4458
4459
                        return false;
4460
                }
4461
4462
                // Load the user object for the user based tickets
4463
                $_SWIFT_UserObject = false;
4464
                if ($_ticketType == 'user')
4465
                {
4466
                        $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_POST['autocomplete_userid']));
4467
                        if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded())
4468
                        {
4469
                                throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4470
                        }
4471
                }
4472
4473
4474
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
4475
                $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
4476
                $_templateGroupCache = $_SWIFT->Cache->Get('templategroupcache');
4477
                $_emailQueueID = 0;
4478
                if ($_POST['newticketfrom'] > 0 && isset($_emailQueueCache['list'][$_POST['newticketfrom']]))
4479
                {
4480
                        $_emailQueueID = $_POST['newticketfrom'];
4481
                }
4482
4483
                $_dontSendEmail = false;
4484
                if (!isset($_POST['optnewticket_sendemail']) || (isset($_POST['optnewticket_sendmail']) && $_POST['optnewticket_sendmail'] != '1'))
4485
                {
4486
                        $_dontSendEmail = true;
4487
                }
4488
4489
                $_dispatchAutoResponder = false;
4490
                if ($_ticketType != 'sendmail' && isset($_POST['optnewticket_sendar']) && $_POST['optnewticket_sendar'] == '1')
4491
                {
4492
                        $_dispatchAutoResponder = true;
4493
                }
4494
4495
                $_isPrivate = false;
4496
                if (isset($_POST['optnewticket_private']) && $_POST['optnewticket_private'] == '1')
4497
                {
4498
                        $_dontSendEmail = true;
4499
                        $_isPrivate = true;
4500
                }
4501
4502
                // Create the ticket
4503
                $_creatorFullName = $_creatorEmail = $_phoneNumber = $_destinationEmail = '';
4504
                $_userID = 0;
4505
                $_ticketPhoneType = SWIFT_Ticket::TYPE_DEFAULT;
4506
                $_ticketCreator = SWIFT_Ticket::CREATOR_STAFF;
4507
                $_destinationEmailContainer = self::GetSanitizedEmailList('newticketto');
4508
                $_recurTicketType = SWIFT_TicketRecurrence::TICKETTYPE_ASUSER;
4509
4510
                $_ticketContents = '<div>' . $_POST['newticketcontents'] . '</div>';
4511
                $_ticketDispatchContents = $_POST['newticketcontents'] . SWIFT_CRLF;
4512
4513
                $_ownerStaffID = 0;
4514
                if (isset($_POST['newticketownerstaffid']) && $_POST['newticketownerstaffid'] != 0) {
4515
                        $_ownerStaffID = intval($_POST['newticketownerstaffid']);
4516
                }
4517
4518
                if ($_ticketType == 'sendmail')
4519
                {
4520
                        $_recurTicketType = SWIFT_TicketRecurrence::TICKETTYPE_SENDEMAIL;
4521
                        $_creatorFullName = $_SWIFT->Staff->GetProperty('fullname');
4522
                        $_creatorEmail = $_SWIFT->Staff->GetProperty('email');
4523
4524
                        $_emailQueueContainer = false;
4525
                        if (isset($_emailQueueCache['list'][$_emailQueueID]))
4526
                        {
4527
                                $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
4528
                        }
4529
4530
                        $_templateGroupID = SWIFT_TemplateGroup::GetDefaultGroupID();
4531
4532
                        if (_is_array($_emailQueueContainer) && isset($_templateGroupCache[$_emailQueueContainer['tgroupid']]))
4533
                        {
4534
                                $_templateGroupID = $_emailQueueContainer['tgroupid'];
4535
                        }
4536
4537
                        $_templateGroupContainer = $_templateGroupCache[$_templateGroupID];
4538
                        $_destinationEmail = $_destinationEmailContainer[0];
4539
4540
                        $_userID = SWIFT_Ticket::GetOrCreateUserID($_destinationEmail, $_destinationEmail, $_templateGroupContainer['regusergroupid']);
4541
4542
                        $_ticketCreator = SWIFT_Ticket::CREATOR_STAFF;
4543
                        $_phoneNumber = '';
4544
4545
                        // Retrieve the signature of the staff
4546
                        $_signatureContentsDefault = preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $_SWIFT->Staff->GetProperty('signature'));;
4547
                        if (_is_array($_emailQueueContainer) && isset($_emailQueueContainer['contents'])) {
4548
                                $_signatureContentsDefault .= preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $_emailQueueContainer['contents']);
4549
                        }
4550
4551
                        // First create the ticket post
4552
                        $_ticketContents = $_ticketContents . SWIFT_CRLF . $_signatureContentsDefault;
4553
4554
                } else if ($_ticketType == 'user') {
4555
                        $_recurTicketType = SWIFT_TicketRecurrence::TICKETTYPE_ASUSER;
4556
                        $_creatorFullName = $_SWIFT_UserObject->GetProperty('fullname');
4557
                        $_creatorEmailList = $_SWIFT_UserObject->GetEmailList();
4558
                        $_creatorEmail = $_creatorEmailList[0];
4559
4560
                        $_userID = $_SWIFT_UserObject->GetUserID();
4561
4562
                        if (isset($_POST['optnewticket_isphone']) && $_POST['optnewticket_isphone'] == '1')
4563
                        {
4564
                                $_ticketPhoneType = SWIFT_Ticket::TYPE_PHONE;
4565
                        }
4566
4567
                        $_ticketCreator = SWIFT_Ticket::CREATOR_USER;
4568
                        $_phoneNumber = $_SWIFT_UserObject->GetProperty('phone');
4569
4570
                }
4571
4572
                $_SWIFT_TicketObject = SWIFT_Ticket::Create($_POST['newticketsubject'], $_creatorFullName, $_creatorEmail,
4573
                                                                                                        $_ticketContents, $_ownerStaffID, $_POST['newticketdepartmentid'], $_POST['newticketticketstatusid'],
4574
                                                                                                        $_POST['newticketticketpriorityid'], $_POST['newtickettickettypeid'], $_userID, $_SWIFT->Staff->GetStaffID(),
4575
                                                                                                        $_ticketPhoneType, $_ticketCreator, SWIFT_Ticket::CREATIONMODE_STAFFCP, $_phoneNumber, $_emailQueueID, false,
4576
                                                                                                        $_destinationEmail, true, DATENOW, $_isPrivate);
4577
                $_SWIFT_TicketPostObject = $_SWIFT_TicketObject->GetFirstPostObject();
4578
                $_SWIFT_TicketObject->ProcessPostAttachments($_SWIFT_TicketPostObject, 'newticketattachments');
4579
4580
4581
                // Did the object load up?
4582
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
4583
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4584
                }
4585
4586
                $_signatureContentsDefault = $_signatureContentsHTML = '';
4587
                if ($_ticketType == 'sendmail') {
4588
                        $_signatureContentsDefault = $_SWIFT_TicketObject->GetSignature(false, $_SWIFT->Staff);
4589
                        $_signatureContentsHTML = $_SWIFT_TicketObject->GetSignature(true, $_SWIFT->Staff);
4590
                }
4591
4592
                $_ticketID = $_SWIFT_TicketObject->GetTicketID();
4593
4594
                $this->_ProcessDispatchTab($_SWIFT_TicketObject, 'newticket');
4595
4596
                // Begin Hook: staff_newticket_create
4597
                unset($_hookCode);
4598
                ($_hookCode = SWIFT_Hook::Execute('staff_newticket_create')) ? eval($_hookCode) : false;
4599
                // End Hook
4600
4601
                /*
4602
                 * BUG FIX - Varun Shoor
4603
                 *
4604
                 * SWIFT-303 Staff Replies and Autoresponder are sending wrong template group name in the Support Center URL
4605
                 * SWIFT-1004 Survey e-mail is always sent in English, even if other language is set as default
4606
                 *
4607
                 * Comments: Reset the template group of the ticket
4608
                 */
4609
                if ($_SWIFT_UserObject === false) {
4610
                        $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($_userID));
4611
                }
4612
4613
                if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded()) {
4614
                        $_userTemplateGroupID = $_SWIFT_UserObject->GetTemplateGroupID();
4615
4616
                        /**
4617
                         * BUG FIX - Ravi Sharma <ravi.sharma@kayako.com>
4618
                         *
4619
                         * SWIFT-4268 Issue with ticket recurrence, if ticket is created using 'As a user' option.
4620
                         *
4621
                         * Comments: If user group is not linked with any template then set the default template.
4622
                         */
4623
                        if (!empty($_userTemplateGroupID) && isset($_templateGroupCache[$_userTemplateGroupID])) {
4624
                                $_SWIFT_TicketObject->SetTemplateGroup($_userTemplateGroupID);
4625
                        } else {
4626
                                $_userTemplateGroupID = SWIFT_TemplateGroup::GetDefaultGroupID();
4627
                                $_SWIFT_TicketObject->SetTemplateGroup($_userTemplateGroupID);
4628
                        }
4629
                }
4630
4631
                // We dispatch the autoresponder after creation so that we end up adding all the CC users etc.
4632
                if ($_dispatchAutoResponder)
4633
                {
4634
                        $_SWIFT_TicketObject->DispatchAutoresponder();
4635
                }
4636
4637
                $_isHTML = true;
4638
4639
                $_fromEmailAddress = self::_GetDispatchFromEmail('newticket');
4640
4641
                if ($_POST['newticketcontents'] != '' && $_dontSendEmail == false)
4642
                {
4643
                        // Carry out the email dispatch logic
4644
                        $_SWIFT_TicketEmailDispatchObject = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
4645
                        $_SWIFT_TicketEmailDispatchObject->DispatchStaffReply($_SWIFT->Staff, $_ticketDispatchContents, $_isHTML, $_fromEmailAddress, array($_signatureContentsDefault, $_signatureContentsHTML));
4646
                }
4647
4648
                if (isset($_POST['optnewticket_watch']) && $_POST['optnewticket_watch'] == '1')
4649
                {
4650
                        SWIFT_Ticket::Watch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
4651
                } else {
4652
                        SWIFT_Ticket::UnWatch(array($_SWIFT_TicketObject->GetTicketID()), $_SWIFT->Staff);
4653
                }
4654
4655
                $_SWIFT_TicketObject->ProcessUpdatePool();
4656
                SWIFT_TicketManager::RebuildCache();
4657
4658
                // Activity Log
4659
                SWIFT_StaffActivityLog::AddToLog(sprintf($_SWIFT->Language->Get('log_newticket'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_POST['newticketsubject']),
4660
                                SWIFT_StaffActivityLog::ACTION_INSERT, SWIFT_StaffActivityLog::SECTION_TICKETS, SWIFT_StaffActivityLog::INTERFACE_STAFF);
4661
4662
                // Do we need to add a macro
4663
                $_addMacro = false;
4664
                if (isset($_POST['optnewticket_addmacro']) && $_POST['optnewticket_addmacro'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded())
4665
                {
4666
                        $_addMacro = true;
4667
                }
4668
4669
                // Do we need to add a KB article
4670
                $_addKBArticle = false;
4671
                if (isset($_POST['optnewticket_addkb']) && $_POST['optnewticket_addkb'] == '1' && $_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject->GetIsClassLoaded() && SWIFT_App::IsInstalled(APP_KNOWLEDGEBASE))
4672
                {
4673
                        $_addKBArticle = true;
4674
                }
4675
4676
                // Update Custom Field Values
4677
                $this->CustomFieldManager->Update(SWIFT_CustomFieldManager::MODE_POST, SWIFT_UserInterface::MODE_INSERT,
4678
                                array(SWIFT_CustomFieldGroup::GROUP_STAFFTICKET, SWIFT_CustomFieldGroup::GROUP_STAFFUSERTICKET),
4679
                                SWIFT_CustomFieldManager::CHECKMODE_STAFF, $_SWIFT_TicketObject->GetTicketID(), $_POST['newticketdepartmentid']);
4680
4681
                /**
4682
                 * ---------------------------------------------
4683
                 * RECURRENCE PROCESSING
4684
                 * ---------------------------------------------
4685
                 */
4686
                // Check permission & recurrence type
4687
                if ($_SWIFT->Staff->GetPermission('staff_tcaninsertrecurrence') != '0' && isset($_POST['recurrencetype'])) {
4688
                        $_endType = SWIFT_TicketRecurrence::END_NOEND;
4689
                        if (isset($_POST['recurrence_endtype']) && $_POST['recurrence_endtype'] == SWIFT_TicketRecurrence::END_DATE && GetCalendarDateline($_POST['recurrence_enddateline']) != false) {
4690
                                $_endType = SWIFT_TicketRecurrence::END_DATE;
4691
                        } else if (isset($_POST['recurrence_endtype']) && $_POST['recurrence_endtype'] == SWIFT_TicketRecurrence::END_OCCURENCES && intval($_POST['recurrence_endcount']) > 0) {
4692
                                $_endType = SWIFT_TicketRecurrence::END_OCCURENCES;
4693
                        }
4694
4695
                        // Daily
4696
                        if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_DAILY) {
4697
                                $_intervalStep = intval($_POST['recurrence_daily_step']);
4698
                                $_dailyEveryWeekday = false;
4699
                                if ((empty($_intervalStep) || $_intervalStep < 0) && $_POST['recurrence_daily_type'] == 'default') {
4700
                                        $_intervalStep = 1;
4701
                                }
4702
4703
                                if ($_POST['recurrence_daily_type'] == 'extended') {
4704
                                        $_intervalStep = 0;
4705
                                        $_dailyEveryWeekday = true;
4706
                                }
4707
4708
                                SWIFT_TicketRecurrence::CreateDaily($_SWIFT_TicketObject, $_SWIFT->Staff, $_recurTicketType, $_POST['newticketdepartmentid'], $_POST['newticketownerstaffid'], $_POST['newtickettickettypeid'], $_POST['newticketticketstatusid'], $_POST['newticketticketpriorityid'], $_intervalStep, $_dailyEveryWeekday, GetCalendarDateline($_POST['recurrence_start']), $_endType, GetCalendarDateline($_POST['recurrence_enddateline']), intval($_POST['recurrence_endcount']), $_dontSendEmail, $_dispatchAutoResponder);
4709
4710
                                // Weekly
4711
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_WEEKLY) {
4712
                                $_intervalStep = intval($_POST['recurrence_weekly_step']);
4713
                                if ((empty($_intervalStep) || $_intervalStep < 0)) {
4714
                                        $_intervalStep = 1;
4715
                                }
4716
4717
                                $_isMonday = $_isTuesday = $_isWednesday = $_isThursday = $_isFriday = $_isSaturday = $_isSunday = false;
4718
                                if (isset($_POST['recurrence_weekly_ismonday'])) {
4719
                                        $_isMonday = true;
4720
                                }
4721
4722
                                if (isset($_POST['recurrence_weekly_istuesday'])) {
4723
                                        $_isTuesday = true;
4724
                                }
4725
4726
                                if (isset($_POST['recurrence_weekly_iswednesday'])) {
4727
                                        $_isWednesday = true;
4728
                                }
4729
4730
                                if (isset($_POST['recurrence_weekly_isthursday'])) {
4731
                                        $_isThursday = true;
4732
                                }
4733
4734
                                if (isset($_POST['recurrence_weekly_isfriday'])) {
4735
                                        $_isFriday = true;
4736
                                }
4737
4738
                                if (isset($_POST['recurrence_weekly_issaturday'])) {
4739
                                        $_isSaturday = true;
4740
                                }
4741
4742
                                if (isset($_POST['recurrence_weekly_issunday'])) {
4743
                                        $_isSunday = true;
4744
                                }
4745
4746
                                SWIFT_TicketRecurrence::CreateWeekly($_SWIFT_TicketObject, $_SWIFT->Staff, $_recurTicketType, $_POST['newticketdepartmentid'], $_POST['newticketownerstaffid'], $_POST['newtickettickettypeid'], $_POST['newticketticketstatusid'], $_POST['newticketticketpriorityid'], $_intervalStep, $_isMonday, $_isTuesday, $_isWednesday, $_isThursday, $_isFriday, $_isSaturday, $_isSunday, GetCalendarDateline($_POST['recurrence_start']), $_endType, GetCalendarDateline($_POST['recurrence_enddateline']), intval($_POST['recurrence_endcount']), $_dontSendEmail, $_dispatchAutoResponder);
4747
4748
                                // Monthly
4749
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_MONTHLY) {
4750
                                $_recurrenceMonthlyType  = SWIFT_TicketRecurrence::MONTHLY_DEFAULT;
4751
                                $_monthlyExtendedDay     = 'monday';
4752
                                $_monthlyExtendedDayStep = 'first';
4753
                                $_intervalStep           = 1;
4754
                                $_monthlyDay             = date('d');
4755
4756
                                if ($_POST['recurrence_monthly_type'] == 'extended') {
4757
                                        $_recurrenceMonthlyType  = SWIFT_TicketRecurrence::MONTHLY_EXTENDED;
4758
                                        $_monthlyExtendedDay     = $_POST['recurrence_monthly_extday'];
4759
                                        $_monthlyExtendedDayStep = $_POST['recurrence_monthly_extdaystep'];
4760
4761
                                        $_intervalStep = intval($_POST['recurrence_monthly_stepext']);
4762
                                } else {
4763
                                        $_intervalStep = intval($_POST['recurrence_monthly_step']);
4764
                                        if (intval($_POST['recurrence_monthly_day']) != '0' && intval($_POST['recurrence_monthly_day']) > 0) {
4765
                                                $_monthlyDay = intval($_POST['recurrence_monthly_day']);
4766
                                        }
4767
                                }
4768
4769
                                if ((empty($_intervalStep) || $_intervalStep < 0)) {
4770
                                        $_intervalStep = 1;
4771
                                }
4772
4773
                                SWIFT_TicketRecurrence::CreateMonthly($_SWIFT_TicketObject, $_SWIFT->Staff, $_recurTicketType, $_POST['newticketdepartmentid'], $_POST['newticketownerstaffid'], $_POST['newtickettickettypeid'], $_POST['newticketticketstatusid'], $_POST['newticketticketpriorityid'], $_intervalStep, $_recurrenceMonthlyType, $_monthlyDay, $_monthlyExtendedDay, $_monthlyExtendedDayStep, GetCalendarDateline($_POST['recurrence_start']), $_endType, GetCalendarDateline($_POST['recurrence_enddateline']), intval($_POST['recurrence_endcount']), $_dontSendEmail, $_dispatchAutoResponder);
4774
4775
                                // Yearly
4776
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_YEARLY) {
4777
                                $_yearlyType            = SWIFT_TicketRecurrence::YEARLY_DEFAULT;
4778
                                $_yearlyMonthDay        = gmdate('d', DATENOW);
4779
                                $_yearlyMonth           = gmdate('n', DATENOW);
4780
                                $_yearlyExtendedDay     = 'first';
4781
                                $_yearlyExtendedDayStep = 'monday';
4782
                                $_yearlyExtendedMonth   = $_yearlyMonth;
4783
4784
                                if ($_POST['recurrence_yearly_type'] == 'extended') {
4785
                                        $_yearlyType            = SWIFT_TicketRecurrence::YEARLY_EXTENDED;
4786
                                        $_yearlyExtendedDay     = $_POST['recurrence_yearly_extday'];
4787
                                        $_yearlyExtendedDayStep = $_POST['recurrence_yearly_extdaystep'];
4788
                                        $_yearlyExtendedMonth   = $_POST['recurrence_yearly_extmonth'];
4789
                                } else {
4790
                                        $_yearlyMonthDay = intval($_POST['recurrence_yearly_monthday']);
4791
                                        if (empty($_yearlyMonthDay) || $_yearlyMonthDay <= 0) {
4792
                                                $_yearlyMonthDay = gmdate('d', DATENOW);
4793
                                        }
4794
4795
                                        $_yearlyMonth = intval($_POST['recurrence_yearly_month']);
4796
                                }
4797
4798
                                SWIFT_TicketRecurrence::CreateYearly($_SWIFT_TicketObject, $_SWIFT->Staff, $_recurTicketType, $_POST['newticketdepartmentid'], $_POST['newticketownerstaffid'], $_POST['newtickettickettypeid'], $_POST['newticketticketstatusid'], $_POST['newticketticketpriorityid'], $_yearlyType, $_yearlyMonth, $_yearlyMonthDay, $_yearlyExtendedDay, $_yearlyExtendedDayStep, $_yearlyExtendedMonth, GetCalendarDateline($_POST['recurrence_start']), $_endType, GetCalendarDateline($_POST['recurrence_enddateline']), intval($_POST['recurrence_endcount']), $_dontSendEmail, $_dispatchAutoResponder);
4799
                        }
4800
                }
4801
4802
                // Does the new department belong to this staff? if not, we need to jump him back to list!
4803
                $_assignedDepartmentIDList = $_SWIFT->Staff->GetAssignedDepartments();
4804
                if (isset($_POST['newticketdepartmentid']) && !empty($_POST['newticketdepartmentid']) &&
4805
                                !in_array($_POST['newticketdepartmentid'], $_assignedDepartmentIDList)) {
4806
                        if ($_addMacro)
4807
                        {
4808
                                $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', -1, -1, -1, $_addKBArticle);
4809
                        } else if ($_addKBArticle) {
4810
                                $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'inbox', -1, -1, -1);
4811
                        } else {
4812
                                $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
4813
                        }
4814
4815
                        return true;
4816
                }
4817
4818
                if ($_addMacro)
4819
                {
4820
                        $this->Load->Controller('MacroReply')->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', -1, -1, -1, $_addKBArticle);
4821
                } else if ($_addKBArticle) {
4822
                        $this->Load->Controller('Article', APP_KNOWLEDGEBASE)->InsertTicket($_SWIFT_TicketPostObject, $_ticketID, 'viewticket', -1, -1, -1);
4823
                } else {
4824
                        $this->Load->Method('View', $_SWIFT_TicketObject->GetTicketID(), 'inbox', -1, -1, -1, 0);
4825
                }
4826
4827
                return true;
4828
        }
4829
4830
        /**
4831
         * Check validity of emails in  the input box
4832
         *
4833
         * @author Varun Shoor
4834
         * @param string $_fieldName The Field Name to Check On
4835
         * @return bool "true" on Success, "false" otherwise
4836
         * @throws SWIFT_Exception If the Class is not Loaded
4837
         */
4838
        protected function _CheckPOSTEmailContainer($_fieldName)
4839
        {
4840
                if (!$this->GetIsClassLoaded())
4841
                {
4842
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4843
4844
                        return false;
4845
                }
4846
4847
                $_emailCount = 0;
4848
4849
                $_postEmailValues = SWIFT_UserInterface::GetMultipleInputValues($_fieldName);
4850
                if (_is_array($_postEmailValues))
4851
                {
4852
                        foreach ($_postEmailValues as $_key => $_val)
4853
                        {
4854
                                if (!IsEmailValid($_val))
4855
                                {
4856
                                        return false;
4857
                                } else {
4858
                                        $_emailCount++;
4859
                                }
4860
                        }
4861
                }
4862
4863
                if (!$_emailCount)
4864
                {
4865
                        return false;
4866
                }
4867
4868
                return true;
4869
        }
4870
4871
        /**
4872
         * Ticket Dispatch Window
4873
         *
4874
         * @author Varun Shoor
4875
         * @param int $_ticketID The Ticket ID
4876
         * @param string $_listType (OPTIONAL) The List Type
4877
         * @param int $_departmentID (OPTIONAL) The Department ID
4878
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
4879
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
4880
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
4881
         * @return bool "true" on Success, "false" otherwise
4882
         * @throws SWIFT_Exception If the Class is not Loaded
4883
         */
4884
        public function Dispatch($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
4885
                        $_ticketLimitOffset = 0)
4886
        {
4887
                $_SWIFT = SWIFT::GetInstance();
4888
4889
                if (!$this->GetIsClassLoaded())
4890
                {
4891
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4892
4893
                        return false;
4894
                } else if (empty($_ticketID)) {
4895
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4896
4897
                        return false;
4898
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
4899
                        return false;
4900
                }
4901
4902
                /*
4903
                 * BUG FIX - Parminder Singh
4904
                 *
4905
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
4906
                 *
4907
                 * Comments: If current ticket id is merged with other tickets
4908
                 */
4909
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
4910
4911
                // Did the object load up?
4912
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
4913
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4914
                }
4915
4916
                // Check permission
4917
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
4918
                        echo $this->Language->Get('msgnoperm');
4919
4920
                        return false;
4921
                }
4922
4923
                SWIFT::Set('ticketurlsuffix', $_listType . '/' . $_departmentID . '/' . $_ticketStatusID . '/' . $_ticketTypeID . '/' . $_ticketLimitOffset);
4924
4925
                $this->UserInterface->Header($this->Language->Get('tickets') . ' > ' . $this->Language->Get('dispatch'), self::MENU_ID, self::NAVIGATION_ID);
4926
                $this->View->RenderDispatchForm(SWIFT_UserInterface::MODE_INSERT, $_SWIFT_TicketObject);
4927
                $this->UserInterface->Footer();
4928
4929
                return true;
4930
        }
4931
4932
        /**
4933
         * Ticket Dispatch Submission
4934
         *
4935
         * @author Varun Shoor
4936
         * @param int $_ticketID The Ticket ID
4937
         * @param string $_listType (OPTIONAL) The List Type
4938
         * @param int $_departmentID (OPTIONAL) The Department ID
4939
         * @param int $_ticketStatusID (OPTIONAL) The Ticket Status ID
4940
         * @param int $_ticketTypeID (OPTIONAL) The Ticket Type ID
4941
         * @param int $_ticketLimitOffset (OPTIONAL) The offset to display ticket posts on
4942
         * @return bool "true" on Success, "false" otherwise
4943
         * @throws SWIFT_Exception If the Class is not Loaded
4944
         */
4945
        public function DispatchSubmit($_ticketID, $_listType = 'inbox', $_departmentID = -1, $_ticketStatusID = -1, $_ticketTypeID = -1,
4946
                        $_ticketLimitOffset = 0)
4947
        {
4948
                $_SWIFT = SWIFT::GetInstance();
4949
4950
                if (!$this->GetIsClassLoaded())
4951
                {
4952
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
4953
4954
                        return false;
4955
                } else if (empty($_ticketID)) {
4956
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4957
4958
                        return false;
4959
                } else if ($_SWIFT->Staff->GetPermission('staff_tcanupdateticket') == '0') {
4960
                        return false;
4961
                }
4962
4963
                /*
4964
                 * BUG FIX - Parminder Singh
4965
                 *
4966
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
4967
                 *
4968
                 * Comments: If current ticket id is merged with other tickets
4969
                 */
4970
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
4971
4972
                // Did the object load up?
4973
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
4974
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
4975
                }
4976
4977
                // Check permission
4978
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
4979
                        echo $this->Language->Get('msgnoperm');
4980
4981
                        return false;
4982
                }
4983
4984
                $_SWIFT_TicketViewObject = SWIFT_TicketViewRenderer::GetDefaultTicketViewObject($_departmentID);
4985
4986
                $_nextTicketID = false;
4987
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
4988
                        $_nextTicketID = SWIFT_TicketViewRenderer::GetNextPreviousTicketID($_SWIFT_TicketObject, 'next', $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
4989
                }
4990
4991
                $_staffCache = $this->Cache->Get('staffcache');
4992
4993
                if (!empty($_POST['dispatchstaffid']) && isset($_staffCache[$_POST['dispatchstaffid']]))
4994
                {
4995
                        $_SWIFT_TicketObject->SetOwner($_POST['dispatchstaffid']);
4996
                }
4997
4998
                /*
4999
                 * BUG FIX - Abhishek Mittal
5000
                 *
5001
                 * SWIFT-3835: Incorrect SLA plan gets linked with the ticket when ticket is moved from a resolved status to unresolved status
5002
                 *
5003
                 * Comments: Update reply due time only in case if SLA plan changed
5004
                 */
5005
                $_SWIFT_TicketObject->ExecuteSLA(false, true, false);
5006
5007
                if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TICKET)
5008
                {
5009
                        $this->Load->Method('View', $_ticketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
5010
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_ACTIVETICKETLIST) {
5011
                        $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
5012
5013
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_TOPTICKETLIST) {
5014
                        $this->Load->Controller('Manage')->Redirect('inbox', -1, -1, -1);
5015
5016
                } else if ($_SWIFT_TicketViewObject->GetProperty('afterreplyaction') == SWIFT_TicketView::AFTERREPLY_NEXTTICKET) {
5017
                        if (!empty($_nextTicketID))
5018
                        {
5019
                                $this->Load->Method('View', $_nextTicketID, $_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketLimitOffset);
5020
                        } else {
5021
                                $this->Load->Controller('Manage')->Redirect($_listType, $_departmentID, $_ticketStatusID, $_ticketTypeID);
5022
                        }
5023
5024
                }
5025
                return true;
5026
        }
5027
5028
        /**
5029
         * Ticket Rating Handler
5030
         *
5031
         * @author Varun Shoor
5032
         * @param int $_ticketID The Ticket ID
5033
         * @return bool "true" on Success, "false" otherwise
5034
         * @throws SWIFT_Exception If the Class is not Loaded
5035
         */
5036
        public function Rating($_ticketID)
5037
        {
5038
                $_SWIFT = SWIFT::GetInstance();
5039
5040
                if (!$this->GetIsClassLoaded())
5041
                {
5042
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5043
5044
                        return false;
5045
                } else if (empty($_ticketID)) {
5046
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5047
5048
                        return false;
5049
                } else if (!isset($_POST['ratingid']) || empty($_POST['ratingid']) || !isset($_POST['ratingvalue'])) {
5050
                        return false;
5051
5052
                } else if ($_SWIFT->Staff->GetPermission('staff_canviewratings') == '0' || $_SWIFT->Staff->GetPermission('staff_canupdateratings') == '0') {
5053
                        return false;
5054
                }
5055
5056
                /*
5057
                 * BUG FIX - Parminder Singh
5058
                 *
5059
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
5060
                 *
5061
                 * Comments: If current ticket id is merged with other tickets
5062
                 */
5063
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
5064
5065
                // Did the object load up?
5066
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
5067
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5068
                }
5069
5070
                // Check permission
5071
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
5072
                        echo $this->Language->Get('msgnoperm');
5073
5074
                        return false;
5075
                }
5076
5077
                $_SWIFT_RatingObject = new SWIFT_Rating(intval($_POST['ratingid']));
5078
                if (!$_SWIFT_RatingObject instanceof SWIFT_Rating || !$_SWIFT_RatingObject->GetIsClassLoaded())
5079
                {
5080
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5081
                }
5082
5083
                SWIFT_RatingResult::CreateOrUpdateIfExists($_SWIFT_RatingObject, $_SWIFT_TicketObject->GetTicketID(), $_POST['ratingvalue'], SWIFT_RatingResult::CREATOR_STAFF, $_SWIFT->Staff->GetStaffID());
5084
5085
                $_SWIFT_TicketObject->MarkHasRatings();
5086
5087
                return true;
5088
        }
5089
5090
5091
        /**
5092
         * Ticket Post Rating Handler
5093
         *
5094
         * @author Varun Shoor
5095
         * @param int $_ticketID The Ticket ID
5096
         * @param int $_ticketPostID The Ticket Post ID
5097
         * @return bool "true" on Success, "false" otherwise
5098
         * @throws SWIFT_Exception If the Class is not Loaded
5099
         */
5100
        public function RatingPost($_ticketID, $_ticketPostID)
5101
        {
5102
                $_SWIFT = SWIFT::GetInstance();
5103
5104
                if (!$this->GetIsClassLoaded())
5105
                {
5106
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5107
5108
                        return false;
5109
                } else if (empty($_ticketID)) {
5110
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5111
5112
                        return false;
5113
                } else if (!isset($_POST['ratingid']) || empty($_POST['ratingid']) || !isset($_POST['ratingvalue'])) {
5114
                        return false;
5115
5116
                } else if ($_SWIFT->Staff->GetPermission('staff_canviewratings') == '0' || $_SWIFT->Staff->GetPermission('staff_canupdateratings') == '0') {
5117
                        return false;
5118
                }
5119
5120
                /*
5121
                 * BUG FIX - Parminder Singh
5122
                 *
5123
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
5124
                 *
5125
                 * Comments: If current ticket id is merged with other tickets
5126
                 */
5127
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
5128
5129
                // Did the object load up?
5130
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
5131
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5132
                }
5133
5134
                // Check permission
5135
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff)) {
5136
                        echo $this->Language->Get('msgnoperm');
5137
5138
                        return false;
5139
                }
5140
5141
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
5142
                if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost && !$_SWIFT_TicketPostObject->GetIsClassLoaded() || $_SWIFT_TicketPostObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID())
5143
                {
5144
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5145
                }
5146
5147
                $_SWIFT_RatingObject = new SWIFT_Rating(intval($_POST['ratingid']));
5148
                if (!$_SWIFT_RatingObject instanceof SWIFT_Rating || !$_SWIFT_RatingObject->GetIsClassLoaded())
5149
                {
5150
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5151
                }
5152
5153
                SWIFT_RatingResult::CreateOrUpdateIfExists($_SWIFT_RatingObject, $_SWIFT_TicketPostObject->GetTicketPostID(), $_POST['ratingvalue'], SWIFT_RatingResult::CREATOR_STAFF, $_SWIFT->Staff->GetStaffID());
5154
5155
                $_SWIFT_TicketObject->MarkHasRatings();
5156
5157
                return true;
5158
        }
5159
5160
        /**
5161
         * Process the follow-up POST data and create a follow up entry
5162
         *
5163
         * @author Varun Shoor
5164
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
5165
         * @param string $_prefix The Prefix for Variables (to prevent race errors)
5166
         * @param SWIFT_TicketFollowUp (OPTIONAL) The SWIFT_TicketFollowUp Object for Updates
5167
         * @return bool "true" on Success, "false" otherwise
5168
         * @throws SWIFT_Exception If Invalid Data is Provided
5169
         */
5170
        public function _ProcessFollowUp(SWIFT_Ticket $_SWIFT_TicketObject, $_prefix, SWIFT_TicketFollowUp $_SWIFT_TicketFollowUpObject = null)
5171
        {
5172
                $_SWIFT = SWIFT::GetInstance();
5173
5174
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded())
5175
                {
5176
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5177
                } else if (!isset($_POST[$_prefix . 'followuptype'])) {
5178
                        return false;
5179
                }
5180
5181
                $_followUpDate = false;
5182
                if ($_POST[$_prefix . 'followuptype'] == 'custom')
5183
                {
5184
                        $_followUpDate = GetDateFieldTimestamp($_prefix . 'followupcustomvalue');
5185
                } else {
5186
                        $_followUpDate = self::_ReturnFollowUpDate($_POST[$_prefix . 'followuptype'], $_POST[$_prefix . 'followupvalue']);
5187
                }
5188
5189
                if (empty($_followUpDate))
5190
                {
5191
                        return false;
5192
                }
5193
5194
                // Now that we have the follow up execution date, we process the properties
5195
                $_executionDateline = $_followUpDate;
5196
5197
                $_doChangeProperties = false;
5198
                $_ownerStaffID = $_departmentID = $_ticketStatusID = $_ticketTypeID = $_ticketPriorityID = 0;
5199
5200
                if (isset($_POST[$_prefix . 'dochangeproperties']) && $_POST[$_prefix . 'dochangeproperties'] == 1)
5201
                {
5202
                        $_doChangeProperties = true;
5203
                        $_ownerStaffID = intval($_POST[$_prefix . 'ownerstaffid']);
5204
                        $_departmentID = intval($_POST[$_prefix . 'departmentid']);
5205
                        $_ticketStatusID = intval($_POST[$_prefix . 'ticketstatusid']);
5206
                        $_ticketTypeID = intval($_POST[$_prefix . 'tickettypeid']);
5207
                        $_ticketPriorityID = intval($_POST[$_prefix . 'ticketpriorityid']);
5208
                }
5209
5210
                $_doChangeDueDateline = false;
5211
                $_dueDateline = $_resolutionDueDateline = 0;
5212
                $_timeWorked = $_timeBillable = 0;
5213
5214
                $_doNote = false;
5215
                $_noteType = 'ticket';
5216
                $_noteColor = 1;
5217
                $_ticketNotes = '';
5218
                if (isset($_POST[$_prefix . 'donote']) && $_POST[$_prefix . 'donote'] == 1)
5219
                {
5220
                        $_doNote = true;
5221
                        $_noteType = $_POST[$_prefix . 'notetype'];
5222
                        $_noteColor = intval($_POST['notecolor_' . $_prefix . 'ticketnotes']);
5223
                        $_ticketNotes = $_POST[$_prefix . 'ticketnotes'];
5224
                }
5225
5226
                $_doReply = false;
5227
                $_replyContents = '';
5228
                if (isset($_POST[$_prefix . 'doreply']) && $_POST[$_prefix . 'doreply'] == 1)
5229
                {
5230
                        $_doReply = true;
5231
5232
                        /*
5233
                         * BUG FIX - Varun Shoor
5234
                         *
5235
                         * SWIFT-1508 Signatures does not append on ticket, if ticket is replied using 'Follow-Up' tab
5236
                         *
5237
                         * Comments: None
5238
                         */
5239
                        $_signatureContentsDefault = preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $_SWIFT->Staff->GetProperty('signature'));
5240
                        $_replyContents = $_POST[$_prefix . 'replycontents'];
5241
5242
                        if (!empty($_signatureContentsDefault)) {
5243
                    $_replyContents = $_POST[$_prefix . 'replycontents'] . SWIFT_CRLF . $_signatureContentsDefault;
5244
                        }
5245
                }
5246
5247
                $_doForward = false;
5248
                $_forwardEmailTo = '';
5249
                $_forwardContents = '';
5250
                if (isset($_POST[$_prefix . 'doforward']) && $_POST[$_prefix . 'doforward'] == '1')
5251
                {
5252
                        $_forwardEmailToContainer = self::GetSanitizedEmailList($_prefix . 'to');
5253
5254
                        if (_is_array($_forwardEmailToContainer))
5255
                        {
5256
                                $_doForward = true;
5257
                                $_forwardEmailTo = $_forwardEmailToContainer[0];
5258
                                $_forwardContents = $_POST[$_prefix . 'forwardcontents'];
5259
                        }
5260
                }
5261
5262
                if ($_SWIFT_TicketFollowUpObject instanceof SWIFT_TicketFollowUp && $_SWIFT_TicketFollowUpObject->GetIsClassLoaded())
5263
                {
5264
                        $_SWIFT_TicketFollowUpObject->Update($_SWIFT_TicketObject, $_executionDateline,
5265
                        $_doChangeProperties, $_ownerStaffID, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketPriorityID,
5266
                        $_doChangeDueDateline, $_dueDateline, $_resolutionDueDateline,
5267
                        $_timeWorked, $_timeBillable,
5268
                        $_doNote, $_noteType, $_noteColor, $_ticketNotes,
5269
                        $_doReply, $_replyContents,
5270
                        $_doForward, $_forwardEmailTo, $_forwardContents,
5271
                        $_SWIFT->Staff);
5272
                } else {
5273
                        SWIFT_TicketFollowUp::Create($_SWIFT_TicketObject, $_executionDateline,
5274
                                $_doChangeProperties, $_ownerStaffID, $_departmentID, $_ticketStatusID, $_ticketTypeID, $_ticketPriorityID,
5275
                                $_doChangeDueDateline, $_dueDateline, $_resolutionDueDateline,
5276
                                $_timeWorked, $_timeBillable,
5277
                                $_doNote, $_noteType, $_noteColor, $_ticketNotes,
5278
                                $_doReply, $_replyContents,
5279
                                $_doForward, $_forwardEmailTo, $_forwardContents,
5280
                                $_SWIFT->Staff);
5281
5282
                }
5283
5284
                $_SWIFT_TicketObject->RebuildProperties();
5285
5286
                return true;
5287
        }
5288
5289
        /**
5290
         * Return a UNIX Timestamp for Follow Up
5291
         *
5292
         * @author Varun Shoor
5293
         * @param string $_followUpType The Follow-Up Type
5294
         * @param string $_followUpValue The Follow-Up Value
5295
         * @return bool "true" on Success, "false" otherwise
5296
         * @throws SWIFT_Exception If Invalid Data is Provided
5297
         */
5298
        static public function _ReturnFollowUpDate($_followUpType, $_followUpValue)
5299
        {
5300
                $_SWIFT = SWIFT::GetInstance();
5301
5302
                switch ($_followUpType)
5303
                {
5304
                        case 'minutes':
5305
                                return DATENOW+(intval($_followUpValue)*60);
5306
                                break;
5307
                        case 'hours':
5308
                                return DATENOW+(intval($_followUpValue)*60*60);
5309
                                break;
5310
                        case 'days':
5311
                                return DATENOW+(intval($_followUpValue)*60*60*24);
5312
                                break;
5313
                        case 'weeks':
5314
                                return DATENOW+(intval($_followUpValue)*60*60*24*7);
5315
                                break;
5316
                        case 'months':
5317
                                return DATENOW+(intval($_followUpValue)*60*60*24*30);
5318
                                break;
5319
                        case 'custom':
5320
                                return strtotime($_followUpValue);
5321
                                break;
5322
                        default:
5323
                                return false;
5324
                                break;
5325
                }
5326
5327
                return false;
5328
        }
5329
5330
        /**
5331
         * Split a ticket
5332
         *
5333
         * @author Simaranjit Singh
5334
         *
5335
         * @param int $_ticketID
5336
         *
5337
         * @return bool
5338
         * @throws SWIFT_Exception If the Class is not Loaded OR If Access Denied
5339
         */
5340
        public function SplitTicket($_ticketID)
5341
        {
5342
                if (!$this->GetIsClassLoaded()) {
5343
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5344
                }
5345
5346
                $_SWIFT = SWIFT::GetInstance();
5347
5348
                // Check permission
5349
                if ($_SWIFT->Staff->GetPermission('staff_tcansplitticket') == '0') {
5350
                        throw new SWIFT_Exception(SWIFT_NOPERMISSION);
5351
                }
5352
5353
                return $this->View->RenderSplitOrDuplicate($_ticketID, SWIFT_Ticket::MODE_SPLIT);
5354
        }
5355
5356
        /**
5357
         * Duplicate a ticket
5358
         *
5359
         * @author Simaranjit Singh
5360
         *
5361
         * @param int $_ticketID
5362
         *
5363
         * @return bool
5364
         * @throws SWIFT_Exception If the Class is not Loaded OR If Access Denied
5365
         */
5366
        public function DuplicateTicket($_ticketID)
5367
        {
5368
                if (!$this->GetIsClassLoaded()) {
5369
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5370
                }
5371
5372
                $_SWIFT = SWIFT::GetInstance();
5373
5374
                // Check permission
5375
                if ($_SWIFT->Staff->GetPermission('staff_tcanduplicateticket') == '0') {
5376
                        throw new SWIFT_Exception(SWIFT_NOPERMISSION);
5377
                }
5378
5379
                return $this->View->RenderSplitOrDuplicate($_ticketID, SWIFT_Ticket::MODE_DUPLICATE);
5380
        }
5381
5382
        /**
5383
         * Split or copy ticket submit
5384
         *
5385
         * @author Simaranjit Singh
5386
         *
5387
         * @return bool
5388
         * @throws SWIFT_Exception If the Class is not Loaded OR If Access Denied OR If Invalid Data is Provided
5389
         */
5390
        public function SplitOrDuplicateSubmit()
5391
        {
5392
                $_SWIFT = SWIFT::GetInstance();
5393
5394
                if (!$this->GetIsClassLoaded()) {
5395
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5396
                }
5397
5398
                SWIFT_Ticket::LoadLanguageTable();
5399
5400
                $_oldTicketID     = intval($_POST['ticketid']);
5401
                $_oldTicketPostID = intval($_POST['splitat']);
5402
                $_operationMode   = intval($_POST['operationmode']);
5403
5404
                if (($_operationMode == SWIFT_TICKET::MODE_SPLIT && $_SWIFT->Staff->GetPermission('staff_tcansplitticket') == '0') || ($_operationMode == SWIFT_TICKET::MODE_DUPLICATE && $_SWIFT->Staff->GetPermission('staff_tcanduplicateticket') == '0')) {
5405
                        throw new SWIFT_Exception(SWIFT_NOPERMISSION);
5406
                } else if ($_operationMode != SWIFT_TICKET::MODE_SPLIT && $_operationMode != SWIFT_TICKET::MODE_DUPLICATE) {
5407
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5408
                }
5409
5410
                $_phrase = IIF($_operationMode == SWIFT_TICKET::MODE_SPLIT, 'split', 'duplicate');
5411
5412
                $_TicketOld = new SWIFT_Ticket(new SWIFT_DataID($_oldTicketID));
5413
5414
                if (!$_TicketOld instanceof SWIFT_Ticket || !$_TicketOld->GetIsClassLoaded()) {
5415
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5416
                }
5417
5418
                $_TicketPostOld = new SWIFT_TicketPost(new SWIFT_DataID($_oldTicketPostID));
5419
5420
                if (!$_TicketPostOld instanceof SWIFT_TicketPost && !$_TicketPostOld->GetIsClassLoaded()) {
5421
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5422
                }
5423
5424
                // Get the dateline for the post from which we're going to split or copy.
5425
                $_dateline = $_TicketPostOld->Get('dateline');
5426
5427
                if ($_dateline > 0) {
5428
                        // Single transaction.
5429
                        $_SWIFT->Database->StartTrans();
5430
5431
                        $_TicketNew = SWIFT_Ticket::Create($_POST['newtitle'], $_TicketOld->Get('fullname'), $_TicketOld->Get('email'), 'DeleteMe', $_TicketOld->Get('ownerstaffid'),
5432
                                $_TicketOld->Get('departmentid'), $_TicketOld->Get('ticketstatusid'), $_TicketOld->Get('priorityid'), $_TicketOld->Get('tickettypeid'),
5433
                                $_TicketOld->Get('userid'), $_SWIFT->Staff->GetStaffID(), $_TicketOld->Get('tickettype'), SWIFT_TicketAuditLog::CREATOR_STAFF,
5434
                                $_TicketOld->Get('creationmode'), '', 0, true, $_TicketOld->Get('replyto'), false);
5435
5436
                        $_TicketNew->SetTemplateGroup($_TicketOld->Get('tgroupid'));
5437
5438
                        $_newTicketID = $_TicketNew->GetTicketID();
5439
5440
                        // Get rid of the ticket post that's created as part of creating the ticket.
5441
                        SWIFT_TicketPost::DeleteOnTicket(array($_newTicketID));
5442
5443
                        // Find and add any additional recipients.
5444
                        $_ticketRecipientContainer = SWIFT_TicketRecipient::RetrieveOnTicket($_TicketOld);
5445
5446
                        if (_is_array($_ticketRecipientContainer)) {
5447
                                foreach ($_ticketRecipientContainer as $_recipientType => $_recipientName) {
5448
                                        SWIFT_TicketRecipient::Create($_TicketNew, $_recipientType, $_recipientName);
5449
                                }
5450
                        }
5451
5452
                        // Set up a bulk copy.
5453
                        if ($_operationMode == SWIFT_TICKET::MODE_DUPLICATE) {
5454
                                $_ticketPostContainer = $_TicketOld->GetTicketPosts(false, false, 'ASC');
5455
5456
                                // Copy the posts first.
5457
                                foreach ($_ticketPostContainer as $_ticketPostID => $_TicketPost) {
5458
5459
                                        // If this post is one that we're meant to copy...
5460
                                        if ($_TicketPost->GetTicketPostID() >= $_oldTicketPostID) {
5461
                                                $_creatorType = $_TicketPost->Get('creator');
5462
5463
                                                $_newTicketPostID = SWIFT_TicketPost::Create($_TicketNew, $_TicketPost->Get('fullname'), $_TicketPost->Get('email'), $_TicketPost->Get('contents'),
5464
                                                        $_creatorType, $_TicketPost->Get(IIF($_creatorType == SWIFT_Ticket::CREATOR_CLIENT, 'userid', 'staffid')), $_TicketPost->Get('creationmode'),
5465
                                                        $_TicketPost->Get('subject'), $_TicketPost->Get('emailto'), $_TicketPost->Get('ishtml'), $_TicketPost->Get('isthirdparty'),
5466
                                                        $_TicketPost->Get('issurveycomment'), $_TicketPost->Get('dateline'));
5467
5468
                                                if (!empty($_newTicketPostID)) {
5469
                                                        $_ticketAttachmentContainer = $_TicketPost->RetrieveAttachments($_TicketOld);
5470
5471
                                                        $_ticketAttachmentIDList = array_keys($_ticketAttachmentContainer);
5472
5473
                                                        if (_is_array($_ticketAttachmentIDList)) {
5474
                                                                $_TicketPostNew = new SWIFT_TicketPost(new SWIFT_DataID($_newTicketPostID));
5475
5476
                                                                foreach ($_ticketAttachmentIDList as $_ticketAttachmentID) {
5477
                                                                        $_Attachment = new SWIFT_Attachment($_ticketAttachmentID);
5478
5479
                                                                        if ($_Attachment instanceof SWIFT_Attachment) {
5480
                                                                                SWIFT_Attachment::CloneOnTicket($_TicketNew, $_TicketPostNew, $_Attachment)->SetDate($_Attachment->GetProperty('dateline'));
5481
5482
                                                                                unset($_Attachment);
5483
                                                                        }
5484
                                                                }
5485
5486
                                                                unset($_TicketPostNew);
5487
                                                        }
5488
                                                } else {
5489
                                                        SWIFT::Error($_SWIFT->Language->Get('ticketsplitter'), $_SWIFT->Language->Get('no_such_post'));
5490
5491
                                                        $_SWIFT->Database->Rollback();
5492
5493
                                                        return false;
5494
                                                }
5495
                                        }
5496
                                }
5497
5498
                                // Retrieve ticket notes
5499
                                $_ticketNoteContainer = $_TicketOld->RetrieveNotes();
5500
5501
                                foreach ($_ticketNoteContainer as $_ticketNoteID => $_ticketNote) {
5502
5503
                                        // Create a copy of the note.
5504
                                        $_newTicketNoteID = SWIFT_TicketNote::Create($_TicketNew, $_ticketNote['forstaffid'], $_ticketNote['staffid'], $_ticketNote['staffname'], $_ticketNote['note'], $_ticketNote['notecolor']);
5505
5506
                                        $_TicketNote = new SWIFT_TicketNote($_newTicketNoteID);
5507
5508
                                        $_TicketNote->UpdatePool('dateline', $_ticketNote['dateline']);
5509
                                        $_TicketNote->ProcessUpdatePool();
5510
                                }
5511
                        } else {
5512
                                $_TicketSplitManager = new SWIFT_TicketSplitManager();
5513
                                $_TicketSplitManager->SetFrom($_oldTicketID)->SetTo($_newTicketID)->SetStartDateline($_dateline)->Split();
5514
                        }
5515
5516
                        $_ticketWatcherContainer = SWIFT_TicketWatcher::RetrieveOnTicket($_TicketOld);
5517
5518
                        foreach ($_ticketWatcherContainer as $_ticketWatcherStaffID => $_ticketWatcherList) {
5519
                                $_ticketWatcherDateline = $_ticketWatcherList['dateline'];
5520
5521
                                $_StaffAsWatcher = new SWIFT_Staff(new SWIFT_DataID($_ticketWatcherStaffID));
5522
5523
                                if (!$_StaffAsWatcher instanceof SWIFT_Staff || !$_StaffAsWatcher->GetIsClassLoaded()) {
5524
                                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5525
                                }
5526
5527
                                $_ticketWatcherID = SWIFT_TicketWatcher::Create($_TicketNew, $_StaffAsWatcher);
5528
5529
                                $_TicketWatcher = new SWIFT_TicketWatcher($_ticketWatcherID);
5530
5531
                                $_TicketWatcher->UpdatePool('dateline', $_ticketWatcherDateline);
5532
                                $_TicketWatcher->ProcessUpdatePool();
5533
                        }
5534
5535
                        // Create something in swticketauditlogs to record this split/copy.
5536
                        $_lastTicketPostContainer = $_SWIFT->Database->QueryFetch("SELECT MAX(ticketpostid) AS ticketpostid FROM " . TABLE_PREFIX . SWIFT_TicketPost::TABLE_NAME . "
5537
                                                                                                                                           WHERE ticketid = " . intval($_oldTicketID));
5538
5539
                        if (is_array($_lastTicketPostContainer) && !empty($_lastTicketPostContainer['ticketpostid'])) {
5540
                                $_TicketPost = new SWIFT_TicketPost(new SWIFT_DataID($_lastTicketPostContainer['ticketpostid']));
5541
5542
                                SWIFT_TicketAuditLog::Create($_TicketOld, $_TicketPost, SWIFT_TicketAuditLog::CREATOR_STAFF, $_SWIFT->Staff->GetStaffID(), $_SWIFT->Staff->GetProperty('fullname'),
5543
                                        SWIFT_TicketAuditLog::ACTION_LINKTICKET, $_SWIFT->Language->Get($_phrase . '_into') . ' ' . $_TicketNew->GetTicketDisplayID(), SWIFT_TicketAuditLog::VALUE_NONE, '');
5544
                        }
5545
5546
                        // and for the new ticket too.
5547
                        $_firstTicketPostContainer = $_SWIFT->Database->QueryFetch("SELECT MIN(ticketpostid) AS ticketpostid FROM " . TABLE_PREFIX . SWIFT_TicketPost::TABLE_NAME . "
5548
                                                                                                                                                WHERE ticketid = " . intval($_newTicketID));
5549
5550
                        if (is_array($_firstTicketPostContainer) && !empty($_firstTicketPostContainer['ticketpostid'])) {
5551
                                $_TicketPost = new SWIFT_TicketPost(new SWIFT_DataID($_firstTicketPostContainer['ticketpostid']));
5552
5553
                                SWIFT_TicketAuditLog::Create($_TicketNew, $_TicketPost, SWIFT_TicketAuditLog::CREATOR_STAFF, $_SWIFT->Staff->GetStaffID(), $_SWIFT->Staff->GetProperty('fullname'),
5554
                                        SWIFT_TicketAuditLog::ACTION_LINKTICKET, $_SWIFT->Language->Get($_phrase . '_from') . ' ' . $_TicketOld->GetTicketDisplayID(), SWIFT_TicketAuditLog::VALUE_NONE, '');
5555
                        }
5556
5557
                        // Reset all the various counts in the owning ticket objects.
5558
                        $_TicketOld->RebuildProperties();
5559
                        $_TicketNew->RebuildProperties();
5560
5561
                        if (isset($_POST['closeold']) && $_POST['closeold'] == '1' && $_operationMode == SWIFT_TICKET::MODE_SPLIT) {
5562
                                // Close the old ticket if requested, using the first available 'resolved' status.
5563
                                $_ticketStatusCache = $_SWIFT->Cache->Get('statuscache');
5564
                                $_ticketDepartment  = $_TicketOld->GetProperty('departmentid');
5565
5566
                                foreach ($_ticketStatusCache as $_ticketStatus) {
5567
                                        if ($_ticketStatus['markasresolved']) {
5568
                                                if ($_ticketStatus['departmentid'] == 0 || $_ticketStatus['departmentid'] == $_ticketDepartment) {
5569
5570
                                                        // This is available to this department, and is resolved.
5571
                                                        $_TicketOld->SetStatus($_ticketStatus['ticketstatusid']);
5572
5573
                                                        break;
5574
                                                }
5575
                                        }
5576
                                }
5577
                        }
5578
5579
                        $_SWIFT->Database->CompleteTrans();
5580
                } else {
5581
                        SWIFT::Error($_SWIFT->Language->Get('ticketsplitter'), $_SWIFT->Language->Get('no_such_post'));
5582
                }
5583
5584
                return $this->Load->Controller('Manage', APP_TICKETS)->Load->Index();
5585
        }
5586
5587
        /**
5588
         * Render the Recurrence for this Ticket
5589
         *
5590
         * @author Parminder Singh
5591
         *
5592
         * @param int $_ticketID
5593
         * @param int $_ticketRecurrenceID
5594
         *
5595
         * @return bool
5596
         */
5597
        public function Recurrence($_ticketID, $_ticketRecurrenceID)
5598
        {
5599
                $_SWIFT = SWIFT::GetInstance();
5600
5601
                $_Ticket = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
5602
5603
                // Check permission
5604
                if (!$_Ticket->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewrecurrence') == '0') {
5605
                        echo $this->Language->Get('msgnoperm');
5606
5607
                        return false;
5608
                }
5609
5610
                $_TicketRecurrence = new SWIFT_TicketRecurrence(new SWIFT_DataID($_ticketRecurrenceID));
5611
5612
                $this->View->RenderRecurrence($_Ticket, $_TicketRecurrence);
5613
5614
                return true;
5615
        }
5616
5617
        /**
5618
         * Pause/Resume ticket recurrence
5619
         *
5620
         * @author Parminder Singh
5621
         *
5622
         * @param int $_ticketID
5623
         * @param int $_ticketRecurrenceID
5624
         *
5625
         * @return bool
5626
         */
5627
        public function PauseOrResumeRecurrence($_ticketID, $_ticketRecurrenceID)
5628
        {
5629
                $_SWIFT = SWIFT::GetInstance();
5630
5631
                $_Ticket = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
5632
5633
                // Check permission
5634
                if (!$_Ticket->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdaterecurrence') == '0') {
5635
                        echo $this->Language->Get('msgnoperm');
5636
5637
                        return false;
5638
                }
5639
5640
                $_TicketRecurrence = new SWIFT_TicketRecurrence(new SWIFT_DataID($_ticketRecurrenceID));
5641
5642
                if ($_TicketRecurrence->Get('nextrecurrence') == '0') { //        If it is paused then resume it
5643
                        $_TicketRecurrence->UpdatePool('nextrecurrence', intval($_TicketRecurrence->GetNextRecurrence()));
5644
                } else { //        Otherwise pause it
5645
                        $_TicketRecurrence->UpdatePool('nextrecurrence', '0');
5646
                }
5647
5648
                $this->Load->Method('View', $_ticketID);
5649
5650
                return true;
5651
        }
5652
5653
        /**
5654
         * Stop the ticket recurrence
5655
         *
5656
         * @author Parminder Singh
5657
         *
5658
         * @param int $_ticketID
5659
         * @param int $_ticketRecurrenceID
5660
         *
5661
         * @return bool
5662
         */
5663
        public function StopRecurrence($_ticketID, $_ticketRecurrenceID)
5664
        {
5665
                $_SWIFT = SWIFT::GetInstance();
5666
5667
                $_Ticket = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
5668
5669
                // Check permission
5670
                if (!$_Ticket->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcandeleterecurrence') == '0') {
5671
                        echo $this->Language->Get('msgnoperm');
5672
5673
                        return false;
5674
                }
5675
5676
                $_TicketRecurrence = new SWIFT_TicketRecurrence(new SWIFT_DataID($_ticketRecurrenceID));
5677
5678
                $_TicketRecurrence->Delete();
5679
5680
                $this->Load->Method('View', $_ticketID);
5681
5682
                return true;
5683
        }
5684
5685
        /**
5686
         * Delete the ticket recurrence
5687
         *
5688
         * @author Parminder Singh
5689
         *
5690
         * @param int $_ticketID
5691
         * @param int $_ticketRecurrenceID
5692
         *
5693
         * @return bool
5694
         */
5695
        public function UpdateRecurrence($_ticketID, $_ticketRecurrenceID)
5696
        {
5697
                $_SWIFT = SWIFT::GetInstance();
5698
5699
                $_Ticket = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
5700
5701
                // Check permission
5702
                if (!$_Ticket->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanupdaterecurrence') == '0') {
5703
                        echo $this->Language->Get('msgnoperm');
5704
5705
                        return false;
5706
                }
5707
5708
                $_TicketRecurrence = new SWIFT_TicketRecurrence(new SWIFT_DataID($_ticketRecurrenceID));
5709
5710
                if (isset($_POST['recurrencetype'])) {
5711
5712
                        // Reset recurrence fields before updating
5713
                        $_TicketRecurrence->Reset();
5714
5715
                        // Daily
5716
                        if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_DAILY) {
5717
                                $_intervalStep      = intval($_POST['recurrence_daily_step']);
5718
                                $_dailyEveryWeekday = false;
5719
                                if ((empty($_intervalStep) || $_intervalStep < 0) && $_POST['recurrence_daily_type'] == 'default') {
5720
                                        $_intervalStep = 1;
5721
                                }
5722
5723
                                if ($_POST['recurrence_daily_type'] == 'extended') {
5724
                                        $_intervalStep      = 0;
5725
                                        $_dailyEveryWeekday = true;
5726
                                }
5727
5728
                                $_TicketRecurrence->UpdateDaily($_intervalStep, $_dailyEveryWeekday);
5729
                                // Weekly
5730
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_WEEKLY) {
5731
                                $_intervalStep = intval($_POST['recurrence_weekly_step']);
5732
                                if ((empty($_intervalStep) || $_intervalStep < 0)) {
5733
                                        $_intervalStep = 1;
5734
                                }
5735
5736
                                $_isMonday = $_isTuesday = $_isWednesday = $_isThursday = $_isFriday = $_isSaturday = $_isSunday = false;
5737
                                if (isset($_POST['recurrence_weekly_ismonday'])) {
5738
                                        $_isMonday = true;
5739
                                }
5740
5741
                                if (isset($_POST['recurrence_weekly_istuesday'])) {
5742
                                        $_isTuesday = true;
5743
                                }
5744
5745
                                if (isset($_POST['recurrence_weekly_iswednesday'])) {
5746
                                        $_isWednesday = true;
5747
                                }
5748
5749
                                if (isset($_POST['recurrence_weekly_isthursday'])) {
5750
                                        $_isThursday = true;
5751
                                }
5752
5753
                                if (isset($_POST['recurrence_weekly_isfriday'])) {
5754
                                        $_isFriday = true;
5755
                                }
5756
5757
                                if (isset($_POST['recurrence_weekly_issaturday'])) {
5758
                                        $_isSaturday = true;
5759
                                }
5760
5761
                                if (isset($_POST['recurrence_weekly_issunday'])) {
5762
                                        $_isSunday = true;
5763
                                }
5764
5765
                                $_TicketRecurrence->UpdateWeekly($_intervalStep, $_isMonday, $_isTuesday, $_isWednesday, $_isThursday, $_isFriday, $_isSaturday, $_isSunday);
5766
                                // Monthly
5767
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_MONTHLY) {
5768
                                $_recurrenceMonthlyType  = SWIFT_TicketRecurrence::MONTHLY_DEFAULT;
5769
                                $_monthlyExtendedDay     = 'monday';
5770
                                $_monthlyExtendedDayStep = 'first';
5771
                                $_monthlyDay             = date('d');
5772
5773
                                if ($_POST['recurrence_monthly_type'] == 'extended') {
5774
                                        $_recurrenceMonthlyType  = SWIFT_TicketRecurrence::MONTHLY_EXTENDED;
5775
                                        $_monthlyExtendedDay     = $_POST['recurrence_monthly_extday'];
5776
                                        $_monthlyExtendedDayStep = $_POST['recurrence_monthly_extdaystep'];
5777
5778
                                        $_intervalStep = intval($_POST['recurrence_monthly_stepext']);
5779
                                } else {
5780
                                        $_intervalStep = intval($_POST['recurrence_monthly_step']);
5781
                                        if (intval($_POST['recurrence_monthly_day']) != '0' && intval($_POST['recurrence_monthly_day']) > 0) {
5782
                                                $_monthlyDay = intval($_POST['recurrence_monthly_day']);
5783
                                        }
5784
                                }
5785
5786
                                if ((empty($_intervalStep) || $_intervalStep < 0)) {
5787
                                        $_intervalStep = 1;
5788
                                }
5789
5790
                                $_TicketRecurrence->UpdateMonthly($_intervalStep, $_recurrenceMonthlyType, $_monthlyDay, $_monthlyExtendedDay, $_monthlyExtendedDayStep);
5791
                                // Yearly
5792
                        } else if ($_POST['recurrencetype'] == SWIFT_TicketRecurrence::INTERVAL_YEARLY) {
5793
                                $_yearlyType            = SWIFT_TicketRecurrence::YEARLY_DEFAULT;
5794
                                $_yearlyMonthDay        = gmdate('d', DATENOW);
5795
                                $_yearlyMonth           = gmdate('n', DATENOW);
5796
                                $_yearlyExtendedDay     = 'first';
5797
                                $_yearlyExtendedDayStep = 'monday';
5798
                                $_yearlyExtendedMonth   = $_yearlyMonth;
5799
5800
                                if ($_POST['recurrence_yearly_type'] == 'extended') {
5801
                                        $_yearlyType            = SWIFT_TicketRecurrence::YEARLY_EXTENDED;
5802
                                        $_yearlyExtendedDay     = $_POST['recurrence_yearly_extday'];
5803
                                        $_yearlyExtendedDayStep = $_POST['recurrence_yearly_extdaystep'];
5804
                                        $_yearlyExtendedMonth   = $_POST['recurrence_yearly_extmonth'];
5805
                                } else {
5806
                                        $_yearlyMonthDay = intval($_POST['recurrence_yearly_monthday']);
5807
                                        if (empty($_yearlyMonthDay) || $_yearlyMonthDay <= 0) {
5808
                                                $_yearlyMonthDay = gmdate('d', DATENOW);
5809
                                        }
5810
5811
                                        $_yearlyMonth = intval($_POST['recurrence_yearly_month']);
5812
                                }
5813
5814
                                $_TicketRecurrence->UpdateYearly($_yearlyType, $_yearlyMonth, $_yearlyMonthDay, $_yearlyExtendedDay, $_yearlyExtendedDayStep, $_yearlyExtendedMonth);
5815
                        }
5816
5817
                        $_endType = SWIFT_TicketRecurrence::END_NOEND;
5818
                        if ($_POST['recurrence_endtype'] == SWIFT_TicketRecurrence::END_DATE && GetCalendarDateline($_POST['recurrence_enddateline']) != false) {
5819
                                $_endType = SWIFT_TicketRecurrence::END_DATE;
5820
                        } else if (($_POST['recurrence_endtype'] == SWIFT_TicketRecurrence::END_OCCURENCES && intval($_POST['recurrence_endcount']) > 0)) {
5821
                                $_endType = SWIFT_TicketRecurrence::END_OCCURENCES;
5822
                        }
5823
5824
                        $_TicketRecurrence->UpdateRecurrenceRange(GetCalendarDateline($_POST['recurrence_start']), $_endType, GetCalendarDateline($_POST['recurrence_enddateline']), intval($_POST['recurrence_endcount']));
5825
5826
                        // Update next recurrence
5827
                        $_TicketRecurrence->UpdatePool('nextrecurrence', intval($_TicketRecurrence->GetNextRecurrence()));
5828
                }
5829
5830
                $this->Load->Method('View', $_ticketID);
5831
5832
                return true;
5833
        }
5834
5835
        /**
5836
         * Dispatch data for quoting a reply
5837
         *
5838
         * @author Varun Shoor
5839
         * @param int $_ticketID The Ticket ID
5840
         * @param int $_ticketPostID The Ticket Post ID
5841
         * @return bool "true" on Success, "false" otherwise
5842
         * @throws SWIFT_Exception If the Class is not Loaded
5843
         */
5844
        public function GetQuote($_ticketID, $_ticketPostID) {
5845
5846
                $_SWIFT = SWIFT::GetInstance();
5847
5848
                if (!$this->GetIsClassLoaded()) {
5849
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
5850
5851
                        return false;
5852
                }
5853
5854
                /*
5855
                 * BUG FIX - Parminder Singh
5856
                 *
5857
                 * SWIFT-2815: Uncaught Exception: Invalid data provided in ./__apps/tickets/models/Ticket/class.SWIFT_Ticket.php:409
5858
                 *
5859
                 * Comments: If current ticket id is merged with other tickets
5860
                 */
5861
                $_SWIFT_TicketObject = SWIFT_Ticket::GetObjectOnID($_ticketID);
5862
5863
                // Did the object load up?
5864
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
5865
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5866
                }
5867
5868
                // Check permission
5869
                if (!$_SWIFT_TicketObject->CanAccess($_SWIFT->Staff) || $_SWIFT->Staff->GetPermission('staff_tcanviewtickets') == '0') {
5870
                        echo $this->Language->Get('msgnoperm');
5871
5872
                        return false;
5873
5874
                }
5875
5876
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
5877
                // Did the object load up?
5878
                if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded()) {
5879
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5880
                }
5881
5882
                if ($_SWIFT_TicketPostObject->GetProperty('ticketid') != $_SWIFT_TicketObject->GetTicketID()) {
5883
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
5884
                }
5885
5886
                echo $_SWIFT_TicketPostObject->GetQuoteContents();
5887
5888
                return true;
5889
        }
5890
5891
        /**
5892
         * Ability to unlink linked ticket
5893
         *
5894
         * @author Rahul Bhattacharya
5895
         *
5896
         * @param int $_ticketID
5897
         * @param int $_linkedTicketDisplayID
5898
         * @param int $_linkTypeID
5899
         *
5900
         * @return bool
5901
         */
5902
        public function Unlink($_ticketID, $_linkedTicketDisplayID, $_linkTypeID)
5903
        {
5904
                $_SWIFT = SWIFT::GetInstance();
5905
5906
                $_ticketHashContainer = $_linkedTicketHashContainer = array();
5907
5908
                //Fetch the chainhash list of the Ticket
5909
                $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . SWIFT_TicketLinkChain::TABLE_NAME . "
5910
                                          WHERE ticketid = " . intval($_ticketID) . "
5911
                                            AND ticketlinktypeid = " . intval($_linkTypeID));
5912
5913
                while ($_SWIFT->Database->NextRecord()) {
5914
                        $_ticketHashContainer[] = $_SWIFT->Database->Record['chainhash'];
5915
                }
5916
5917
                // Fetch the chainhash list of the linked Ticket
5918
                $_LinkedTicket = SWIFT_Ticket::GetObjectOnID($_linkedTicketDisplayID);
5919
                $_linkedTicketID = $_LinkedTicket->GetID();
5920
5921
                $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . SWIFT_TicketLinkChain::TABLE_NAME . "
5922
                                                                  WHERE ticketid = " . intval($_linkedTicketID) . "
5923
                                                                    AND ticketlinktypeid = " . intval($_linkTypeID));
5924
5925
                while ($_SWIFT->Database->NextRecord()) {
5926
                        $_linkedTicketHashContainer[] = $_SWIFT->Database->Record['chainhash'];
5927
                }
5928
5929
                $_chainHashContainer = array_intersect($_ticketHashContainer, $_linkedTicketHashContainer);
5930
5931
                if (_is_array($_chainHashContainer)) {
5932
                        $_finalTicketIDList = array($_linkedTicketID);
5933
                        $_chainHash         = end($_chainHashContainer);
5934
5935
                        $_hashCount = $_SWIFT->Database->QueryFetch("SELECT COUNT(*) AS totalrecords FROM " . TABLE_PREFIX . SWIFT_TicketLinkChain::TABLE_NAME . "
5936
                                                                                                                 WHERE chainhash = '" . $_SWIFT->Database->Escape($_chainHash) . "'");
5937
5938
                        if ($_hashCount['totalrecords'] <= 2) {
5939
                                $_finalTicketIDList[] = $_ticketID;
5940
                        }
5941
5942
                        $_finalTicketLinkChainIDList = array();
5943
                        $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . SWIFT_TicketLinkChain::TABLE_NAME . "
5944
                                                                          WHERE ticketid IN (" . BuildIN($_finalTicketIDList, true) . ")
5945
                                                                                AND ticketlinktypeid = " . intval($_linkTypeID) . "
5946
                                                                                AND chainhash = '" . $_SWIFT->Database->Escape($_chainHash) . "'");
5947
5948
                        while ($_SWIFT->Database->NextRecord()) {
5949
                                $_finalTicketLinkChainIDList[] = $_SWIFT->Database->Record['ticketlinkchainid'];
5950
                        }
5951
5952
                        if (_is_array($_finalTicketLinkChainIDList)) {
5953
                                SWIFT_TicketLinkChain::DeleteList($_finalTicketLinkChainIDList);
5954
                        }
5955
5956
                        $_Ticket       = SWIFT_Ticket::GetObjectOnID($_ticketID);
5957
                        $_LinkedTicket = SWIFT_Ticket::GetObjectOnID($_linkedTicketID);
5958
5959
                        if ($_Ticket instanceof SWIFT_Ticket && !_is_array($_Ticket->GetLinks())) {
5960
                                $_Ticket->MarkAsUnlinked();
5961
                        }
5962
5963
                        if ($_LinkedTicket instanceof SWIFT_Ticket && !_is_array($_LinkedTicket->GetLinks())) {
5964
                                $_LinkedTicket->MarkAsUnlinked();
5965
                        }
5966
                }
5967
5968
                $this->View($_ticketID, 'inbox', '-1', '-1', '-1');
5969
5970
                return true;
5971
        }
5972
                public function SmartReply($_SWIFT_TicketObject, $_TicketPostContents){
5973
       // $_SmartWords = Array('fullname','forename','surname','organization','title','salutation','customfields');
5974
5975
        //preg_replace($pattern, $replacement, $string);
5976
5977
5978
        $_SWIFT = SWIFT::GetInstance();
5979
        $this->Language->Load('staff_users');
5980
        $parts = explode(" ", $_SWIFT_TicketObject->GetProperty('fullname'));
5981
        $lastname = array_pop($parts);
5982
        $firstname = implode(" ", $parts);
5983
        $_salutationList = array('',$this->Language->Get('salutationmr'),$this->Language->Get('salutationmiss'),$this->Language->Get('salutationmrs'),$this->Language->Get('salutationdr'));
5984
5985
5986
5987
5988
        $_SWIFT_UserObject = $_SWIFT_TicketObject->GetUserObject();
5989
        $_userdesignation = '';
5990
        $_salutation = '';
5991
        if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded()){
5992
5993
        $_userdesignation = $_SWIFT_UserObject->GetProperty('userdesignation');
5994
        $_salutation = $_SWIFT_UserObject->GetProperty('salutation');
5995
5996
        $_SWIFT_UserOrganizationObject = '';
5997
                try {
5998
                        $_SWIFT_UserOrganizationObject = new SWIFT_UserOrganization($_SWIFT_UserObject->GetProperty('userorganizationid'));
5999
                } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
6000
6001
                }
6002
6003
6004
                if ($_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization) {
6005
                                $_OrganizationName = $_SWIFT_UserOrganizationObject->GetProperty('organizationname');
6006
                }else{
6007
            $_OrganizationName = 'NA';
6008
        }
6009
6010
        }
6011
6012
6013
6014
        $_TicketPostContents = str_replace('{{fullname}}',$firstname . ' ' . $lastname, $_TicketPostContents);
6015
        $_TicketPostContents = str_replace('{{forename}}',$firstname, $_TicketPostContents);
6016
        $_TicketPostContents = str_replace('{{surname}}',$lastname, $_TicketPostContents);
6017
6018
        $_TicketPostContents = str_replace('{{title}}',$_userdesignation, $_TicketPostContents);
6019
        $_TicketPostContents = str_replace('{{salutation}}',$_salutationList[$_salutation], $_TicketPostContents);
6020
        $_TicketPostContents = str_replace('{{organization}}',$_OrganizationName, $_TicketPostContents);
6021
6022
6023
        // start custom fields check
6024
        $str_test = $_TicketPostContents;
6025
6026
        $count = 0;
6027
        $offset = 4;
6028
        $find = "{{custom_field[";
6029
        $positions = array();
6030
6031
        for($i = 0; $i<strlen($str_test); $i++)
6032
        {
6033
         $pos = 0;
6034
        $pos = strpos($str_test, $find, $count);
6035
         if($pos <> 0){
6036
           $positions[] = $pos;
6037
         }
6038
         $count = $pos + 2;
6039
        }
6040
        if (empty($positions)) {
6041
        return $_TicketPostContents;
6042
        }
6043
        foreach ($positions as $value) {
6044
        //$_FieldName[] = substr($_TicketPostContents,$value + 15)
6045
        $pos2 = strpos($_TicketPostContents, "]}}",$value);
6046
        $_FinalName[] = substr($_TicketPostContents,$value + 15,$pos2 - $value - 15);
6047
        }
6048
6049
        foreach ($_FinalName as $field){
6050
6051
        $this->Database->Query("select customfieldid,fieldtype,customfieldgroupid from " . TABLE_PREFIX . "customfields where title = '" . $field . "'");
6052
    while ($this->Database->NextRecord())
6053
        {
6054
6055
            $_fieldtype = $this->Database->Record['fieldtype'];
6056
            $_customfieldID = $this->Database->Record['customfieldid'];
6057
            $_customfieldGroupID = $this->Database->Record['customfieldgroupid'];
6058
6059
6060
        $this->Database->Query("select grouptype from " . TABLE_PREFIX . "customfieldgroups where customfieldgroupid = " . $_customfieldGroupID);
6061
    while ($this->Database->NextRecord())
6062
        {
6063
        $_Grouptype = $this->Database->Record['grouptype'];
6064
6065
        }
6066
6067
6068
6069
        if ($_Grouptype == 1){
6070
6071
        if (in_array($_fieldtype, array("1", "10", "2", "3"))) {
6072
6073
        $this->Database->Query("select fieldvalue from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_TicketObject->GetProperty('userid') ." and customfieldid = " . $_customfieldID);
6074
    while ($this->Database->NextRecord())
6075
        {
6076
            $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$this->Database->Record['fieldvalue'], $_TicketPostContents);
6077
        }
6078
6079
6080
        }//end fieldtype 1,10,2,3
6081
6082
        if (in_array($_fieldtype, array("4","5", "6", "7", "9"))) {
6083
6084
        $this->Database->Query("select fieldvalue,isserialized from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_TicketObject->GetProperty('userid') ." and customfieldid = " . $_customfieldID);
6085
    while ($this->Database->NextRecord())
6086
        {
6087
            $_fieldValue = $this->Database->Record['fieldvalue'];
6088
            if ($this->Database->Record['isserialized'] == '1') {
6089
            $_fieldValue = mb_unserialize($_fieldValue);
6090
            $_fieldValue  = self::multi_implode($_fieldValue,",");
6091
6092
            }
6093
        $_Allvalues = '';
6094
        $this->Database->Query("select optionvalue from " . TABLE_PREFIX . "customfieldoptions where customfieldid = " . $_customfieldID ." and customfieldoptionid In (" . $_fieldValue . ")");
6095
    while ($this->Database->NextRecord())
6096
        {
6097
           if ($_Allvalues == ""){
6098
           $_Allvalues = $this->Database->Record['optionvalue'];
6099
           }else{
6100
         $_Allvalues = $_Allvalues . "," . $this->Database->Record['optionvalue'];
6101
            }
6102
        }
6103
        $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$_Allvalues, $_TicketPostContents);
6104
6105
        }
6106
6107
6108
        }//end fieldtype 4,5,6,7,9
6109
        }//end grouptype check
6110
6111
        if ($_Grouptype == 3 || $_Grouptype == 4 || $_Grouptype == 9){
6112
6113
        if (in_array($_fieldtype, array("1", "10", "2", "3"))) {
6114
6115
        $this->Database->Query("select fieldvalue from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_TicketObject->GetProperty('ticketid') ." and customfieldid = " . $_customfieldID);
6116
    while ($this->Database->NextRecord())
6117
        {
6118
            $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$this->Database->Record['fieldvalue'], $_TicketPostContents);
6119
        }
6120
6121
6122
        }//end fieldtype 1,10,2,3
6123
6124
              if (in_array($_fieldtype, array("4","5", "6", "7", "9"))) {
6125
6126
        $this->Database->Query("select fieldvalue,isserialized from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_TicketObject->GetProperty('ticketid') ." and customfieldid = " . $_customfieldID);
6127
    while ($this->Database->NextRecord())
6128
        {
6129
            $_fieldValue = $this->Database->Record['fieldvalue'];
6130
            if ($this->Database->Record['isserialized'] == '1') {
6131
            $_fieldValue = mb_unserialize($_fieldValue);
6132
            $_fieldValue  = self::multi_implode($_fieldValue,",");
6133
6134
            }
6135
        $_Allvalues = '';
6136
        $this->Database->Query("select optionvalue from " . TABLE_PREFIX . "customfieldoptions where customfieldid = " . $_customfieldID ." and customfieldoptionid In (" . $_fieldValue . ")");
6137
    while ($this->Database->NextRecord())
6138
        {
6139
           if ($_Allvalues == ""){
6140
           $_Allvalues = $this->Database->Record['optionvalue'];
6141
           }else{
6142
         $_Allvalues = $_Allvalues . "," . $this->Database->Record['optionvalue'];
6143
            }
6144
        }
6145
        $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$_Allvalues, $_TicketPostContents);
6146
6147
        }
6148
6149
6150
        }//end fieldtype 4,5,6,7,9
6151
6152
        }//end grouptype check
6153
6154
                if ($_Grouptype == 2){
6155
6156
        if (in_array($_fieldtype, array("1", "10", "2", "3"))) {
6157
6158
        $this->Database->Query("select fieldvalue from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_UserObject->GetProperty('userorganizationid') ." and customfieldid = " . $_customfieldID);
6159
    while ($this->Database->NextRecord())
6160
        {
6161
            $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$this->Database->Record['fieldvalue'], $_TicketPostContents);
6162
        }
6163
6164
6165
        }//end fieldtype 1,10,2,3
6166
                      if (in_array($_fieldtype, array("4","5", "6", "7", "9"))) {
6167
6168
        $this->Database->Query("select fieldvalue,isserialized from " . TABLE_PREFIX . "customfieldvalues where typeid = " . $_SWIFT_UserObject->GetProperty('userorganizationid') ." and customfieldid = " . $_customfieldID);
6169
    while ($this->Database->NextRecord())
6170
        {
6171
            $_fieldValue = $this->Database->Record['fieldvalue'];
6172
            if ($this->Database->Record['isserialized'] == '1') {
6173
            $_fieldValue = mb_unserialize($_fieldValue);
6174
            $_fieldValue  = self::multi_implode($_fieldValue,",");
6175
6176
            }
6177
        $_Allvalues = '';
6178
        $this->Database->Query("select optionvalue from " . TABLE_PREFIX . "customfieldoptions where customfieldid = " . $_customfieldID ." and customfieldoptionid In (" . $_fieldValue . ")");
6179
    while ($this->Database->NextRecord())
6180
        {
6181
           if ($_Allvalues == ""){
6182
           $_Allvalues = $this->Database->Record['optionvalue'];
6183
           }else{
6184
         $_Allvalues = $_Allvalues . "," . $this->Database->Record['optionvalue'];
6185
            }
6186
        }
6187
        $_TicketPostContents = str_replace('{{custom_field[' . $field . ']}}',$_Allvalues, $_TicketPostContents);
6188
6189
        }
6190
6191
6192
        }//end fieldtype 4,5,6,7,9
6193
        }//end grouptype check
6194
6195
6196
        }
6197
        }//foreach
6198
6199
        return $_TicketPostContents;
6200
    }
6201
6202
public function multi_implode($array, $glue) {
6203
    $ret = '';
6204
6205
    foreach ($array as $item) {
6206
        if (is_array($item)) {
6207
            $ret .= self::multi_implode($item, $glue) . $glue;
6208
        } else {
6209
            $ret .= $item . $glue;
6210
        }
6211
    }
6212
6213
    $ret = substr($ret, 0, 0-strlen($glue));
6214
6215
    return $ret;
6216
}
6217
6218
}