class.SWIFT_TicketPost.php

Amarjeet Kaur, 12/25/2012 12:19 am

Download (38.9 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 Ticket Post Management Class
20
 *
21
 * @author Varun Shoor
22
 */
23
class SWIFT_TicketPost extends SWIFT_Model
24
{
25
        const TABLE_NAME                =        'ticketposts';
26
        const PRIMARY_KEY                =        'ticketpostid';
27
28
        const TABLE_STRUCTURE        =        "ticketpostid I PRIMARY AUTO NOTNULL,
29
                                                                ticketid I DEFAULT '0' NOTNULL,
30
                                                                dateline I DEFAULT '0' NOTNULL,
31
                                                                userid I DEFAULT '0' NOTNULL,
32
                                                                fullname C(255) DEFAULT '' NOTNULL,
33
                                                                email C(255) DEFAULT '' NOTNULL,
34
                                                                emailto C(255) DEFAULT '' NOTNULL,
35
                                                                subject C(255) DEFAULT '' NOTNULL,
36
                                                                ipaddress C(50) DEFAULT '0.0.0.0' NOTNULL,
37
                                                                hasattachments I2 DEFAULT '0' NOTNULL,
38
                                                                edited I2 DEFAULT '0' NOTNULL,
39
                                                                editedbystaffid I DEFAULT '0' NOTNULL,
40
                                                                editeddateline I DEFAULT '0' NOTNULL,
41
                                                                creator I2 DEFAULT '0' NOTNULL,
42
                                                                isthirdparty I2 DEFAULT '0' NOTNULL,
43
                                                                ishtml I2 DEFAULT '0' NOTNULL,
44
                                                                isemailed I2 DEFAULT '0' NOTNULL,
45
                                                                isprivate I2 DEFAULT '0' NOTNULL,
46
                                                                staffid I DEFAULT '0' NOTNULL,
47
                                                                contents X2,
48
                                                                contenthash C(50) DEFAULT '' NOTNULL,
49
                                                                subjecthash C(50) DEFAULT '' NOTNULL,
50
                                                                issurveycomment I2 DEFAULT '0' NOTNULL,
51
52
                                                                creationmode I2 DEFAULT '0' NOTNULL,
53
                                                                responsetime I DEFAULT '0' NOTNULL,
54
                                                                firstresponsetime I DEFAULT '0' NOTNULL";
55
56
        const INDEX_1                        =        'ticketid, staffid';
57
        const INDEX_2                        =        'email, subjecthash';
58
        const INDEX_3                        =        'creator, staffid, dateline';
59
        const INDEX_4                        =        'responsetime';
60
        const INDEX_5                        =        'firstresponsetime';
61
62
63
64
        protected $_dataStore = array();
65
66
        const CREATOR_STAFF = 1;
67
        const CREATOR_USER = 2;
68
        const CREATOR_CLIENT = 2;
69
        const CREATOR_CC = 3;
70
        const CREATOR_BCC = 4;
71
        const CREATOR_THIRDPARTY = 5;
72
73
        /**
74
         * Constructor
75
         *
76
         * @author Varun Shoor
77
         * @param SWIFT_Data $_SWIFT_DataObject The SWIFT_Data Object
78
         * @return bool "true" on Success, "false" otherwise
79
         * @throws SWIFT_Ticket_Exception If the Record could not be loaded
80
         */
81
        public function __construct(SWIFT_Data $_SWIFT_DataObject)
82
        {
83
                parent::__construct();
84
85
                if (!$_SWIFT_DataObject instanceof SWIFT_Data || !$_SWIFT_DataObject->GetIsClassLoaded() || !$this->LoadData($_SWIFT_DataObject)) {
86
                        throw new SWIFT_Ticket_Exception('Failed to load Ticket Post Object');
87
88
                        $this->SetIsClassLoaded(false);
89
90
                        return false;
91
                }
92
93
                return true;
94
        }
95
96
        /**
97
         * Destructor
98
         *
99
         * @author Varun Shoor
100
         * @return bool "true" on Success, "false" otherwise
101
         */
102
        public function __destruct()
103
        {
104
                parent::__destruct();
105
106
                return true;
107
        }
108
109
        /**
110
         * Processes the Update Pool Data
111
         *
112
         * @author Varun Shoor
113
         * @return bool "true" on Success, "false" otherwise
114
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded
115
         */
116
        public function ProcessUpdatePool()
117
        {
118
                if (!$this->GetIsClassLoaded()) {
119
                        return false;
120
                } else if (!_is_array($this->GetUpdatePool())) {
121
                        return false;
122
                }
123
124
                $this->Database->AutoExecute(TABLE_PREFIX . 'ticketposts', $this->GetUpdatePool(), 'UPDATE', "ticketpostid = '" .
125
                                intval($this->GetTicketPostID()) . "'");
126
127
                $this->ClearUpdatePool();
128
129
                return true;
130
        }
131
132
        /**
133
         * Retrieves the Ticket Post ID
134
         *
135
         * @author Varun Shoor
136
         * @return mixed "ticketpostid" on Success, "false" otherwise
137
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded
138
         */
139
        public function GetTicketPostID()
140
        {
141
                if (!$this->GetIsClassLoaded())
142
                {
143
                        throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
144
145
                        return false;
146
                }
147
148
                return $this->_dataStore['ticketpostid'];
149
        }
150
151
        /**
152
         * Load the Data
153
         *
154
         * @author Varun Shoor
155
         * @param SWIFT_Data $_SWIFT_DataObject The SWIFT_Data Object
156
         * @return bool "true" on Success, "false" otherwise
157
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
158
         */
159
        protected function LoadData($_SWIFT_DataObject)
160
        {
161
                // Is it a ID?
162
                if ($_SWIFT_DataObject instanceof SWIFT_DataID && $_SWIFT_DataObject->GetIsClassLoaded())
163
                {
164
                        $_dataStore = $this->Database->QueryFetch("SELECT * FROM " . TABLE_PREFIX . "ticketposts WHERE ticketpostid = '" .
165
                                        intval($_SWIFT_DataObject->GetDataID()) . "'");
166
                        if (isset($_dataStore['ticketpostid']) && !empty($_dataStore['ticketpostid']))
167
                        {
168
                                $this->_dataStore = $_dataStore;
169
170
                                return true;
171
                        }
172
173
                // Is it a Store?
174
                } else if ($_SWIFT_DataObject instanceof SWIFT_DataStore && $_SWIFT_DataObject->GetIsClassLoaded()) {
175
                        $this->_dataStore = $_SWIFT_DataObject->GetDataStore();
176
177
                        if (!isset($this->_dataStore['ticketpostid']) || empty($this->_dataStore['ticketpostid']))
178
                        {
179
                                throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
180
                        }
181
182
                        return true;
183
                }
184
185
                throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
186
187
                return false;
188
        }
189
190
        /**
191
         * Returns the Data Store Array
192
         *
193
         * @author Varun Shoor
194
         * @return mixed "_dataStore" Array on Success, "false" otherwise
195
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded
196
         */
197
        public function GetDataStore()
198
        {
199
                if (!$this->GetIsClassLoaded())
200
                {
201
                        throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
202
203
                        return false;
204
                }
205
206
                return $this->_dataStore;
207
        }
208
209
        /**
210
         * Retrieves a Property Value from Data Store
211
         *
212
         * @author Varun Shoor
213
         * @param string $_key The Key Identifier
214
         * @return mixed Property Data on Success, "false" otherwise
215
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded
216
         */
217
        public function GetProperty($_key)
218
        {
219
                if (!$this->GetIsClassLoaded())
220
                {
221
                        throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
222
223
                        return false;
224
                } else if (!isset($this->_dataStore[$_key])) {
225
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
226
227
                        return false;
228
                }
229
230
                return $this->_dataStore[$_key];
231
        }
232
233
        /**
234
         * Check to see if its a valid creator type
235
         *
236
         * @author Varun Shoor
237
         * @param constant $_creatorType The Creator Type
238
         * @return bool "true" on Success, "false" otherwise
239
         */
240
        static public function IsValidCreatorType($_creatorType)
241
        {
242
                if ($_creatorType == self::CREATOR_STAFF || $_creatorType == self::CREATOR_USER || $_creatorType == self::CREATOR_THIRDPARTY ||
243
                                $_creatorType == self::CREATOR_CC || $_creatorType == self::CREATOR_BCC)
244
                {
245
                        return true;
246
                }
247
248
                return false;
249
        }
250
251
        /**
252
         * Create a Staff Reply
253
         *
254
         * @author Varun Shoor
255
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
256
         * @param SWIFT_Staff $_SWIFT_StaffObject The SWIFT_Staff Object Pointer
257
         * @param constant $_creationMode The Creation Mode
258
         * @param string $_contents The Reply Contents
259
         * @param string $_subject The Reply Subject
260
         * @param bool $_dontSendEmail (OPTIONAL) Whether to send a email to client or not
261
         * @param bool $_isHTML (OPTIONAL) Whether the contents contain HTML data
262
         * @param string $_overrideFromEmail (OPTIONAL) Whether to override the from email address with the given address
263
         * @param bool $_isPrivate (OPTIONAL) Whether its private post
264
         * @return int Ticket Post ID
265
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
266
         */
267
        static public function CreateStaff(SWIFT_Ticket $_SWIFT_TicketObject, SWIFT_Staff $_SWIFT_StaffObject, $_creationMode,
268
                        $_contents, $_subject, $_dontSendEmail = false, $_isHTML = false, $_overrideFromEmail = '', $_isPrivate = false)
269
        {
270
                $_SWIFT = SWIFT::GetInstance();
271
272
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded() ||
273
                                !$_SWIFT_StaffObject instanceof SWIFT_Staff || !$_SWIFT_StaffObject->GetIsClassLoaded())
274
                {
275
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
276
                } else if (empty($_contents) || !SWIFT_Ticket::IsValidCreationMode($_creationMode)) {
277
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
278
                }
279
                // Notification Event
280
                $_SWIFT_TicketObject->NotificationManager->SetEvent('newstaffreply');
281
282
                // Retrieve the signature of the staff/queue
283
                $_signatureContentsDefault = $_SWIFT_TicketObject->GetSignature($_isHTML, $_SWIFT_StaffObject);
284
                $_signatureContentsHTML = $_SWIFT_TicketObject->GetSignature(true, $_SWIFT_StaffObject);
285
286
                // First create the ticket post
287
                $_finalPostContents = $_contents . SWIFT_CRLF . $_signatureContentsDefault;
288
                $_finalDispatchContents = $_contents . SWIFT_CRLF;
289
                $_ticketPostID = self::Create($_SWIFT_TicketObject, $_SWIFT_StaffObject->GetProperty('fullname'), $_SWIFT_StaffObject->GetProperty('email'),
290
                                $_finalPostContents, SWIFT_Ticket::CREATOR_STAFF, $_SWIFT_StaffObject->GetStaffID(), $_creationMode, $_subject, '', $_isHTML, false, false, DATENOW, $_isPrivate);
291
292
                // Clear overdue time?
293
                if ($_SWIFT->Settings->Get('t_slaresets') == '1')
294
                {
295
                        $_SWIFT_TicketObject->ClearOverdue();
296
                }
297
298
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
299
300
                $_SWIFT_TicketObject->ProcessPostAttachments($_SWIFT_TicketPostObject, 'replyattachments');
301
302
                if (!$_dontSendEmail && !$_isPrivate)
303
                {
304
                        // Carry out the email dispatch logic
305
                        $_SWIFT_TicketEmailDispatchObject = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
306
                        $_SWIFT_TicketEmailDispatchObject->DispatchStaffReply($_SWIFT_StaffObject, $_finalDispatchContents, $_isHTML, $_overrideFromEmail, array($_signatureContentsDefault, $_signatureContentsHTML));
307
                }
308
309
                return $_SWIFT_TicketPostObject;
310
        }
311
312
        /**
313
         * Create a Forward
314
         *
315
         * @author Varun Shoor
316
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
317
         * @param SWIFT_Staff $_SWIFT_StaffObject The SWIFT_Staff Object Pointer
318
         * @param constant $_creationMode The Creation Mode
319
         * @param string $_contents The Reply Contents
320
         * @param string $_subject The Reply Subject
321
         * @param string $_emailTo The Destination Email Address
322
         * @param bool $_dontSendEmail (OPTIONAL) Whether to send a email to client or not
323
         * @param bool $_isHTML (OPTIONAL) Whether the contents contain HTML data
324
         * @param string $_overrideFromEmail (OPTIONAL) Whether to override the from email address with the given address
325
         * @param bool $_isPrivate (OPTIONAL) Whether its private post
326
         * @return int Ticket Post ID
327
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
328
         */
329
        static public function CreateForward(SWIFT_Ticket $_SWIFT_TicketObject, SWIFT_Staff $_SWIFT_StaffObject, $_creationMode,
330
                        $_contents, $_subject, $_emailTo, $_dontSendEmail = false, $_isHTML = false, $_overrideFromEmail = '', $_isPrivate = false)
331
        {
332
                $_SWIFT = SWIFT::GetInstance();
333
334
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded() ||
335
                                !$_SWIFT_StaffObject instanceof SWIFT_Staff || !$_SWIFT_StaffObject->GetIsClassLoaded())
336
                {
337
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
338
                } else if (empty($_contents) || !SWIFT_Ticket::IsValidCreationMode($_creationMode)) {
339
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
340
                }
341
342
                // Retrieve the signature of the staff/queue
343
                $_signatureContentsDefault = $_SWIFT_TicketObject->GetSignature($_isHTML, $_SWIFT_StaffObject);
344
                $_signatureContentsHTML = $_SWIFT_TicketObject->GetSignature(true, $_SWIFT_StaffObject);
345
346
                // First create the ticket post
347
                $_finalDispatchContents = $_contents . SWIFT_CRLF;
348
                $_finalPostContents = $_contents . SWIFT_CRLF . $_signatureContentsDefault;
349
                $_ticketPostID = self::Create($_SWIFT_TicketObject, $_SWIFT_StaffObject->GetProperty('fullname'), $_SWIFT_StaffObject->GetProperty('email'),
350
                $_finalPostContents, SWIFT_Ticket::CREATOR_STAFF, $_SWIFT_StaffObject->GetStaffID(), $_creationMode, $_subject, $_emailTo, $_isHTML, true, false, DATENOW, $_isPrivate);
351
352
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
353
354
                $_SWIFT_TicketObject->ProcessPostAttachments($_SWIFT_TicketPostObject, 'forwardattachments');
355
356
                // Carry out the email dispatch logic
357
                if ($_dontSendEmail == false) {
358
                        $_SWIFT_TicketEmailDispatchObject = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
359
                        $_SWIFT_TicketEmailDispatchObject->DispatchForwardReply($_emailTo, $_SWIFT_StaffObject, $_finalDispatchContents, $_isHTML, $_overrideFromEmail, array($_signatureContentsDefault, $_signatureContentsHTML));
360
                }
361
362
                return $_ticketPostID;
363
        }
364
365
        /**
366
         * Create a Client Ticket Post
367
         *
368
         * @author Varun Shoor
369
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
370
         * @param SWIFT_User $_SWIFT_UserObject The SWIFT_User Object Pointer
371
         * @param constant $_creationMode The Creation Mode
372
         * @param string $_contents The Reply Contents
373
         * @param string $_subject The Reply Subject
374
         * @param constant $_creatorType The Creator Type
375
         * @param bool $_isHTML (OPTIONAL) Whether the contents contain HTML data
376
         * @param string $_customEmail (OPTIONAL) The custom email from which the post was received
377
         * @param string $_attachmentsContainer (OPTIONAL) The Attachments Container
378
         * @return int Ticket Post ID
379
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
380
         */
381
        static public function CreateClient(SWIFT_Ticket $_SWIFT_TicketObject, SWIFT_User $_SWIFT_UserObject, $_creationMode, $_contents, $_subject, $_creatorType,
382
                        $_isHTML = false, $_customEmail = '', $_attachmentsContainer = array())
383
        {
384
                $_SWIFT = SWIFT::GetInstance();
385
386
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded() ||
387
                                !$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded())
388
                {
389
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA . '2');
390
                } else if (empty($_contents) || !SWIFT_Ticket::IsValidCreationMode($_creationMode)) {
391
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA . '3');
392
                }
393
394
                $_ticketStatusCache = $_SWIFT->Cache->Get('statuscache');
395
396
                $_isThirdParty = false;
397
                if ($_creatorType == self::CREATOR_THIRDPARTY)
398
                {
399
                        $_isThirdParty = true;
400
                }
401
402
                $_finalEmail = '';
403
                if (empty($_customEmail))
404
                {
405
                        $_userEmailList = $_SWIFT_UserObject->GetEmailList();
406
                        $_finalEmail = $_userEmailList[0];
407
                } else {
408
                        $_finalEmail = $_customEmail;
409
                }
410
411
                // Notification Event
412
                $_SWIFT_TicketObject->NotificationManager->SetEvent('newclientreply');
413
414
                /*
415
                 * BUG FIX - Varun Shoor
416
                 *
417
                 * SWIFT-1140 "Ticket Status (Post Parse)" criteria does not work
418
                 *
419
                 * Comments: Added has status changed property to make sure that this does not override the status set by parser rule
420
                 */
421
                if (isset($_ticketStatusCache[$_SWIFT->Settings->Get('t_cstatusupd')]) && $_SWIFT_TicketObject->GetHasStatusChanged() == false)
422
                {
423
                        $_SWIFT_TicketObject->SetStatus($_SWIFT->Settings->Get('t_cstatusupd'));
424
                }
425
426
                // First create the ticket post
427
                $_finalPostContents = $_contents;
428
                $_ticketPostID = self::Create($_SWIFT_TicketObject, $_SWIFT_UserObject->GetProperty('fullname'), $_finalEmail,
429
                                $_finalPostContents, $_creatorType, $_SWIFT_UserObject->GetUserID(), $_creationMode, $_subject, '', $_isHTML, $_isThirdParty);
430
431
                // Execute SLA
432
                /*
433
                 * BUG FIX - Varun Shoor
434
                 *
435
                 * SWIFT-2563 Resolution time gets reset on ticket after every client reply
436
                 *
437
                 */
438
                $_SWIFT_TicketObject->ExecuteSLA(false);
439
440
                // Carry out the email dispatch logic
441
442
                /*
443
                 * BUG FIX - Varun Shoor
444
                 *
445
                 * SWIFT-1736 Help desk should not send reply to recipient address if it is already added in the email as CC or TO
446
                 *
447
                 * Comments: Dont send the emails to other recipients if the creation mode is email. This prevents the system from sending duplicate replies to other recipients.
448
                 */
449
                if ($_creationMode != SWIFT_Ticket::CREATIONMODE_EMAIL) {
450
                        $_SWIFT_TicketEmailDispatchObject = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
451
                        $_SWIFT_TicketEmailDispatchObject->DispatchUserReply($_SWIFT_UserObject, $_contents, $_isHTML, $_attachmentsContainer, $_finalEmail, $_isThirdParty);
452
                }
453
454
                return $_ticketPostID;
455
        }
456
457
        /**
458
         * Create a Client Ticket Post
459
         *
460
         * @author Varun Shoor
461
         * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
462
         * @param SWIFT_User $_SWIFT_UserObject The SWIFT_User Object Pointer
463
         * @param constant $_creationMode The Creation Mode
464
         * @param string $_contents The Reply Contents
465
         * @param string $_subject The Reply Subject
466
         * @param constant $_creatorType The Creator Type
467
         * @param bool $_isHTML (OPTIONAL) Whether the contents contain HTML data
468
         * @param string $_customEmail (OPTIONAL) The custom email from which the post was received
469
         * @return int Ticket Post ID
470
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
471
         */
472
        static public function CreateClientSurvey(SWIFT_Ticket $_SWIFT_TicketObject, SWIFT_User $_SWIFT_UserObject, $_creationMode, $_contents, $_subject, $_creatorType,
473
                        $_isHTML = false, $_customEmail = '')
474
        {
475
                $_SWIFT = SWIFT::GetInstance();
476
477
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded() ||
478
                                !$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded())
479
                {
480
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA . '2');
481
                } else if (empty($_contents) || !SWIFT_Ticket::IsValidCreationMode($_creationMode)) {
482
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA . '3');
483
                }
484
485
                $_isThirdParty = false;
486
                if ($_creatorType == self::CREATOR_THIRDPARTY)
487
                {
488
                        $_isThirdParty = true;
489
                }
490
491
                $_finalEmail = '';
492
                if (empty($_customEmail))
493
                {
494
                        $_userEmailList = $_SWIFT_UserObject->GetEmailList();
495
                        $_finalEmail = $_userEmailList[0];
496
                } else {
497
                        $_finalEmail = $_customEmail;
498
                }
499
500
                // Notification Event
501
                $_SWIFT_TicketObject->NotificationManager->SetEvent('newclientsurvey');
502
503
                // First create the ticket post
504
                $_finalPostContents = $_contents;
505
                $_ticketPostID = self::Create($_SWIFT_TicketObject, $_SWIFT_UserObject->GetProperty('fullname'), $_finalEmail,
506
                                $_finalPostContents, $_creatorType, $_SWIFT_UserObject->GetUserID(), $_creationMode, $_subject, '', $_isHTML, $_isThirdParty, true);
507
508
                return $_ticketPostID;
509
        }
510
511
        /**
512
         * Create a new Ticket Post
513
         *
514
         * @author Varun Shoor
515
         * @param object $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
516
         * @param string $_fullName The Fullname
517
         * @param string $_email The Email Address
518
         * @param string $_contents The contents of the post
519
         * @param constant $_creatorType The Creator Type
520
         * @param int $_creatorID The Creator ID
521
         * @param constant $_creationMode The Creation Mode
522
         * @param string $_subject (OPTIONAL) The Subject
523
         * @param string $_emailTo (OPTIONAL) The Email to which this post was received for, generally the email address of the queue
524
         * @param bool $_isHTML (OPTIONAL) Whether this is a HTML post
525
         * @param bool $_isThirdParty (OPTIONAL) Whether its a third party reply
526
         * @param bool $_isSurveyComment (OPTIONAL) Whether its a survey comment
527
         * @param bool $_isPrivate (OPTIONAL) Whether its private post
528
         * @return mixed "_ticketPostID" (INT) on Success, "false" otherwise
529
         * @throws SWIFT_Ticket_Exception If Invalid Data is Provided or If the Object could not be created
530
         */
531
        static public function Create(SWIFT_Ticket $_SWIFT_TicketObject, $_fullName, $_email, $_contents, $_creatorType, $_creatorID, $_creationMode,
532
                        $_subject, $_emailTo = '', $_isHTML = false, $_isThirdParty = false, $_isSurveyComment = false, $_dateline = DATENOW, $_isPrivate = false)
533
        {
534
                $_SWIFT = SWIFT::GetInstance();
535
536
                $_creatorID = intval($_creatorID);
537
538
                if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded() || empty($_fullName) || empty($_email) ||
539
                                $_contents == '' || !self::IsValidCreatorType($_creatorType) ||
540
                                !SWIFT_Ticket::IsValidCreationMode($_creationMode))
541
                {
542
                        throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA . '4');
543
544
                        return false;
545
                }
546
547
                $_staffID = $_userID = 0;
548
                if ($_creatorType == SWIFT_Ticket::CREATOR_STAFF)
549
                {
550
                        $_staffID = intval($_creatorID);
551
                } else if ($_creatorType == SWIFT_Ticket::CREATOR_USER) {
552
                        $_userID = intval($_creatorID);
553
                }
554
555
                $_isEmailed = false;
556
                if ($_creationMode == SWIFT_Ticket::CREATIONMODE_EMAIL)
557
                {
558
                        $_isEmailed = true;
559
                }
560
561
                $_ipAddress = '';
562
                if ($_SWIFT->Interface->GetInterface() != SWIFT_Interface::INTERFACE_CRON && $_SWIFT->Interface->GetInterface() != SWIFT_Interface::INTERFACE_CONSOLE)
563
                {
564
                        $_ipAddress = SWIFT::Get('IP');
565
                }
566
567
                $_responseTime = 0;
568
569
                // Calculate average response time
570
                // Does this ticket have a last post?
571
                if ($_SWIFT_TicketObject->GetProperty('lastpostid') != '0') {
572
                        try {
573
                                $_SWIFT_TicketPostObject_Avg = new SWIFT_TicketPost(new SWIFT_DataID($_SWIFT_TicketObject->GetProperty('lastpostid')));
574
                                $_responseTime = DATENOW - $_SWIFT_TicketPostObject_Avg->GetProperty('dateline');
575
576
                                // Was the last post by client?
577
                                if ($_creatorType == self::CREATOR_STAFF && $_SWIFT_TicketPostObject_Avg->GetProperty('creator') != self::CREATOR_STAFF) {
578
                                        $_SWIFT_TicketObject->UpdateAverageResponseTime($_responseTime);
579
                                }
580
                        } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
581
                        }
582
                }
583
584
                $_firstResponseTime = 0;
585
586
                // The creator of post is staff, first response time is empty AND we have a last post.. and the total replies is less than four
587
                if ($_creatorType == self::CREATOR_STAFF && $_SWIFT_TicketObject->GetProperty('firstresponsetime') == '0' && $_SWIFT_TicketObject->GetProperty('lastpostid') != '0' && $_SWIFT_TicketObject->GetProperty('totalreplies') <= 4 && $_isPrivate == false) {
588
                        $_firstResponseTime = DATENOW - $_SWIFT_TicketObject->GetProperty('dateline');
589
                }
590
591
                $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'ticketposts', array('ticketid' => intval($_SWIFT_TicketObject->GetTicketID()),
592
                        'fullname' => $_fullName, 'email' => mb_strtolower($_email), 'emailto' => mb_strtolower($_emailTo), 'subject' => $_subject, 'ipaddress' => $_ipAddress,
593
                        'creator' => intval($_creatorType), 'isemailed' => intval($_isEmailed), 'staffid' => intval($_staffID), 'userid' => intval($_userID),
594
                        'contents' => $_contents, 'contenthash' => sha1($_contents), 'subjecthash' => sha1($_subject), 'creationmode' => intval($_creationMode),
595
                        'dateline' => $_dateline, 'ishtml' => intval($_isHTML), 'isthirdparty' => intval($_isThirdParty), 'issurveycomment' => intval($_isSurveyComment),
596
                        'responsetime' => intval($_responseTime), 'firstresponsetime' => intval($_firstResponseTime), 'isprivate' => intval($_isPrivate)),
597
                                'INSERT');
598
                $_ticketPostID = $_SWIFT->Database->Insert_ID();
599
600
                if (!$_ticketPostID)
601
                {
602
                        throw new SWIFT_Ticket_Exception(SWIFT_CREATEFAILED);
603
604
                        return false;
605
                }
606
607
                $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
608
609
                if (!empty($_firstResponseTime)) {
610
                        $_SWIFT_TicketObject->UpdatePool('firstresponsetime', intval($_firstResponseTime));
611
                }
612
613
                $_SWIFT_TicketObject->UpdatePool('lastpostid', intval($_ticketPostID));
614
                $_SWIFT_TicketObject->UpdatePool('lastactivity', DATENOW);
615
                $_SWIFT_TicketObject->UpdatePool('lastreplier', $_fullName);
616
                $_SWIFT_TicketObject->UpdatePool('autoclosestatus', SWIFT_Ticket::AUTOCLOSESTATUS_NONE);
617
                $_SWIFT_TicketObject->UpdatePool('autoclosetimeline', '0');
618
619
                if ($_creatorType == SWIFT_Ticket::CREATOR_STAFF && $_isPrivate == false)
620
                {
621
                        $_SWIFT_TicketObject->UpdatePool('laststaffreplytime', DATENOW);
622
                } else if ($_creatorType == SWIFT_Ticket::CREATOR_USER) {
623
                        $_SWIFT_TicketObject->UpdatePool('lastuserreplytime', DATENOW);
624
                }
625
626
                if ($_isPrivate == false)
627
                {
628
                        $_totalTicketReplies = intval($_SWIFT_TicketObject->GetProperty('totalreplies'));
629
                        $_SWIFT_TicketObject->UpdatePool('totalreplies', $_totalTicketReplies + 1);
630
                }
631
632
                $_SWIFT_TicketObject->SetWatcherProperties($_fullName, sprintf($_SWIFT->Language->Get('watcherprefix'), $_fullName, $_email) . SWIFT_CRLF . $_contents);
633
634
635
                // Index the words in the post for searching
636
                $eng = new SWIFT_SearchEngine();
637
                $eng->Insert($_SWIFT_TicketObject->GetTicketID(), $_ticketPostID, SWIFT_SearchEngine::TYPE_TICKET, $_contents);
638
639
                // Create unique message id
640
                SWIFT_TicketMessageID::Create($_SWIFT_TicketObject, $_SWIFT_TicketPostObject);
641
642
                /*
643
                 * BUG FIX - Varun Shoor
644
                 *
645
                 * SWIFT-1609 ticketpostid is always set 0 in swticketauditlogs table
646
                 */
647
                // Create Audit Log
648
                SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, $_SWIFT_TicketPostObject, SWIFT_TicketAuditLog::ACTION_NEWTICKETPOST,
649
                                sprintf($_SWIFT->Language->Get('al_newreply'), $_fullName, $_email), SWIFT_TicketAuditLog::VALUE_NONE, 0, '',
650
                                0, '');
651
652
                return $_ticketPostID;
653
        }
654
655
        /**
656
         * Update the Ticket Post Record
657
         *
658
         * @author Varun Shoor
659
         * @param string $_contents The Ticket Post Contents
660
         * @param int $_staffID (OPTIONAL) The Staff ID making the change
661
         * @return bool "true" on Success, "false" otherwise
662
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
663
         */
664
        public function Update($_contents, $_staffID = 0)
665
        {
666
                if (!$this->GetIsClassLoaded())
667
                {
668
                        throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
669
670
                        return false;
671
                }
672
673
                // Search engine index
674
                $eng = new SWIFT_SearchEngine();
675
                $eng->Update($this->GetProperty('ticketid'), $this->GetProperty('ticketpostid'), SWIFT_SearchEngine::TYPE_TICKET, $_contents);
676
677
                $this->UpdatePool('contents', $_contents);
678
                $this->UpdatePool('contenthash', sha1($_contents));
679
                $this->UpdatePool('edited', '1');
680
                $this->UpdatePool('editedbystaffid', intval($_staffID));
681
                $this->UpdatePool('editeddateline', DATENOW);
682
683
                $this->ProcessUpdatePool();
684
685
                return true;
686
        }
687
688
        /**
689
         * Retrieve the display contents for this ticket post
690
         *
691
         * @author Varun Shoor
692
         * @return string The display contents
693
         * @throws SWIFT_Exception If the Class is not Loaded
694
         */
695
        public function GetDisplayContents() {
696
                if (!$this->GetIsClassLoaded()) {
697
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
698
699
                        return false;
700
                }
701
702
                $_parsedContents = '';
703
704
                // Staff Creator?
705
                if ($this->GetProperty('creator') == SWIFT_Ticket::CREATOR_STAFF) {
706
                        $_parsedContents = self::GetParsedContents($this->GetProperty('contents'), $this->Settings->Get('t_ochtml'), intval($this->GetProperty('ishtml')));
707
                        if ($this->GetProperty('ishtml') == '0' || $this->Settings->Get('t_chtml') == 'strip' || $this->Settings->Get('t_chtml') == 'entities') {
708
                                $_parsedContents = nl2br($_parsedContents);
709
710
                        }
711
712
                // Client Creator?
713
                } else {
714
                        $_parsedContents = self::GetParsedContents($this->GetProperty('contents'), $this->Settings->Get('t_chtml'), intval($this->GetProperty('ishtml')));
715
                        if ($this->GetProperty('ishtml') == '0' || $this->Settings->Get('t_chtml') == 'strip' || $this->Settings->Get('t_chtml') == 'entities') {
716
                                $_parsedContents = nl2br($_parsedContents);
717
718
                        }
719
                }
720
721
                // Always strip javascript out of the contents.. ALWAYS!
722
                $_parsedContents = strip_javascript($_parsedContents);
723
724
                return $_parsedContents;
725
        }
726
727
728
        /**
729
         * Retrieve the parsed contents
730
         *
731
         * @author Varun Shoor
732
         * @param string $_contents The Contents to Parse
733
         * @param string $_settingValue The Setting Value
734
         * @param bool $_isContentHTML
735
         * @param string $_overrideAllowableTags (OPTIONAL)
736
         * @return bool "true" on Success, "false" otherwise
737
         * @throws SWIFT_Exception If Invalid Data is Provided
738
         */
739
        static public function GetParsedContents($_contents, $_settingValue, $_isContentHTML = false, $_overrideAllowableTags = false) {
740
                $_SWIFT = SWIFT::GetInstance();
741
742
                $_SWIFT_StringHTMLToTextObject = new SWIFT_StringHTMLToText();
743
744
                /*
745
                 * BUG FIX - Varun Shoor
746
                 *
747
                 * SWIFT-1826 Replies that contain the code <base href="x-msg://27/"> , does not allow ticket tabs to work properly
748
                 *
749
                 * Comments: Cleanup base tags
750
                 */
751
                $_searchBase = array('@<base[^>]*?>@si');
752
                $_contents = preg_replace($_searchBase, '', $_contents);
753
754
755
                // SWIFT-393 - If no HTML is present, no need to strip.
756
                if (!preg_match("/([\<])([^\>]{1,})*([\>])/i", $_contents))
757
                {
758
                        $_settingValue = 'entities';
759
                }
760
761
                /*
762
                 * BUG FIX - Varun Shoor
763
                 *
764
                 * SWIFT-1377 Any text between angular brackets is stripped even if it arrives in text part of email.
765
                 * SWIFT-1752 Encoded entities appearing in ticket posts
766
                 *
767
                 * Comments: If we dont find the base HTML tags and the mode is set to strip, then we force it to use entities. This prevents any false tag cleanup from the system.
768
                 */
769
                if ($_settingValue == 'strip' && !preg_match("/<(\s+)?(div|p|span|br)([\s]+(.*)|[\s]*\/)?(\s+)?>/i", $_contents) && $_SWIFT->Interface->GetInterface() != SWIFT_Interface::INTERFACE_STAFFAPI) {
770
                        $_settingValue = 'entities';
771
                }
772
773
                switch ($_settingValue) {
774
                        case 'entities':
775
                                // If its HTML, try to convert to readable text first
776
                                if ($_isContentHTML) {
777
                                        $_contents = $_SWIFT_StringHTMLToTextObject->Convert($_contents);
778
                                }
779
780
                                return AutoLink(htmlspecialchars($_contents));
781
                                break;
782
783
                        case 'htmlpurifier':
784
                        {
785
                                return $_contents;
786
787
                                $_SWIFT_HTMLPurifierObject = $_SWIFT->HTMLPurifier;
788
                                if (!$_SWIFT->HTMLPurifier instanceof SWIFT_HTMLPurifier) {
789
                                        $_SWIFT_HTMLPurifierObject = new SWIFT_HTMLPurifier();
790
                                        $_SWIFT->SetClass('HTMLPurifier', $_SWIFT_HTMLPurifierObject);
791
                                }
792
793
                                return $_SWIFT_HTMLPurifierObject->Purify($_contents);
794
                        }
795
796
                        case 'html':
797
                                /*
798
                                 * BUG FIX - Varun Shoor
799
                                 *
800
                                 * SWIFT-1780 In case of No processing, style tag should be removed from the contents
801
                                 *
802
                                 * Comments: Strip style tags completely
803
                                 */
804
                                /*
805
                                 * BUG FIX - Parminder Singh
806
                                 *
807
                                 * SWIFT-2162: Extra line spaces are showing in ticket post, if we send an email from outlook
808
                                 *
809
                                 */
810
                                /*$_search = array('@<style[^>]*?>.*?</style>@si');
811
                                $_contents = preg_replace($_search, '', $_contents);*/
812
                                return $_contents;
813
814
                        case 'strip':
815
                                {
816
                                        $_preAllowableTags = $_allowableTags = $_allowableTagsAttributes = '';
817
818
                                        if ($_SWIFT->Settings->Get('t_allowhtml') == '1') {
819
                                                $_preAllowableTags = $_SWIFT->Settings->Get('t_allowableadvtags');
820
                                                $_allowableTagsAttributes = $_SWIFT->Settings->Get('t_allowableadvtagsattributes');
821
                                        }
822
823
                                        if ($_overrideAllowableTags !== false) {
824
                                                $_preAllowableTags = $_overrideAllowableTags;
825
                                        }
826
827
                                        if (strstr($_preAllowableTags, ',')) {
828
                                                $_tagsContainer = explode(',', $_preAllowableTags);
829
                                                foreach ($_tagsContainer as $_tagName) {
830
                                                        $_allowableTags .= '<' . Clean(trim($_tagName)) . '>';
831
                                                }
832
                                        } else if (!empty($_preAllowableTags)) {
833
                                                $_allowableTags = '<' . Clean($_preAllowableTags) . '>';
834
                                        }
835
836
                                        /*
837
                                         * BUG FIX - Varun Shoor
838
                                         *
839
                                         * SWIFT-1472 In case of strip tags, <style> tag does not process correctly.
840
                                         *
841
                                         * Comments: None
842
                                         */
843
                                        if (!strstr($_allowableTags, '<style>')) {
844
                                                // Strip style tags properly
845
                                                $_search = array('@<style[^>]*?>.*?</style>@si');
846
                                                $_contents = preg_replace($_search, '', $_contents);
847
                                        }
848
849
                                        /*
850
                                         * BUG FIX - Varun Shoor
851
                                         *
852
                                         * SWIFT-1473 Software does not process <br/> and <br /> tags, in case of strip tags.
853
                                         *
854
                                         * Comments: None
855
                                         */
856
                                        $_contents = preg_replace('/<(\s+)?br(\s+)?(\/)?>/i', '<br>', $_contents);
857
858
                                        // strip_tags() appears to become nauseated at the site of a <!DOCTYPE> declaration (Ref: http://php.net/manual/en/function.strip-tags.php)
859
                                        $_contents = str_replace('<!DOCTYPE', '<DOCTYPE', $_contents);
860
861
                                        /*
862
                                         * BUG FIX - Varun Shoor
863
                                         *
864
                                         * SWIFT-1674 Replies/Tickets from Outlook render with an abnormal amount of line spaces and broken HTML tags
865
                                         *
866
                                         * Comments: None
867
                                         */
868
                                        return preg_replace('/\n{2,}/', "\n\n", strip_tags_attributes($_contents, $_allowableTags, $_allowableTagsAttributes));
869
                                }
870
871
                        default:
872
                                break;
873
                }
874
875
                return false;
876
        }
877
878
        /**
879
         * Delete the Ticket Post record
880
         *
881
         * @author Varun Shoor
882
         * @return bool "true" on Success, "false" otherwise
883
         * @throws SWIFT_Ticket_Exception If the Class is not Loaded
884
         */
885
        public function Delete()
886
        {
887
                if (!$this->GetIsClassLoaded())
888
                {
889
                        throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
890
891
                        return false;
892
                }
893
894
                self::DeleteList(array($this->GetTicketPostID()));
895
896
                $this->SetIsClassLoaded(false);
897
898
                return true;
899
        }
900
901
        /**
902
         * Delete a list of Ticket Posts
903
         *
904
         * @author Varun Shoor
905
         * @param array $_ticketPostIDList The Ticket Post ID List
906
         * @return bool "true" on Success, "false" otherwise
907
         */
908
        static public function DeleteList($_ticketPostIDList)
909
        {
910
                $_SWIFT = SWIFT::GetInstance();
911
912
                if (!_is_array($_ticketPostIDList))
913
                {
914
                        return false;
915
                }
916
917
                $_finalTicketPostIDList = array();
918
                $_SWIFT->Database->Query("SELECT ticketpostid FROM " . TABLE_PREFIX . "ticketposts WHERE ticketpostid IN (" . BuildIN($_ticketPostIDList) .
919
                                ")");
920
                while ($_SWIFT->Database->NextRecord())
921
                {
922
                        $_finalTicketPostIDList[] = intval($_SWIFT->Database->Record['ticketpostid']);
923
                }
924
925
                if (!count($_finalTicketPostIDList))
926
                {
927
                        return false;
928
                }
929
930
                $_SWIFT->Database->Query("DELETE FROM " . TABLE_PREFIX . "ticketposts WHERE ticketpostid IN (" . BuildIN($_finalTicketPostIDList) . ")");
931
932
                // Clear Attachments
933
                SWIFT_Attachment::DeleteOnTicketPost($_finalTicketPostIDList);
934
935
                // Clear Notes
936
                SWIFT_TicketPostNote::DeleteOnTicketPost($_finalTicketPostIDList);
937
938
                return true;
939
        }
940
941
        /**
942
         * Delete list of ticket posts based on list of ticket ids
943
         *
944
         * @author Varun Shoor
945
         * @param array $_ticketIDList The Ticket ID List
946
         * @return bool "true" on Success, "false" otherwise
947
         */
948
        static public function DeleteOnTicket($_ticketIDList)
949
        {
950
                $_SWIFT = SWIFT::GetInstance();
951
952
                if (!_is_array($_ticketIDList))
953
                {
954
                        return false;
955
                }
956
957
                $_ticketPostIDList = array();
958
                $_SWIFT->Database->Query("SELECT ticketpostid FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
959
                while ($_SWIFT->Database->NextRecord())
960
                {
961
                        $_ticketPostIDList[] = intval($_SWIFT->Database->Record['ticketpostid']);
962
                }
963
964
                if (!count($_ticketPostIDList))
965
                {
966
                        return false;
967
                }
968
969
                // Search engine index
970
                //
971
                // We're nuking all of these ticket posts, based on ticket IDs.
972
                // In the search index, tickets are objects and ticket posts are sub-objects.
973
                // So, what we do is delete all of the objects (tickets) and the posts go with them.
974
                // No other data about tickets is stored in the index
975
                $eng = new SWIFT_SearchEngine();
976
                $eng->DeleteList($_ticketIDList, SWIFT_SearchEngine::TYPE_TICKET);
977
978
                self::DeleteList($_ticketPostIDList);
979
980
                return true;
981
        }
982
983
        /**
984
         * Replace the current ticket id all tickets with the new one
985
         *
986
         * @author Varun Shoor
987
         * @param array $_ticketIDList The Old Ticket ID List
988
         * @param SWIFT_Ticket $_SWIFT_ParentTicketObject The Parent Ticket Object
989
         * @return bool "true" on Success, "false" otherwise
990
         * @throws SWIFT_Exception If Invalid Data is Provided
991
         */
992
        static public function ReplaceTicket($_ticketIDList, SWIFT_Ticket $_SWIFT_ParentTicketObject) {
993
                $_SWIFT = SWIFT::GetInstance();
994
995
                if (!$_SWIFT_ParentTicketObject instanceof SWIFT_Ticket || !$_SWIFT_ParentTicketObject->GetIsClassLoaded()) {
996
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
997
                }
998
999
                if (!_is_array($_ticketIDList)) {
1000
                        return false;
1001
                }
1002
1003
                $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'ticketposts', array('ticketid' => intval($_SWIFT_ParentTicketObject->GetTicketID())), 'UPDATE', "ticketid IN (" . BuildIN($_ticketIDList) . ")");
1004
1005
                return true;
1006
        }
1007
1008
        /**
1009
         * Retrieve the processed HTML & Text Contents
1010
         *
1011
         * @author Varun Shoor
1012
         * @param string $_contents The Real Contents
1013
         * @param bool $_isHTML Whether the content is HTML
1014
         * @return array array(text contents, html contents)
1015
         * @throws SWIFT_Exception If Invalid Data is Provided
1016
         */
1017
        static public function RetrieveProcessedContent($_contents, $_isHTML)
1018
        {
1019
                $_textContents = $_htmlContents = '';
1020
1021
                if ($_isHTML == true)
1022
                {
1023
                        $_textContents = strip_tags(br2nl($_contents));
1024
                        $_htmlContents = $_contents;
1025
                } else {
1026
                        $_textContents = $_contents;
1027
                        $_htmlContents = nl2br(htmlspecialchars($_contents));
1028
                }
1029
1030
                return array($_textContents, $_htmlContents);
1031
        }
1032
1033
        /**
1034
         * Retrieve contents for quote dispatch
1035
         *
1036
         * @author Varun Shoor
1037
         * @return string The Quote Contents
1038
         * @throws SWIFT_Exception If the Class is not Loaded
1039
         */
1040
        public function GetQuoteContents()
1041
        {
1042
                if (!$this->GetIsClassLoaded())
1043
                {
1044
                        throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
1045
1046
                        return false;
1047
                }
1048
1049
                $_SWIFT_StringHTMLToTextObject = new SWIFT_StringHTMLToText();
1050
1051
                /*
1052
                 * BUG FIX - Varun Shoor
1053
                 *
1054
                 * SWIFT-1499 Quote button removes the line breakes while we quote the ticket post in staff CP
1055
                 *
1056
                 */
1057
                $_finalContents = $_SWIFT_StringHTMLToTextObject->Convert(preg_replace("#(\r\n|\r|\n)#s", "<br>", $this->GetProperty('contents')), false);
1058
1059
                $_finalContentsContainer = explode(SWIFT_CRLF, $_finalContents);
1060
1061
                $_dispatchContents = '';
1062
                foreach ($_finalContentsContainer as $_line)
1063
                {
1064
                        $_dispatchContents .= ' > ' . $_line . SWIFT_CRLF;
1065
                }
1066
1067
                return $_dispatchContents;
1068
        }
1069
1070
        /**
1071
         * Retrieve the total ticket post count
1072
         *
1073
         * @author Varun Shoor
1074
         * @return int The Total Ticket Post Count
1075
         */
1076
        static public function GetPostCount()
1077
        {
1078
                $_SWIFT = SWIFT::GetInstance();
1079
1080
                $_ticketPostCount = $_SWIFT->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "ticketposts");
1081
                if (isset($_ticketPostCount['totalitems']))
1082
                {
1083
                        return intval($_ticketPostCount['totalitems']);
1084
                }
1085
1086
                return 0;
1087
        }
1088
1089
        /**
1090
         * Update the Full Name and Email on Ticket & User ID
1091
         *
1092
         * @author Varun Shoor
1093
         * @param int $_ticketID
1094
         * @param int $_existingUserID
1095
         * @param int $_newUserID
1096
         * @param int $_newFullName
1097
         * @param int $_newEmail
1098
         * @return bool "true" on Success, "false" otherwise
1099
         * @throws SWIFT_Exception If Invalid Data is Provided
1100
         */
1101
        static public function UpdateFullnameAndEmailOnTicketUser($_ticketID, $_existingUserID, $_newUserID, $_newFullName, $_newEmail)
1102
        {
1103
                $_SWIFT = SWIFT::GetInstance();
1104
1105
                if (empty($_ticketID)) {
1106
                        throw new SWIFT_Exception(SWIFT_INVALIDDATA);
1107
                }
1108
1109
                $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'ticketposts', array('userid' => intval($_newUserID), 'fullname' => $_newFullName, 'email' => $_newEmail), 'UPDATE', "ticketid = '" . intval($_ticketID) . "' AND userid = '" . intval($_existingUserID) . "'");
1110
1111
                return true;
1112
        }
1113
1114
    /**
1115
     * Update has attachments property of ticket post
1116
     *
1117
     * @author Ruchi Kothari
1118
     * @param int $_hasAttachments Has Attachment Value(0 or 1)
1119
     * @return bool "true" on Success, "false" otherwise
1120
     * @throws SWIFT_Exception If the Class is not Loaded
1121
     */
1122
    public function UpdateHasAttachments($_hasAttachments)
1123
    {
1124
        if (!$this->GetIsClassLoaded()) {
1125
            throw new SWIFT_Exception(__CLASS__ . ':  ' . SWIFT_CLASSNOTLOADED);
1126
        }
1127
1128
        $this->UpdatePool('hasattachments', intval($_hasAttachments));
1129
        $this->ProcessUpdatePool();
1130
1131
        return true;
1132
    }
1133
1134
}
1135
?>