| 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 Model Class
|
| 20 | *
|
| 21 | * @author Varun Shoor
|
| 22 | */
|
| 23 | class SWIFT_Ticket extends SWIFT_Model
|
| 24 | {
|
| 25 | const TABLE_NAME = 'tickets';
|
| 26 | const PRIMARY_KEY = 'ticketid';
|
| 27 |
|
| 28 | const TABLE_STRUCTURE = "ticketid I PRIMARY AUTO NOTNULL,
|
| 29 | ticketmaskid C(20) DEFAULT '' NOTNULL,
|
| 30 | departmentid I DEFAULT '0' NOTNULL,
|
| 31 | departmenttitle C(255) DEFAULT '' NOTNULL,
|
| 32 | ticketstatusid I DEFAULT '0' NOTNULL,
|
| 33 | ticketstatustitle C(255) DEFAULT '' NOTNULL,
|
| 34 | priorityid I DEFAULT '0' NOTNULL,
|
| 35 | prioritytitle C(255) DEFAULT '' NOTNULL,
|
| 36 | emailqueueid I DEFAULT '0' NOTNULL,
|
| 37 | userid I DEFAULT '0' NOTNULL,
|
| 38 | staffid I DEFAULT '0' NOTNULL,
|
| 39 | ownerstaffid I DEFAULT '0' NOTNULL,
|
| 40 | ownerstaffname C(255) DEFAULT '' NOTNULL,
|
| 41 | assignstatus I2 DEFAULT '0' NOTNULL,
|
| 42 |
|
| 43 | fullname C(225) DEFAULT '' NOTNULL,
|
| 44 | email C(150) DEFAULT '' NOTNULL,
|
| 45 | lastreplier C(255) DEFAULT '' NOTNULL,
|
| 46 | replyto C(150) DEFAULT '' NOTNULL,
|
| 47 | subject C(255) DEFAULT '' NOTNULL,
|
| 48 | dateline I DEFAULT '0' NOTNULL,
|
| 49 | lastactivity I DEFAULT '0' NOTNULL,
|
| 50 | laststaffreplytime I DEFAULT '0' NOTNULL,
|
| 51 | lastuserreplytime I DEFAULT '0' NOTNULL,
|
| 52 | slaplanid I DEFAULT '0' NOTNULL,
|
| 53 | ticketslaplanid I DEFAULT '0' NOTNULL,
|
| 54 | duetime I DEFAULT '0' NOTNULL,
|
| 55 | totalreplies I DEFAULT '0' NOTNULL,
|
| 56 | ipaddress C(50) DEFAULT '0.0.0.0' NOTNULL,
|
| 57 | flagtype I2 DEFAULT '0' NOTNULL,
|
| 58 | hasnotes I2 DEFAULT '0' NOTNULL,
|
| 59 | hasattachments I2 DEFAULT '0' NOTNULL,
|
| 60 | isemailed I2 DEFAULT '0' NOTNULL,
|
| 61 | edited I2 DEFAULT '0' NOTNULL,
|
| 62 | editedbystaffid I DEFAULT '0' NOTNULL,
|
| 63 | editeddateline I DEFAULT '0' NOTNULL,
|
| 64 | creator I2 DEFAULT '0' NOTNULL,
|
| 65 | charset C(100) DEFAULT '' NOTNULL,
|
| 66 | transferencoding C(50) DEFAULT '' NOTNULL,
|
| 67 | timeworked I DEFAULT '0' NOTNULL,
|
| 68 | timebilled I DEFAULT '0' NOTNULL,
|
| 69 | dateicon I DEFAULT '0' NOTNULL,
|
| 70 | lastpostid I DEFAULT '0' NOTNULL,
|
| 71 | firstpostid I DEFAULT '0' NOTNULL,
|
| 72 | tgroupid I DEFAULT '0' NOTNULL,
|
| 73 | messageid C(17) DEFAULT '' NOTNULL,
|
| 74 | escalationruleid I DEFAULT '0' NOTNULL,
|
| 75 | hasdraft I2 DEFAULT '0' NOTNULL,
|
| 76 | hasbilling I2 DEFAULT '0' NOTNULL,
|
| 77 | isphonecall I2 DEFAULT '0' NOTNULL,
|
| 78 | isescalated I2 DEFAULT '0' NOTNULL,
|
| 79 | isescalatedvolatile I2 DEFAULT '0' NOTNULL,
|
| 80 | phoneno C(255) DEFAULT '' NOTNULL,
|
| 81 |
|
| 82 | isautoclosed I2 DEFAULT '0' NOTNULL,
|
| 83 | autocloseruleid I DEFAULT '0' NOTNULL,
|
| 84 | autoclosestatus I2 DEFAULT '0' NOTNULL,
|
| 85 | autoclosetimeline I DEFAULT '0' NOTNULL,
|
| 86 |
|
| 87 | escalatedtime I DEFAULT '0' NOTNULL,
|
| 88 | followupcount I DEFAULT '0' NOTNULL,
|
| 89 | hasfollowup I2 DEFAULT '0' NOTNULL,
|
| 90 |
|
| 91 | hasratings I2 DEFAULT '0' NOTNULL,
|
| 92 | tickethash C(50) DEFAULT '' NOTNULL,
|
| 93 | islinked I2 DEFAULT '0' NOTNULL,
|
| 94 | trasholddepartmentid I DEFAULT '0' NOT NULL,
|
| 95 | tickettype I2 DEFAULT '0' NOTNULL,
|
| 96 | tickettypeid I DEFAULT '0' NOTNULL,
|
| 97 | tickettypetitle C(255) DEFAULT '' NOTNULL,
|
| 98 | creationmode I2 DEFAULT '0' NOTNULL,
|
| 99 |
|
| 100 | isfirstcontactresolved I2 DEFAULT '0' NOTNULL,
|
| 101 | wasreopened I2 DEFAULT '0' NOTNULL,
|
| 102 | reopendateline I DEFAULT '0' NOTNULL,
|
| 103 | resolutiondateline I DEFAULT '0' NOTNULL,
|
| 104 | escalationlevelcount I DEFAULT '0' NOTNULL,
|
| 105 | resolutionseconds I DEFAULT '0' NOTNULL,
|
| 106 | resolutionlevel I DEFAULT '0' NOTNULL,
|
| 107 | repliestoresolution I DEFAULT '0' NOTNULL,
|
| 108 |
|
| 109 | averageresponsetime I DEFAULT '0' NOTNULL,
|
| 110 | averageresponsetimehits I DEFAULT '0' NOTNULL,
|
| 111 | firstresponsetime I DEFAULT '0' NOTNULL,
|
| 112 |
|
| 113 | resolutionduedateline I DEFAULT '0' NOTNULL,
|
| 114 | isresolved I2 DEFAULT '0' NOTNULL,
|
| 115 | iswatched I2 DEFAULT '0' NOTNULL,
|
| 116 |
|
| 117 | oldeditemailaddress C(255) DEFAULT '' NOTNULL,
|
| 118 |
|
| 119 | linkkbarticleid I DEFAULT '0' NOTNULL,
|
| 120 | linkticketmacroid I DEFAULT '0' NOTNULL,
|
| 121 | bayescategoryid I DEFAULT '0' NOTNULL";
|
| 122 |
|
| 123 | const INDEX_TICKETCOUNT = 'departmentid, ticketstatusid, ownerstaffid, lastactivity';
|
| 124 | const INDEX_1 = 'userid, email, replyto, departmentid, isresolved';
|
| 125 | const INDEX_2 = 'slaplanid, duetime, ticketstatusid';
|
| 126 | const INDEX_3 = 'departmentid, ticketstatusid, lastactivity';
|
| 127 | const INDEX_4 = 'email';
|
| 128 | const INDEX_5 = 'departmentid, ticketstatusid, userid';
|
| 129 | const INDEX_6 = 'departmentid, ticketstatusid, duetime';
|
| 130 | const INDEX_7 = 'dateline';
|
| 131 | const INDEX_8 = 'departmentid, ticketstatusid, lastuserreplytime';
|
| 132 | const INDEX_9 = 'duetime, resolutionduedateline, isescalatedvolatile, isresolved';
|
| 133 | const INDEX_10 = 'ticketmaskid, ticketid, departmentid';
|
| 134 | const INDEX_11 = 'departmentid, ticketstatusid, duetime, resolutionduedateline';
|
| 135 | const INDEX_12 = 'isresolved, departmentid';
|
| 136 | const INDEX_13 = 'ticketstatusid, departmentid, priorityid, tickettypeid';
|
| 137 | const INDEX_14 = 'isescalatedvolatile, isresolved';
|
| 138 | const INDEX_15 = 'ticketid, departmentid'; // Used by Staff API Protocol
|
| 139 | const INDEX_16 = 'ticketid, isresolved, autoclosestatus, lastactivity'; // Used by Auto Close
|
| 140 | const INDEX_17 = 'autoclosestatus, autocloseruleid, autoclosetimeline'; // Used by Auto Close
|
| 141 | const INDEX_18 = 'lastactivity'; // Unified Search
|
| 142 |
|
| 143 |
|
| 144 | const COLUMN_RENAME_HASBENCHMARKS = 'hasratings';
|
| 145 |
|
| 146 | protected $_dataStore = array();
|
| 147 |
|
| 148 | // Attachments
|
| 149 | static protected $_attachmentsContainer = array();
|
| 150 | static protected $_notificationAttachmentsContainer = array();
|
| 151 |
|
| 152 | // Notification Stuff
|
| 153 | public $Notification = false;
|
| 154 | public $NotificationManager = false;
|
| 155 | static protected $_notificationExecutionCache = array();
|
| 156 |
|
| 157 | // Workflow Queue Related Variables
|
| 158 | static protected $_isWorkflowQueueActive = false;
|
| 159 | static protected $_workflowQueue = array();
|
| 160 |
|
| 161 | // Watcher
|
| 162 | static protected $_watcherPendingCache = array();
|
| 163 | static protected $_watcherExecutedCache = array();
|
| 164 | protected $_watchNotificationMessage = '';
|
| 165 | protected $_lastPostNotificationMessage = '';
|
| 166 | protected $_watcherCustomName = '';
|
| 167 |
|
| 168 | protected $_noAlerts = false;
|
| 169 |
|
| 170 | /**
|
| 171 | * @var bool This property decides whether the SLA calculation has been queued on shutdown
|
| 172 | */
|
| 173 | protected $_slaOverdueQueued = -1;
|
| 174 |
|
| 175 | /**
|
| 176 | * @var bool This property is used to prevent the execution of SLA calculation.
|
| 177 | */
|
| 178 | protected $_noSLACalculation = false;
|
| 179 |
|
| 180 | /**
|
| 181 | * @var SWIFT_User This property is used to cache the user object
|
| 182 | */
|
| 183 | protected $_UserObject = false;
|
| 184 |
|
| 185 | /**
|
| 186 | * @var SWIFT_UserOrganization This property is used to cache the user organization object
|
| 187 | */
|
| 188 | protected $_UserOrganizationObject = false;
|
| 189 |
|
| 190 | /**
|
| 191 | * @var SWIFT_UserGroup This property is used to cache the user group object
|
| 192 | */
|
| 193 | protected $_UserGroupObject = false;
|
| 194 |
|
| 195 | /**
|
| 196 | * @var bool This property is used to determine the cache flag for the user object
|
| 197 | */
|
| 198 | protected $_isUserObjectCached = false;
|
| 199 |
|
| 200 | /**
|
| 201 | * @var bool This property is used to determine the cache flag for the user group object
|
| 202 | */
|
| 203 | protected $_isUserGroupObjectCached = false;
|
| 204 |
|
| 205 | /**
|
| 206 | * @var bool This property is used to determine the cache flag for the user organization object
|
| 207 | */
|
| 208 | protected $_isUserOrganizationObjectCached = false;
|
| 209 |
|
| 210 | /**
|
| 211 | * @var bool Is used to determine if the status was changed in this object
|
| 212 | */
|
| 213 | protected $_hasStatusChanged = false;
|
| 214 |
|
| 215 | /**
|
| 216 | * @var array Is used to keep old Ticket Properties.
|
| 217 | */
|
| 218 | protected $_oldTicketProperties = array();
|
| 219 |
|
| 220 | // Core Constants
|
| 221 | const CREATOR_STAFF = 1;
|
| 222 | const CREATOR_USER = 2;
|
| 223 | const CREATOR_CLIENT = 2;
|
| 224 |
|
| 225 | const CREATIONMODE_SUPPORTCENTER = 1;
|
| 226 | const CREATIONMODE_STAFFCP = 2;
|
| 227 | const CREATIONMODE_EMAIL = 3;
|
| 228 | const CREATIONMODE_API = 4;
|
| 229 | const CREATIONMODE_SITEBADGE = 5;
|
| 230 | const CREATIONMODE_MOBILE = 6;
|
| 231 | const CREATIONMODE_STAFFAPI = 7;
|
| 232 |
|
| 233 | const TYPE_DEFAULT = 1;
|
| 234 | const TYPE_PHONE = 2;
|
| 235 |
|
| 236 | const MAIL_NOTIFICATION = 1;
|
| 237 | const MAIL_CLIENT = 2;
|
| 238 | const MAIL_THIRDPARTY = 3;
|
| 239 |
|
| 240 | const AUTOCLOSESTATUS_NONE = 0;
|
| 241 | const AUTOCLOSESTATUS_PENDING = 1;
|
| 242 | const AUTOCLOSESTATUS_CLOSED = 2;
|
| 243 |
|
| 244 | /**
|
| 245 | * Constructor
|
| 246 | *
|
| 247 | * @author Varun Shoor
|
| 248 | * @param SWIFT_Data $_SWIFT_DataObject The SWIFT_Data Object
|
| 249 | * @return bool "true" on Success, "false" otherwise
|
| 250 | * @throws SWIFT_Ticket_Exception If the Record could not be loaded
|
| 251 | */
|
| 252 | public function __construct(SWIFT_Data $_SWIFT_DataObject)
|
| 253 | {
|
| 254 | parent::__construct();
|
| 255 |
|
| 256 | if (!$_SWIFT_DataObject instanceof SWIFT_Data || !$_SWIFT_DataObject->GetIsClassLoaded() || !$this->LoadData($_SWIFT_DataObject)) {
|
| 257 | throw new SWIFT_Ticket_Exception('Failed to load Ticket Object');
|
| 258 |
|
| 259 | $this->SetIsClassLoaded(false);
|
| 260 |
|
| 261 | return false;
|
| 262 | }
|
| 263 |
|
| 264 | $this->Load->Library('Ticket:TicketManager');
|
| 265 |
|
| 266 | $this->Notification = new SWIFT_TicketNotification($this);
|
| 267 | $this->NotificationManager = new SWIFT_NotificationManager($this);
|
| 268 |
|
| 269 | register_shutdown_function(array($this, 'ProcessNotifications'));
|
| 270 |
|
| 271 | if ($this->GetProperty('iswatched') == '1') {
|
| 272 | register_shutdown_function(array($this, 'ProcessWatchers'));
|
| 273 | }
|
| 274 |
|
| 275 | return true;
|
| 276 | }
|
| 277 |
|
| 278 | /**
|
| 279 | * Destructor
|
| 280 | *
|
| 281 | * @author Varun Shoor
|
| 282 | * @return bool "true" on Success, "false" otherwise
|
| 283 | */
|
| 284 | public function __destruct()
|
| 285 | {
|
| 286 | chdir(SWIFT_BASEPATH);
|
| 287 |
|
| 288 | if ($this->_slaOverdueQueued != -1) {
|
| 289 | $this->ProcessSLAOverdue($this->_slaOverdueQueued);
|
| 290 | }
|
| 291 |
|
| 292 | if ($this->GetProperty('iswatched') == '1') {
|
| 293 | $this->ProcessWatchers();
|
| 294 | }
|
| 295 |
|
| 296 | $this->ProcessUpdatePool();
|
| 297 |
|
| 298 | parent::__destruct();
|
| 299 |
|
| 300 | return true;
|
| 301 | }
|
| 302 |
|
| 303 | /**
|
| 304 | * Execute SLA If pending
|
| 305 | *
|
| 306 | * @author Varun Shoor
|
| 307 | * @param bool $_processResolutionDue (OPTIONAL) Whether to process the resolution due dateline
|
| 308 | * @param bool $_dontQueue (OPTIONAL) Dont queue the SLA execution
|
| 309 | * @return bool "true" on Success, "false" otherwise
|
| 310 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 311 | */
|
| 312 | public function ExecuteSLA($_processResolutionDue = true, $_dontQueue = false) {
|
| 313 | if (!$this->GetIsClassLoaded()) {
|
| 314 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 315 |
|
| 316 | return false;
|
| 317 | }
|
| 318 |
|
| 319 | $this->ProcessUpdatePool();
|
| 320 |
|
| 321 | if ($this->_slaOverdueQueued != -1 || $_dontQueue == true) {
|
| 322 | $this->ProcessSLAOverdue($_processResolutionDue);
|
| 323 |
|
| 324 | if ($_dontQueue) {
|
| 325 | $this->ProcessUpdatePool();
|
| 326 | }
|
| 327 | } else {
|
| 328 | $this->QueueSLAOverdue($_processResolutionDue);
|
| 329 | }
|
| 330 |
|
| 331 | return true;
|
| 332 | }
|
| 333 |
|
| 334 | /**
|
| 335 | * Processes the Update Pool Data
|
| 336 | *
|
| 337 | * @author Varun Shoor
|
| 338 | * @return bool "true" on Success, "false" otherwise
|
| 339 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 340 | */
|
| 341 | public function ProcessUpdatePool()
|
| 342 | {
|
| 343 | if (!$this->GetIsClassLoaded()) {
|
| 344 | return false;
|
| 345 | } else if (!_is_array($this->GetUpdatePool())) {
|
| 346 | return false;
|
| 347 | }
|
| 348 |
|
| 349 | $this->Database->AutoExecute(TABLE_PREFIX . 'tickets', $this->GetUpdatePool(), 'UPDATE', "ticketid = '" . intval($this->GetTicketID()) .
|
| 350 | "'");
|
| 351 |
|
| 352 | $this->ClearUpdatePool();
|
| 353 |
|
| 354 | return true;
|
| 355 | }
|
| 356 |
|
| 357 | /**
|
| 358 | * Retrieves the Ticket ID
|
| 359 | *
|
| 360 | * @author Varun Shoor
|
| 361 | * @return mixed "ticketid" on Success, "false" otherwise
|
| 362 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 363 | */
|
| 364 | public function GetTicketID()
|
| 365 | {
|
| 366 | if (!$this->GetIsClassLoaded())
|
| 367 | {
|
| 368 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 369 |
|
| 370 | return false;
|
| 371 | }
|
| 372 |
|
| 373 | return $this->_dataStore['ticketid'];
|
| 374 | }
|
| 375 |
|
| 376 | /**
|
| 377 | * Load the Data
|
| 378 | *
|
| 379 | * @author Varun Shoor
|
| 380 | * @param SWIFT_Data $_SWIFT_DataObject The SWIFT_Data Object
|
| 381 | * @return bool "true" on Success, "false" otherwise
|
| 382 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 383 | */
|
| 384 | protected function LoadData($_SWIFT_DataObject)
|
| 385 | {
|
| 386 | $_SWIFT = SWIFT::GetInstance();
|
| 387 |
|
| 388 | // Is it a ID?
|
| 389 | if ($_SWIFT_DataObject instanceof SWIFT_DataID && $_SWIFT_DataObject->GetIsClassLoaded())
|
| 390 | {
|
| 391 | $_dataStore = $this->Database->QueryFetch("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid = '" .
|
| 392 | intval($_SWIFT_DataObject->GetDataID()) . "'");
|
| 393 | if (isset($_dataStore['ticketid']) && !empty($_dataStore['ticketid']))
|
| 394 | {
|
| 395 | $this->_dataStore = $_dataStore;
|
| 396 | $this->_dataStore['displayticketid'] = IIF($_SWIFT->Settings->Get('t_eticketid') == 'seq', $this->_dataStore['ticketid'], $this->_dataStore['ticketmaskid']);
|
| 397 |
|
| 398 | return true;
|
| 399 | }
|
| 400 |
|
| 401 | // Is it a Store?
|
| 402 | } else if ($_SWIFT_DataObject instanceof SWIFT_DataStore && $_SWIFT_DataObject->GetIsClassLoaded()) {
|
| 403 | $this->_dataStore = $_SWIFT_DataObject->GetDataStore();
|
| 404 | $this->_dataStore['displayticketid'] = IIF($_SWIFT->Settings->Get('t_eticketid') == 'seq', $this->_dataStore['ticketid'], $this->_dataStore['ticketmaskid']);
|
| 405 |
|
| 406 | if (!isset($this->_dataStore['ticketid']) || empty($this->_dataStore['ticketid']))
|
| 407 | {
|
| 408 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 409 | }
|
| 410 |
|
| 411 | return true;
|
| 412 | }
|
| 413 |
|
| 414 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 415 |
|
| 416 | return false;
|
| 417 | }
|
| 418 |
|
| 419 | /**
|
| 420 | * Returns the Data Store Array
|
| 421 | *
|
| 422 | * @author Varun Shoor
|
| 423 | * @return mixed "_dataStore" Array on Success, "false" otherwise
|
| 424 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 425 | */
|
| 426 | public function GetDataStore()
|
| 427 | {
|
| 428 | if (!$this->GetIsClassLoaded())
|
| 429 | {
|
| 430 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 431 |
|
| 432 | return false;
|
| 433 | }
|
| 434 |
|
| 435 | return $this->_dataStore;
|
| 436 | }
|
| 437 |
|
| 438 | /**
|
| 439 | * Retrieves a Property Value from Data Store
|
| 440 | *
|
| 441 | * @author Varun Shoor
|
| 442 | * @param string $_key The Key Identifier
|
| 443 | * @return mixed Property Data on Success, "false" otherwise
|
| 444 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 445 | */
|
| 446 | public function GetProperty($_key)
|
| 447 | {
|
| 448 | if (!$this->GetIsClassLoaded())
|
| 449 | {
|
| 450 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 451 |
|
| 452 | return false;
|
| 453 | } else if (!isset($this->_dataStore[$_key])) {
|
| 454 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 455 |
|
| 456 | return false;
|
| 457 | }
|
| 458 |
|
| 459 | return $this->_dataStore[$_key];
|
| 460 | }
|
| 461 |
|
| 462 | /**
|
| 463 | * Check to see if its a valid creator type
|
| 464 | *
|
| 465 | * @author Varun Shoor
|
| 466 | * @param constant $_creatorType The Creator Type
|
| 467 | * @return bool "true" on Success, "false" otherwise
|
| 468 | */
|
| 469 | static public function IsValidCreatorType($_creatorType)
|
| 470 | {
|
| 471 | if ($_creatorType == self::CREATOR_STAFF || $_creatorType == self::CREATOR_USER)
|
| 472 | {
|
| 473 | return true;
|
| 474 | }
|
| 475 |
|
| 476 | return false;
|
| 477 | }
|
| 478 |
|
| 479 | /**
|
| 480 | * Check to see if its a valid creation mode
|
| 481 | *
|
| 482 | * @author Varun Shoor
|
| 483 | * @param constant $_creationMode The Creation Mode
|
| 484 | * @return bool "true" on Success, "false" otherwise
|
| 485 | */
|
| 486 | static public function IsValidCreationMode($_creationMode)
|
| 487 | {
|
| 488 | if ($_creationMode == self::CREATIONMODE_SUPPORTCENTER || $_creationMode == self::CREATIONMODE_STAFFCP ||
|
| 489 | $_creationMode == self::CREATIONMODE_EMAIL || $_creationMode == self::CREATIONMODE_API ||
|
| 490 | $_creationMode == self::CREATIONMODE_SITEBADGE || $_creationMode == self::CREATIONMODE_MOBILE ||
|
| 491 | $_creationMode == self::CREATIONMODE_STAFFAPI)
|
| 492 | {
|
| 493 | return true;
|
| 494 | }
|
| 495 |
|
| 496 | return false;
|
| 497 | }
|
| 498 |
|
| 499 | /**
|
| 500 | * Check to see if its a valid ticket type
|
| 501 | *
|
| 502 | * @author Varun Shoor
|
| 503 | * @param constant $_ticketType The Ticket Type
|
| 504 | * @return bool "true" on Success, "false" otherwise
|
| 505 | */
|
| 506 | static public function IsValidTicketType($_ticketType)
|
| 507 | {
|
| 508 | if ($_ticketType == self::TYPE_DEFAULT || $_ticketType == self::TYPE_PHONE)
|
| 509 | {
|
| 510 | return true;
|
| 511 | }
|
| 512 |
|
| 513 | return false;
|
| 514 | }
|
| 515 |
|
| 516 | /**
|
| 517 | * Get or Create a User ID based on given info
|
| 518 | *
|
| 519 | * @author Varun Shoor
|
| 520 | * @param string $_fullName The User Full Name
|
| 521 | * @param string $_email the User Email
|
| 522 | * @param int $_userGroupID The User Group ID
|
| 523 | * @param int $_languageID (OPTIONAL) The Language ID
|
| 524 | * @param bool $_checkGeoIP (OPTIONAL) Check GeoIP for User
|
| 525 | * @return int The User ID on Success, "false" otherwise
|
| 526 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 527 | */
|
| 528 | static public function GetOrCreateUserID($_fullName, $_email, $_userGroupID, $_languageID = false, $_checkGeoIP = false) {
|
| 529 | $_SWIFT = SWIFT::GetInstance();
|
| 530 |
|
| 531 | // User processing.. no user specified?
|
| 532 | $_userIDFromEmail = SWIFT_UserEmail::RetrieveUserIDOnUserEmail($_email);
|
| 533 |
|
| 534 | $_userID = false;
|
| 535 | if (!empty($_userIDFromEmail)) {
|
| 536 | $_userID = $_userIDFromEmail;
|
| 537 | } else {
|
| 538 | $_SWIFT_UserObject = SWIFT_User::Create($_userGroupID, false, SWIFT_User::SALUTATION_NONE, $_fullName, '', '', true,
|
| 539 | false, array($_email), false, $_languageID, false, false, false, false, false, true, true, $_checkGeoIP);
|
| 540 |
|
| 541 | $_userID = $_SWIFT_UserObject->GetUserID();
|
| 542 | }
|
| 543 |
|
| 544 | return $_userID;
|
| 545 | }
|
| 546 |
|
| 547 | /**
|
| 548 | * Create a new Ticket
|
| 549 | *
|
| 550 | * @author Varun Shoor
|
| 551 | * @param string $_subject The Ticket Subject
|
| 552 | * @param string $_fullName The Full Name of Creator
|
| 553 | * @param string $_email The Email of Creator
|
| 554 | * @param string $_contents The Ticket Contents
|
| 555 | * @param int $_departmentID The Department ID
|
| 556 | * @param int $_ticketStatusID The Ticket Status ID
|
| 557 | * @param int $_ticketPriorityID The Ticket Priority ID
|
| 558 | * @param int $_ticketTypeID The Ticket Type ID
|
| 559 | * @param int $_userID The User ID (If creator is user)
|
| 560 | * @param int $_staffID The Staff ID (If creator is staff)
|
| 561 | * @param constant $_ticketType The Ticket Type (Default/Phone)
|
| 562 | * @param constant $_creatorType The Creator Type
|
| 563 | * @param constant $_creationMode The Creation Mode
|
| 564 | * @param string $_phoneNumber (OPTIONAL) The Phone Number of User
|
| 565 | * @param int $_emailQueueID (OPTIONAL) The Email Queue ID
|
| 566 | * @param bool $_dispatchAutoResponder (OPTIONAL) Whether to dispatch the autoresponder msg
|
| 567 | * @param string $_emailTo (OPTIONAL) Only to be used when creating tickets from staff cp and using send mail option. Signifies the destination email address.
|
| 568 | * @param bool $_isPrivate (OPTIONAL) Whether private ticket post
|
| 569 | * @return mixed "_SWIFT_TicketObject" (OBJECT) on Success, "false" otherwise
|
| 570 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided or If the Object could not be created
|
| 571 | */
|
| 572 | static public function Create($_subject, $_fullName, $_email, $_contents, $_departmentID, $_ticketStatusID, $_ticketPriorityID, $_ticketTypeID,
|
| 573 | $_userID, $_staffID, $_ticketType, $_creatorType, $_creationMode, $_phoneNumber = '', $_emailQueueID = 0, $_dispatchAutoResponder = true,
|
| 574 | $_emailTo = '', $_isHTML = false, $_date = DATENOW, $_isPrivate = false)
|
| 575 | {
|
| 576 | $_SWIFT = SWIFT::GetInstance();
|
| 577 |
|
| 578 | $_departmentID = intval($_departmentID);
|
| 579 | $_ticketStatusID = intval($_ticketStatusID);
|
| 580 | $_ticketPriorityID = intval($_ticketPriorityID);
|
| 581 | $_userID = intval($_userID);
|
| 582 | $_ticketTypeID = intval($_ticketTypeID);
|
| 583 |
|
| 584 | $_ticketTypeCache = $_SWIFT->Cache->Get('tickettypecache');
|
| 585 | if(empty($_ticketTypeID)) {
|
| 586 | // Set default ticket type ID
|
| 587 | foreach ($_ticketTypeCache as $_ticketTypeID => $_ticketTypeContainer) {
|
| 588 | break;
|
| 589 | }
|
| 590 |
|
| 591 | }
|
| 592 |
|
| 593 | if ($_subject == '' || empty($_fullName) || empty($_email) || $_contents == '' || empty($_departmentID) || empty($_ticketStatusID) || !self::IsValidCreatorType($_creatorType)
|
| 594 | || !self::IsValidCreationMode($_creationMode) || !self::IsValidTicketType($_ticketType))
|
| 595 | {
|
| 596 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 597 |
|
| 598 | return false;
|
| 599 | }
|
| 600 |
|
| 601 |
|
| 602 | // Sanity check.. IMPORTANT
|
| 603 | $_departmentCache = $_SWIFT->Cache->Get('departmentcache');
|
| 604 | $_ticketStatusCache = $_SWIFT->Cache->Get('statuscache');
|
| 605 | $_ticketPriorityCache = $_SWIFT->Cache->Get('prioritycache');
|
| 606 |
|
| 607 | if (!isset($_departmentCache[$_departmentID]) || !isset($_ticketStatusCache[$_ticketStatusID]) ||
|
| 608 | !isset($_ticketPriorityCache[$_ticketPriorityID]) || !isset($_ticketTypeCache[$_ticketTypeID])) {
|
| 609 | throw new SWIFT_Ticket_Exception('Invalid Core Data: Department, Status, Priority, Type');
|
| 610 | } else if ($_departmentCache[$_departmentID]['departmentapp'] != APP_TICKETS) {
|
| 611 | throw new SWIFT_Ticket_Exception('Invalid Department App');
|
| 612 | }
|
| 613 |
|
| 614 | $_ticketMaskID = GenerateUniqueMask();
|
| 615 |
|
| 616 | $_isPhoneCall = false;
|
| 617 | if ($_ticketType == self::TYPE_PHONE)
|
| 618 | {
|
| 619 | $_isPhoneCall = true;
|
| 620 | }
|
| 621 |
|
| 622 | $_replyToEmail = $_email;
|
| 623 | if (!empty($_emailTo))
|
| 624 | {
|
| 625 | $_replyToEmail = $_emailTo;
|
| 626 | }
|
| 627 |
|
| 628 | $_isEmailed = false;
|
| 629 | if ($_creationMode == self::CREATIONMODE_EMAIL)
|
| 630 | {
|
| 631 | $_isEmailed = true;
|
| 632 | }
|
| 633 |
|
| 634 | $_ipAddress = '';
|
| 635 | if ($_SWIFT->Interface->GetInterface() != SWIFT_Interface::INTERFACE_CRON && $_SWIFT->Interface->GetInterface() != SWIFT_Interface::INTERFACE_CONSOLE)
|
| 636 | {
|
| 637 | $_ipAddress = SWIFT::Get('IP');
|
| 638 | }
|
| 639 |
|
| 640 | $_SWIFT_BayesianObject = new SWIFT_Bayesian();
|
| 641 | $_finalBayesCategoryID = 0;
|
| 642 | $_probabilityContainer = $_SWIFT_BayesianObject->Get($_subject . ' ' . $_contents);
|
| 643 | if (_is_array($_probabilityContainer))
|
| 644 | {
|
| 645 | $_finalBayesBenchmark = 0;
|
| 646 | foreach ($_probabilityContainer[0] as $_bayesCategoryID => $_probability)
|
| 647 | {
|
| 648 | if ($_probability['combined'] >= 0.500 && $_probability['combined'] > $_finalBayesBenchmark)
|
| 649 | {
|
| 650 | $_finalBayesCategoryID = $_bayesCategoryID;
|
| 651 | $_finalBayesBenchmark = $_probability['combined'];
|
| 652 | }
|
| 653 | }
|
| 654 | }
|
| 655 |
|
| 656 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('ticketmaskid' => $_ticketMaskID, 'departmentid' => intval($_departmentID),
|
| 657 | 'ticketstatusid' => intval($_ticketStatusID), 'priorityid' => intval($_ticketPriorityID), 'emailqueueid' => intval($_emailQueueID),
|
| 658 | 'userid' => intval($_userID), 'staffid' => intval($_staffID), 'fullname' => $_fullName, 'email' => mb_strtolower($_email), 'lastreplier' => $_fullName,
|
| 659 | 'replyto' => $_replyToEmail, 'subject' => $_subject, 'dateline' => $_date, 'lastactivity' => DATENOW, 'ipaddress' => $_ipAddress,
|
| 660 | 'isemailed' => intval($_isEmailed), 'isphonecall' => intval($_isPhoneCall), 'creator' => intval($_creatorType),
|
| 661 | 'tickettype' => intval($_ticketType), 'phoneno' => $_phoneNumber, 'tickettypeid' => intval($_ticketTypeID), 'tickethash' => substr(BuildHash(), 0, 12),
|
| 662 | 'creationmode' => intval($_creationMode), 'bayescategoryid' => intval($_finalBayesCategoryID)), 'INSERT');
|
| 663 | $_ticketID = $_SWIFT->Database->Insert_ID();
|
| 664 |
|
| 665 | if (!$_ticketID)
|
| 666 | {
|
| 667 | throw new SWIFT_Ticket_Exception(SWIFT_CREATEFAILED);
|
| 668 |
|
| 669 | return false;
|
| 670 | }
|
| 671 |
|
| 672 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
|
| 673 | if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded())
|
| 674 | {
|
| 675 | throw new SWIFT_Ticket_Exception(SWIFT_CREATEFAILED);
|
| 676 |
|
| 677 | return false;
|
| 678 | }
|
| 679 |
|
| 680 | $_departmentTitle = $_departmentCache[$_departmentID]['title'];
|
| 681 | $_statusTitle = $_ticketStatusCache[$_ticketStatusID]['title'];
|
| 682 | $_typeTitle = $_ticketTypeCache[$_ticketTypeID]['title'];
|
| 683 | $_priorityTitle = $_ticketPriorityCache[$_ticketPriorityID]['title'];
|
| 684 |
|
| 685 | $_SWIFT_TicketObject->UpdatePool('departmenttitle', $_departmentTitle);
|
| 686 | $_SWIFT_TicketObject->UpdatePool('ticketstatustitle', $_statusTitle);
|
| 687 | $_SWIFT_TicketObject->UpdatePool('tickettypetitle', $_typeTitle);
|
| 688 | $_SWIFT_TicketObject->UpdatePool('prioritytitle', $_priorityTitle);
|
| 689 |
|
| 690 | // Create the ticket post..
|
| 691 | $_creatorID = $_staffID;
|
| 692 | if ($_creatorType == self::CREATOR_CLIENT) {
|
| 693 | $_creatorID = $_userID;
|
| 694 | }
|
| 695 |
|
| 696 | // Get Email Queue Name
|
| 697 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 698 | $_emailQueueAddress = '';
|
| 699 | if (isset($_emailQueueCache['list'][$_emailQueueID])) {
|
| 700 | $_emailQueueAddress = $_emailQueueCache['list'][$_emailQueueID]['email'];
|
| 701 | }
|
| 702 |
|
| 703 | // Create Audit Log
|
| 704 |
|
| 705 | /*
|
| 706 | * BUG FIX - Varun Shoor
|
| 707 | *
|
| 708 | * SWIFT-1657 Audit Log does not show email queue address via which ticket is created
|
| 709 | *
|
| 710 | * Comments: None
|
| 711 | */
|
| 712 | if (!empty($_emailQueueAddress)) {
|
| 713 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_NEWTICKET, sprintf($_SWIFT->Language->Get('al_newticket_queue'), $_fullName, $_email, $_subject, $_emailQueueAddress),
|
| 714 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 715 | } else {
|
| 716 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_NEWTICKET, sprintf($_SWIFT->Language->Get('al_newticket'), $_fullName, $_email, $_subject),
|
| 717 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 718 | }
|
| 719 |
|
| 720 | $_ticketPostID = SWIFT_TicketPost::Create($_SWIFT_TicketObject, $_fullName, $_email, $_contents, $_creatorType, $_creatorID, $_creationMode,
|
| 721 | $_subject, $_emailTo, $_isHTML, false, false, $_date, $_isPrivate);
|
| 722 |
|
| 723 | $_SWIFT_TicketObject->UpdatePool('firstpostid', $_ticketPostID);
|
| 724 | $_SWIFT_TicketObject->UpdatePool('lastpostid', $_ticketPostID);
|
| 725 | $_SWIFT_TicketObject->UpdatePool('totalreplies', '0');
|
| 726 |
|
| 727 |
|
| 728 | /*
|
| 729 | * BUG FIX - Varun Shoor
|
| 730 | *
|
| 731 | * SWIFT-965 When a new ticket is created with status "closed", 'Clear due time' setting does not work
|
| 732 | *
|
| 733 | * Comments: None
|
| 734 | */
|
| 735 |
|
| 736 | // SLA & Status Properties
|
| 737 | $_ticketStatusContainer = $_ticketStatusCache[$_ticketStatusID];
|
| 738 | if ($_ticketStatusContainer['resetduetime'] == '1') {
|
| 739 | $_SWIFT_TicketObject->UpdatePool('duetime', '0');
|
| 740 | $_SWIFT_TicketObject->_noSLACalculation = true;
|
| 741 | }
|
| 742 |
|
| 743 | if ($_ticketStatusContainer['markasresolved'] == '1')
|
| 744 | {
|
| 745 | $_SWIFT_TicketObject->UpdatePool('isresolved', '1');
|
| 746 | $_SWIFT_TicketObject->UpdatePool('resolutiondateline', DATENOW);
|
| 747 | $_SWIFT_TicketObject->UpdatePool('repliestoresolution', $_SWIFT_TicketObject->GetProperty('totalreplies'));
|
| 748 |
|
| 749 | // How much time did it take to resolve this ticket?
|
| 750 | $_SWIFT_TicketObject->UpdatePool('resolutionseconds', DATENOW-$_SWIFT_TicketObject->GetProperty('dateline'));
|
| 751 | }
|
| 752 |
|
| 753 | // If the status is set to resolved then we reset the resolution due time
|
| 754 | $_processResolutionDue = false;
|
| 755 | if ($_ticketStatusContainer['markasresolved'] == '1') {
|
| 756 | $_SWIFT_TicketObject->UpdatePool('resolutionduedateline', '0');
|
| 757 | $_SWIFT_TicketObject->UpdatePool('duetime', '0');
|
| 758 |
|
| 759 | $_SWIFT_TicketObject->_noSLACalculation = true;
|
| 760 |
|
| 761 | // Otherwise if its not, and resolutionduedateline is 0 then we force it to recalculate the resolution due time
|
| 762 | } else if ($_ticketStatusContainer['markasresolved'] == '0' && $_SWIFT_TicketObject->GetProperty('resolutionduedateline') == '0') {
|
| 763 | $_processResolutionDue = true;
|
| 764 | }
|
| 765 |
|
| 766 | $_SWIFT_TicketObject->ProcessSLAOverdue($_processResolutionDue);
|
| 767 |
|
| 768 | // Notification Event
|
| 769 | $_SWIFT_TicketObject->NotificationManager->SetEvent('newticket');
|
| 770 |
|
| 771 | // Load and Process Workflow Rules
|
| 772 | self::AddToWorkflowQueue($_SWIFT_TicketObject);
|
| 773 |
|
| 774 | // Recount the cache
|
| 775 | SWIFT_TicketManager::Recount(false);
|
| 776 |
|
| 777 | if ($_dispatchAutoResponder == true)
|
| 778 | {
|
| 779 | $_SWIFT_TicketObject->DispatchAutoresponder();
|
| 780 | }
|
| 781 |
|
| 782 | return $_SWIFT_TicketObject;
|
| 783 | }
|
| 784 |
|
| 785 | /**
|
| 786 | * Update the Ticket Record
|
| 787 | *
|
| 788 | * @author Varun Shoor
|
| 789 | * @param string $_subject The Ticket Subject
|
| 790 | * @param string $_fullName The Ticket Fullname
|
| 791 | * @param string $_email The Ticket Email
|
| 792 | * @return bool "true" on Success, "false" otherwise
|
| 793 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 794 | */
|
| 795 | public function Update($_subject, $_fullName, $_email)
|
| 796 | {
|
| 797 | $_SWIFT = SWIFT::GetInstance();
|
| 798 |
|
| 799 | if (!$this->GetIsClassLoaded())
|
| 800 | {
|
| 801 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 802 |
|
| 803 | return false;
|
| 804 | }
|
| 805 |
|
| 806 | // Create Audit Log
|
| 807 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 808 | sprintf($_SWIFT->Language->Get('al_updateproperties'), StripName($this->GetProperty('subject'), 60), StripName($_subject, 60), StripName($this->GetProperty('fullname'), 30),
|
| 809 | StripName($_fullName, 30), StripName($this->GetProperty('email'), 40), StripName($_email, 40)), SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 810 |
|
| 811 | $this->UpdatePool('subject', $_subject);
|
| 812 | $this->UpdatePool('fullname', $_fullName);
|
| 813 |
|
| 814 | $_ticketEmailAddress = $this->GetProperty('email');
|
| 815 | if ($this->GetProperty('replyto') != '')
|
| 816 | {
|
| 817 | $_ticketEmailAddress = $this->GetProperty('replyto');
|
| 818 | }
|
| 819 |
|
| 820 | $this->UpdatePool('oldeditemailaddress', $_ticketEmailAddress);
|
| 821 | $this->UpdatePool('email', $_email);
|
| 822 | $this->UpdatePool('replyto', $_email);
|
| 823 |
|
| 824 | // Load and Process Workflow Rules
|
| 825 | self::AddToWorkflowQueue($this);
|
| 826 |
|
| 827 | return true;
|
| 828 | }
|
| 829 |
|
| 830 | /**
|
| 831 | * Delete the Ticket record
|
| 832 | *
|
| 833 | * @author Varun Shoor
|
| 834 | * @return bool "true" on Success, "false" otherwise
|
| 835 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 836 | */
|
| 837 | public function Delete()
|
| 838 | {
|
| 839 | if (!$this->GetIsClassLoaded())
|
| 840 | {
|
| 841 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 842 |
|
| 843 | return false;
|
| 844 | }
|
| 845 |
|
| 846 | self::DeleteList(array($this->GetTicketID()));
|
| 847 |
|
| 848 | $this->SetIsClassLoaded(false);
|
| 849 |
|
| 850 | return true;
|
| 851 | }
|
| 852 |
|
| 853 | /**
|
| 854 | * Delete a list of Tickets
|
| 855 | *
|
| 856 | * @author Varun Shoor
|
| 857 | * @param array $_ticketIDList The Ticket ID List
|
| 858 | * @return bool "true" on Success, "false" otherwise
|
| 859 | */
|
| 860 | static public function DeleteList($_ticketIDList)
|
| 861 | {
|
| 862 | $_SWIFT = SWIFT::GetInstance();
|
| 863 |
|
| 864 | if (!_is_array($_ticketIDList))
|
| 865 | {
|
| 866 | return false;
|
| 867 | }
|
| 868 |
|
| 869 | $_finalTicketIDList = $_departmentIDList = array();
|
| 870 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 871 | while ($_SWIFT->Database->NextRecord())
|
| 872 | {
|
| 873 | $_finalTicketIDList[] = intval($_SWIFT->Database->Record['ticketid']);
|
| 874 |
|
| 875 | $_departmentIDList[] = intval($_SWIFT->Database->Record['departmentid']);
|
| 876 |
|
| 877 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataSTore($_SWIFT->Database->Record));
|
| 878 |
|
| 879 | // Create Audit Log
|
| 880 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_DELETETICKET,
|
| 881 | sprintf($_SWIFT->Language->Get('al_deleteticket'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT->Database->Record['subject'],
|
| 882 | $_SWIFT->Database->Record['fullname'], $_SWIFT->Database->Record['email']),
|
| 883 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 884 | }
|
| 885 |
|
| 886 | if (!count($_finalTicketIDList))
|
| 887 | {
|
| 888 | return false;
|
| 889 | }
|
| 890 |
|
| 891 | $_SWIFT->Database->Query("DELETE FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_finalTicketIDList) . ")");
|
| 892 |
|
| 893 | // Clear Ticket Posts
|
| 894 | SWIFT_TicketPost::DeleteOnTicket($_finalTicketIDList);
|
| 895 |
|
| 896 | // Clear Attachments
|
| 897 | SWIFT_Attachment::DeleteOnTicket($_finalTicketIDList);
|
| 898 |
|
| 899 | // Clear Notes
|
| 900 | SWIFT_TicketNote::DeleteOnTicket($_finalTicketIDList);
|
| 901 |
|
| 902 | // Clear Ticket Drafts
|
| 903 | SWIFT_TicketDraft::DeleteOnTicket($_finalTicketIDList);
|
| 904 |
|
| 905 | // Release the Locks
|
| 906 | SWIFT_TicketLock::DeleteOnTicket($_finalTicketIDList);
|
| 907 | SWIFT_TicketPostLock::DeleteOnTicket($_finalTicketIDList);
|
| 908 |
|
| 909 | // Clear the Recipients
|
| 910 | SWIFT_TicketRecipient::DeleteOnTicket($_finalTicketIDList);
|
| 911 |
|
| 912 | // Clear the Audit Logs
|
| 913 | SWIFT_TicketAuditLog::DeleteOnTicket($_finalTicketIDList);
|
| 914 |
|
| 915 | // Clear the Time Track entries
|
| 916 | SWIFT_TicketTimeTrack::DeleteOnTicket($_finalTicketIDList);
|
| 917 |
|
| 918 | // Clear the Message IDs
|
| 919 | SWIFT_TicketMessageID::DeleteOnTicket($_finalTicketIDList);
|
| 920 |
|
| 921 | // Clear the Linked Table IDs
|
| 922 | SWIFT_TicketLinkedTable::DeleteOnTicket($_finalTicketIDList);
|
| 923 |
|
| 924 | // Clear the ticket watchers
|
| 925 | SWIFT_TicketWatcher::DeleteOnTicket($_finalTicketIDList);
|
| 926 |
|
| 927 | // Clear the chains
|
| 928 | SWIFT_TicketLinkChain::DeleteOnTicket($_finalTicketIDList);
|
| 929 |
|
| 930 | // Delete the merge logs
|
| 931 | SWIFT_TicketMergeLog::DeleteOnTicket($_finalTicketIDList);
|
| 932 |
|
| 933 | // Delete the Ticket Follow-Up's
|
| 934 | SWIFT_TicketFollowUp::DeleteOnTicket($_finalTicketIDList);
|
| 935 |
|
| 936 | // Delete the Ticket Escalation Paths
|
| 937 | SWIFT_EscalationPath::DeleteOnTicket($_finalTicketIDList);
|
| 938 |
|
| 939 | // Delete the Ticket Recurrence
|
| 940 | SWIFT_TicketRecurrence::DeleteOnTicket($_finalTicketIDList);
|
| 941 |
|
| 942 | // Delete the tags
|
| 943 | SWIFT_TagLink::DeleteOnLinkList(SWIFT_TagLink::TYPE_TICKET, $_finalTicketIDList);
|
| 944 |
|
| 945 | // Rebuild count cache
|
| 946 | SWIFT_TicketManager::RebuildCache();
|
| 947 |
|
| 948 | return true;
|
| 949 | }
|
| 950 |
|
| 951 | /**
|
| 952 | * Un-Delete a list of Tickets
|
| 953 | *
|
| 954 | * @author Varun Shoor
|
| 955 | * @param array $_ticketIDList The Ticket ID List
|
| 956 | * @return bool "true" on Success, "false" otherwise
|
| 957 | */
|
| 958 | static public function UnDeleteList($_ticketIDList)
|
| 959 | {
|
| 960 | $_SWIFT = SWIFT::GetInstance();
|
| 961 |
|
| 962 | if (!_is_array($_ticketIDList))
|
| 963 | {
|
| 964 | return false;
|
| 965 | }
|
| 966 |
|
| 967 | $_finalTicketIDList = $_departmentIDList = $_ticketContainer = array();
|
| 968 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 969 | while ($_SWIFT->Database->NextRecord())
|
| 970 | {
|
| 971 | $_ticketContainer[$_SWIFT->Database->Record['ticketid']] = $_SWIFT->Database->Record;
|
| 972 |
|
| 973 | $_finalTicketIDList[] = intval($_SWIFT->Database->Record['ticketid']);
|
| 974 |
|
| 975 | $_departmentIDList[] = intval($_SWIFT->Database->Record['departmentid']);
|
| 976 |
|
| 977 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataSTore($_SWIFT->Database->Record));
|
| 978 |
|
| 979 | // Create Audit Log
|
| 980 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_DELETETICKET,
|
| 981 | sprintf($_SWIFT->Language->Get('al_untrashticket'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT->Database->Record['subject'],
|
| 982 | $_SWIFT->Database->Record['fullname'], $_SWIFT->Database->Record['email']),
|
| 983 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 984 | }
|
| 985 |
|
| 986 | if (!count($_finalTicketIDList))
|
| 987 | {
|
| 988 | return false;
|
| 989 | }
|
| 990 |
|
| 991 | foreach ($_finalTicketIDList as $_ticketID)
|
| 992 | {
|
| 993 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('departmentid' => intval($_ticketContainer[$_ticketID]['trasholddepartmentid'])), 'UPDATE', "ticketid = '" . intval($_ticketID) . "'");
|
| 994 | }
|
| 995 |
|
| 996 | // Rebuild count cache
|
| 997 | SWIFT_TicketManager::RebuildCache();
|
| 998 |
|
| 999 | return true;
|
| 1000 | }
|
| 1001 |
|
| 1002 | /**
|
| 1003 | * Merge a list of tickets together
|
| 1004 | *
|
| 1005 | * @author Varun Shoor
|
| 1006 | * @param array $_ticketIDList The Ticket ID List
|
| 1007 | * @param int $_parentTicketID (OPTIONAL) The Parent Ticket ID
|
| 1008 | * @return bool "true" on Success, "false" otherwise
|
| 1009 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 1010 | */
|
| 1011 | static public function Merge($_ticketIDList, $_parentTicketID = false, $_staffID = false) {
|
| 1012 | $_SWIFT = SWIFT::GetInstance();
|
| 1013 |
|
| 1014 | if (!_is_array($_ticketIDList) || (count($_ticketIDList) < 2 && empty($_parentTicketID))) {
|
| 1015 | return false;
|
| 1016 | }
|
| 1017 |
|
| 1018 | $_departmentIDList = $_ticketMaskIDList = $_mergeTicketIDList = $_mergeEmailList = array();
|
| 1019 |
|
| 1020 | if (!$_parentTicketID) {
|
| 1021 | $_parentTicketID = $_ticketIDList[0];
|
| 1022 | }
|
| 1023 |
|
| 1024 | // Load the parent ticket
|
| 1025 | $_SWIFT_ParentTicketObject = new SWIFT_Ticket(new SWIFT_DataID($_parentTicketID));
|
| 1026 | if (!$_SWIFT_ParentTicketObject instanceof SWIFT_Ticket || !$_SWIFT_ParentTicketObject->GetIsClassLoaded()) {
|
| 1027 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 1028 | }
|
| 1029 |
|
| 1030 | $_departmentIDList[] = $_SWIFT_ParentTicketObject->GetProperty('departmentid');
|
| 1031 |
|
| 1032 | // Load the other objects
|
| 1033 | $_ticketObjectContainer = array();
|
| 1034 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 1035 | while ($_SWIFT->Database->NextRecord()) {
|
| 1036 | if ($_SWIFT->Database->Record['ticketid'] == $_parentTicketID) {
|
| 1037 | continue;
|
| 1038 | }
|
| 1039 |
|
| 1040 | $_ticketObjectContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 1041 |
|
| 1042 | // Create Audit Log
|
| 1043 | $_SWIFT_TicketObject_Merge = $_ticketObjectContainer[$_SWIFT->Database->Record['ticketid']];
|
| 1044 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject_Merge, null, SWIFT_TicketAuditLog::ACTION_MERGETICKET,
|
| 1045 | sprintf($_SWIFT->Language->Get('al_merge'), $_SWIFT_TicketObject_Merge->GetTicketDisplayID(), $_SWIFT->Database->Record['subject'],
|
| 1046 | $_SWIFT->Database->Record['fullname'], $_SWIFT->Database->Record['email']),
|
| 1047 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 1048 |
|
| 1049 | if (!in_array($_SWIFT->Database->Record['departmentid'], $_departmentIDList)) {
|
| 1050 | $_departmentIDList[] = $_SWIFT->Database->Record['departmentid'];
|
| 1051 | }
|
| 1052 |
|
| 1053 | $_ticketMaskIDList[] = $_SWIFT->Database->Record['ticketmaskid'];
|
| 1054 |
|
| 1055 | $_mergeTicketIDList[] = $_SWIFT->Database->Record['ticketid'];
|
| 1056 |
|
| 1057 | if (!in_array($_SWIFT->Database->Record['email'], $_mergeEmailList) &&
|
| 1058 | $_SWIFT->Database->Record['email'] != $_SWIFT_ParentTicketObject->GetProperty('email')) {
|
| 1059 | $_mergeEmailList[] = $_SWIFT->Database->Record['email'];
|
| 1060 | }
|
| 1061 | }
|
| 1062 |
|
| 1063 | /**
|
| 1064 | * @todo Raise Alert Here
|
| 1065 | */
|
| 1066 |
|
| 1067 | // By now we have the parent ticket and the child tickets, we need to start the merge process now.
|
| 1068 |
|
| 1069 | // Update Notes. !! IMPORTANT: This needs to be called before ticket posts are updated. !!
|
| 1070 | SWIFT_TicketNoteManager::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1071 |
|
| 1072 | // Update Ticket Posts
|
| 1073 | SWIFT_TicketPost::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1074 |
|
| 1075 | // Update Attachments
|
| 1076 | SWIFT_Attachment::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1077 |
|
| 1078 | // Update the Recipients
|
| 1079 | SWIFT_TicketRecipient::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1080 |
|
| 1081 | // Update the Audit Logs
|
| 1082 | SWIFT_TicketAuditLog::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1083 |
|
| 1084 | // Update the Time Track entries
|
| 1085 | SWIFT_TicketTimeTrack::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1086 |
|
| 1087 | // Update the Ticket Follow-Up's
|
| 1088 | SWIFT_TicketFollowUp::ReplaceTicket($_mergeTicketIDList, $_SWIFT_ParentTicketObject);
|
| 1089 |
|
| 1090 | // Add all the recipients if needed
|
| 1091 | if ($_SWIFT->Settings->Get('t_mergrecip') == 1 && count($_mergeEmailList))
|
| 1092 | {
|
| 1093 | SWIFT_TicketRecipient::Create($_SWIFT_ParentTicketObject, SWIFT_TicketRecipient::TYPE_CC, $_mergeEmailList);
|
| 1094 | }
|
| 1095 |
|
| 1096 | // Recaclulate all properties
|
| 1097 | $_SWIFT_ParentTicketObject->RebuildProperties();
|
| 1098 |
|
| 1099 | /**
|
| 1100 | * @todo Add Audit Log Entry
|
| 1101 | */
|
| 1102 |
|
| 1103 | // First add the Merge Log List.. this is used to route replies to the right ticket.
|
| 1104 | foreach ($_ticketObjectContainer as $_ticketID => $_SWIFT_TicketObject) {
|
| 1105 | SWIFT_TicketMergeLog::Create($_SWIFT_ParentTicketObject, $_SWIFT_TicketObject->GetTicketID(),
|
| 1106 | $_SWIFT_TicketObject->GetProperty('ticketmaskid'), $_staffID);
|
| 1107 | }
|
| 1108 |
|
| 1109 | // Delete JUST the ticket entries
|
| 1110 | $_SWIFT->Database->Query("DELETE FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_mergeTicketIDList) . ")");
|
| 1111 |
|
| 1112 | // Clear Ticket Drafts
|
| 1113 | SWIFT_TicketDraft::DeleteOnTicket($_mergeTicketIDList);
|
| 1114 |
|
| 1115 | // Release the Locks
|
| 1116 | SWIFT_TicketLock::DeleteOnTicket($_mergeTicketIDList);
|
| 1117 | SWIFT_TicketPostLock::DeleteOnTicket($_mergeTicketIDList);
|
| 1118 |
|
| 1119 | // Clear the Message IDs
|
| 1120 | SWIFT_TicketMessageID::DeleteOnTicket($_mergeTicketIDList);
|
| 1121 |
|
| 1122 | // Clear the Linked Table IDs
|
| 1123 | SWIFT_TicketLinkedTable::DeleteOnTicket($_mergeTicketIDList);
|
| 1124 |
|
| 1125 | // Clear the ticket watchers
|
| 1126 | SWIFT_TicketWatcher::DeleteOnTicket($_mergeTicketIDList);
|
| 1127 |
|
| 1128 | // Clear the chains
|
| 1129 | SWIFT_TicketLinkChain::DeleteOnTicket($_mergeTicketIDList);
|
| 1130 |
|
| 1131 | // Delete the Ticket Escalation Paths
|
| 1132 | SWIFT_EscalationPath::DeleteOnTicket($_mergeTicketIDList);
|
| 1133 |
|
| 1134 | // Delete the Ticket Recurrence
|
| 1135 | SWIFT_TicketRecurrence::DeleteOnTicket($_mergeTicketIDList);
|
| 1136 |
|
| 1137 | // Delete the tags
|
| 1138 | SWIFT_TagLink::DeleteOnLinkList(SWIFT_TagLink::TYPE_TICKET, $_mergeTicketIDList);
|
| 1139 |
|
| 1140 | // Time for a recount
|
| 1141 | SWIFT_TicketManager::RebuildCache();
|
| 1142 |
|
| 1143 | return true;
|
| 1144 | }
|
| 1145 |
|
| 1146 | /**
|
| 1147 | * Move the Ticket record to trash
|
| 1148 | *
|
| 1149 | * @author Varun Shoor
|
| 1150 | * @return bool "true" on Success, "false" otherwise
|
| 1151 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1152 | */
|
| 1153 | public function Trash()
|
| 1154 | {
|
| 1155 | if (!$this->GetIsClassLoaded())
|
| 1156 | {
|
| 1157 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1158 |
|
| 1159 | return false;
|
| 1160 | }
|
| 1161 |
|
| 1162 | self::TrashList(array($this->GetTicketID()));
|
| 1163 |
|
| 1164 | return true;
|
| 1165 | }
|
| 1166 |
|
| 1167 | /**
|
| 1168 | * Trash a list of Tickets
|
| 1169 | *
|
| 1170 | * @author Varun Shoor
|
| 1171 | * @param array $_ticketIDList The Ticket ID List
|
| 1172 | * @return bool "true" on Success, "false" otherwise
|
| 1173 | */
|
| 1174 | static public function TrashList($_ticketIDList)
|
| 1175 | {
|
| 1176 | $_SWIFT = SWIFT::GetInstance();
|
| 1177 |
|
| 1178 | if (!_is_array($_ticketIDList))
|
| 1179 | {
|
| 1180 | return false;
|
| 1181 | }
|
| 1182 |
|
| 1183 | $_finalTicketIDList = $_departmentIDList = array();
|
| 1184 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 1185 | while ($_SWIFT->Database->NextRecord())
|
| 1186 | {
|
| 1187 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 1188 | $_SWIFT_TicketObject->UpdateTrashDepartment();
|
| 1189 |
|
| 1190 | $_finalTicketIDList[] = intval($_SWIFT->Database->Record['ticketid']);
|
| 1191 |
|
| 1192 | $_departmentIDList[] = intval($_SWIFT->Database->Record['departmentid']);
|
| 1193 |
|
| 1194 | // Create Audit Log
|
| 1195 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_TRASHTICKET,
|
| 1196 | sprintf($_SWIFT->Language->Get('al_trashticket'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT->Database->Record['subject'],
|
| 1197 | $_SWIFT->Database->Record['fullname'], $_SWIFT->Database->Record['email']),
|
| 1198 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 1199 | }
|
| 1200 |
|
| 1201 | if (!count($_finalTicketIDList))
|
| 1202 | {
|
| 1203 | return false;
|
| 1204 | }
|
| 1205 |
|
| 1206 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('departmentid' => '0'), 'UPDATE', "ticketid IN (" .
|
| 1207 | BuildIN($_finalTicketIDList) . ")");
|
| 1208 |
|
| 1209 | // Rebuild count cache
|
| 1210 | SWIFT_TicketManager::RebuildCache();
|
| 1211 |
|
| 1212 | return true;
|
| 1213 | }
|
| 1214 |
|
| 1215 | /**
|
| 1216 | * Update the trash department
|
| 1217 | *
|
| 1218 | * @author Varun Shoor
|
| 1219 | * @return bool "true" on Success, "false" otherwise
|
| 1220 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1221 | */
|
| 1222 | public function UpdateTrashDepartment() {
|
| 1223 | if (!$this->GetIsClassLoaded()) {
|
| 1224 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1225 |
|
| 1226 | return false;
|
| 1227 | }
|
| 1228 |
|
| 1229 | /*
|
| 1230 | * BUG FIX - Varun Shoor
|
| 1231 | *
|
| 1232 | * SWIFT-1781 Help desk is not removing the SLA while moving the tickets in Trash folder
|
| 1233 | *
|
| 1234 | */
|
| 1235 | $this->ClearOverdue();
|
| 1236 | $this->ClearResolutiondue();
|
| 1237 | $this->UpdatePool('slaplanid', '0');
|
| 1238 | $this->UpdatePool('trasholddepartmentid', $this->GetProperty('departmentid'));
|
| 1239 | $this->ProcessUpdatePool();
|
| 1240 |
|
| 1241 | return true;
|
| 1242 | }
|
| 1243 |
|
| 1244 | /**
|
| 1245 | * Ban the creator of this ticket
|
| 1246 | *
|
| 1247 | * @author Varun Shoor
|
| 1248 | * @return bool "true" on Success, "false" otherwise
|
| 1249 | * @param int $_staffID (OPTIONAL) The Staff ID initiating the Ban
|
| 1250 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1251 | */
|
| 1252 | public function Ban($_staffID = 0)
|
| 1253 | {
|
| 1254 | if (!$this->GetIsClassLoaded())
|
| 1255 | {
|
| 1256 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1257 |
|
| 1258 | return false;
|
| 1259 | }
|
| 1260 |
|
| 1261 | self::BanList(array($this->GetTicketID()), $_staffID);
|
| 1262 |
|
| 1263 | return true;
|
| 1264 | }
|
| 1265 |
|
| 1266 | /**
|
| 1267 | * Ban a list of ticket ids
|
| 1268 | *
|
| 1269 | * @author Varun Shoor
|
| 1270 | * @param array $_ticketIDList The Ticket ID List to ban
|
| 1271 | * @param int $_staffID (OPTIONAL) The Staff ID initiating the Ban
|
| 1272 | * @return bool "true" on Success, "false" otherwise
|
| 1273 | */
|
| 1274 | static public function BanList($_ticketIDList, $_staffID = 0)
|
| 1275 | {
|
| 1276 | $_SWIFT = SWIFT::GetInstance();
|
| 1277 |
|
| 1278 | if (!_is_array($_ticketIDList))
|
| 1279 | {
|
| 1280 | return false;
|
| 1281 | }
|
| 1282 |
|
| 1283 | $_staffCache = $_SWIFT->Cache->Get('staffcache');
|
| 1284 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 1285 | $_rejectEmailList = array();
|
| 1286 |
|
| 1287 | foreach ($_staffCache as $_key => $_val)
|
| 1288 | {
|
| 1289 | $_rejectEmailList[] = mb_strtolower($_val['email']);
|
| 1290 | }
|
| 1291 |
|
| 1292 | if (_is_array($_emailQueueCache) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 1293 | {
|
| 1294 | foreach ($_emailQueueCache['list'] as $_key => $_val)
|
| 1295 | {
|
| 1296 | $_rejectEmailList[] = mb_strtolower($_val['email']);
|
| 1297 | }
|
| 1298 | }
|
| 1299 |
|
| 1300 | $_finalEmailBanList = array();
|
| 1301 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 1302 | while ($_SWIFT->Database->NextRecord())
|
| 1303 | {
|
| 1304 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 1305 |
|
| 1306 | // Create Audit Log
|
| 1307 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_BAN,
|
| 1308 | sprintf($_SWIFT->Language->Get('al_ban'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT->Database->Record['email']),
|
| 1309 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 1310 |
|
| 1311 | if (!in_array(mb_strtolower($_SWIFT->Database->Record['email']), $_finalEmailBanList) &&
|
| 1312 | !in_array(mb_strtolower($_SWIFT->Database->Record['email']), $_rejectEmailList))
|
| 1313 | {
|
| 1314 | $_finalEmailBanList[] = mb_strtolower($_SWIFT->Database->Record['email']);
|
| 1315 | }
|
| 1316 | }
|
| 1317 |
|
| 1318 | if (!count($_finalEmailBanList))
|
| 1319 | {
|
| 1320 | return false;
|
| 1321 | }
|
| 1322 |
|
| 1323 | SWIFT_Loader::LoadModel('Ban:ParserBan', APP_PARSER);
|
| 1324 |
|
| 1325 | if (class_exists('SWIFT_ParserBan', false))
|
| 1326 | {
|
| 1327 | foreach ($_finalEmailBanList as $_key => $_val)
|
| 1328 | {
|
| 1329 | SWIFT_ParserBan::Create($_val, $_staffID);
|
| 1330 | }
|
| 1331 | }
|
| 1332 |
|
| 1333 | return true;
|
| 1334 | }
|
| 1335 |
|
| 1336 | /**
|
| 1337 | * Recaculates the 'hasattachment' property of the given tickets
|
| 1338 | *
|
| 1339 | * @author Varun Shoor
|
| 1340 | * @param array $_ticketIDList The Ticket ID List
|
| 1341 | * @return bool "true" on Success, "false" otherwise
|
| 1342 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 1343 | */
|
| 1344 | static public function RecalculateHasAttachmentProperty($_ticketIDList) {
|
| 1345 | $_SWIFT = SWIFT::GetInstance();
|
| 1346 |
|
| 1347 | if (!_is_array($_ticketIDList)) {
|
| 1348 | return false;
|
| 1349 | }
|
| 1350 |
|
| 1351 | $_finalTicketIDList = array();
|
| 1352 | $_SWIFT->Database->Query("SELECT ticketid FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 1353 | while ($_SWIFT->Database->NextRecord()) {
|
| 1354 | $_finalTicketIDList[] = $_SWIFT->Database->Record['ticketid'];
|
| 1355 | }
|
| 1356 |
|
| 1357 | if (!count($_finalTicketIDList)) {
|
| 1358 | return false;
|
| 1359 | }
|
| 1360 |
|
| 1361 | // Now we calculate attachments
|
| 1362 | $_attachmentCountContainer = array();
|
| 1363 | $_SWIFT->Database->Query("SELECT COUNT(*) AS totalitems, ticketid FROM " . TABLE_PREFIX . "attachments GROUP BY ticketid HAVING ticketid IN (" . BuildIN($_finalTicketIDList) . ")");
|
| 1364 | while ($_SWIFT->Database->NextRecord()) {
|
| 1365 | $_attachmentCountContainer[$_SWIFT->Database->Record['ticketid']] = intval($_SWIFT->Database->Record['totalitems']);
|
| 1366 | }
|
| 1367 |
|
| 1368 | $_attachmentTicketIDList = array();
|
| 1369 | foreach ($_attachmentCountContainer as $_key => $_val) {
|
| 1370 | if ($_val > 0) {
|
| 1371 | $_attachmentTicketIDList[] = $_key;
|
| 1372 | }
|
| 1373 | }
|
| 1374 |
|
| 1375 | $_nonAttachmentTicketIDList = array();
|
| 1376 | foreach ($_finalTicketIDList as $_ticketID) {
|
| 1377 | if (!in_array($_ticketID, $_attachmentTicketIDList)) {
|
| 1378 | $_nonAttachmentTicketIDList[] = $_ticketID;
|
| 1379 | }
|
| 1380 | }
|
| 1381 |
|
| 1382 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('hasattachments' => '1'), 'UPDATE', "ticketid IN (" . BuildIN($_attachmentTicketIDList) . ")");
|
| 1383 |
|
| 1384 | if (count($_nonAttachmentTicketIDList)) {
|
| 1385 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('hasattachments' => '0'), 'UPDATE', "ticketid IN (" . BuildIN($_nonAttachmentTicketIDList) . ")");
|
| 1386 | }
|
| 1387 |
|
| 1388 | return true;
|
| 1389 | }
|
| 1390 |
|
| 1391 | /**
|
| 1392 | * Retrieve the User Group ID based on User ID
|
| 1393 | *
|
| 1394 | * @author Varun Shoor
|
| 1395 | * @return bool "true" on Success, "false" otherwise
|
| 1396 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1397 | */
|
| 1398 | public function GetUserGroupID() {
|
| 1399 | if (!$this->GetIsClassLoaded()) {
|
| 1400 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1401 |
|
| 1402 | return false;
|
| 1403 | }
|
| 1404 |
|
| 1405 | $_userID = intval($this->GetProperty('userid'));
|
| 1406 | if (empty($_userID)) {
|
| 1407 | return false;
|
| 1408 | }
|
| 1409 |
|
| 1410 | try {
|
| 1411 | $_SWIFT_UserObject = $this->GetUserObject();
|
| 1412 |
|
| 1413 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded()) {
|
| 1414 | return $_SWIFT_UserObject->GetProperty('usergroupid');
|
| 1415 | }
|
| 1416 |
|
| 1417 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 1418 | return false;
|
| 1419 | }
|
| 1420 |
|
| 1421 | return false;
|
| 1422 | }
|
| 1423 |
|
| 1424 | /**
|
| 1425 | * Retrieve the SLA properties. This array is used to process the SLA rules and the value should match the criteria specified for SWIFT_SLA
|
| 1426 | *
|
| 1427 | * @author Varun Shoor
|
| 1428 | * @return mixed "_slaProperties" (ARRAY) on Success, "false" otherwise
|
| 1429 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1430 | */
|
| 1431 | public function GetSLAProperties() {
|
| 1432 | if (!$this->GetIsClassLoaded()) {
|
| 1433 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1434 |
|
| 1435 | return false;
|
| 1436 | }
|
| 1437 |
|
| 1438 | $_slaProperties = array();
|
| 1439 | $_slaProperties[SWIFT_SLA::SLA_TICKETSTATUS] = $this->GetProperty('ticketstatusid');
|
| 1440 | $_slaProperties[SWIFT_SLA::SLA_TICKETPRIORITY] = $this->GetProperty('priorityid');
|
| 1441 | $_slaProperties[SWIFT_SLA::SLA_TICKETDEPARTMENT] = $this->GetProperty('departmentid');
|
| 1442 | $_slaProperties[SWIFT_SLA::SLA_TICKETOWNER] = $this->GetProperty('ownerstaffid');
|
| 1443 | $_slaProperties[SWIFT_SLA::SLA_TICKETEMAILQUEUE] = $this->GetProperty('emailqueueid');
|
| 1444 | $_slaProperties[SWIFT_SLA::SLA_TICKETFLAGTYPE] = $this->GetProperty('flagtype');
|
| 1445 | $_slaProperties[SWIFT_SLA::SLA_TICKETCREATOR] = $this->GetProperty('creator');
|
| 1446 | $_slaProperties[SWIFT_SLA::SLA_TICKETUSERGROUP] = $this->GetUserGroupID();
|
| 1447 |
|
| 1448 | $_slaProperties[SWIFT_SLA::SLA_TICKETFULLNAME] = $this->GetProperty('fullname');
|
| 1449 | $_slaProperties[SWIFT_SLA::SLA_TICKETEMAIL] = $this->GetProperty('email');
|
| 1450 | $_slaProperties[SWIFT_SLA::SLA_TICKETLASTREPLIER] = $this->GetProperty('lastreplier');
|
| 1451 | $_slaProperties[SWIFT_SLA::SLA_TICKETSUBJECT] = $this->GetProperty('subject');
|
| 1452 | $_slaProperties[SWIFT_SLA::SLA_TICKETCHARSET] = $this->GetProperty('charset');
|
| 1453 |
|
| 1454 | $_slaProperties[SWIFT_SLA::SLA_TICKETTEMPLATEGROUP] = $this->GetProperty('tgroupid');
|
| 1455 | $_slaProperties[SWIFT_SLA::SLA_TICKETISRESOLVED] = $this->GetProperty('isresolved');
|
| 1456 | $_slaProperties[SWIFT_SLA::SLA_TICKETTYPE] = $this->GetProperty('tickettypeid');
|
| 1457 | $_slaProperties[SWIFT_SLA::SLA_TICKETWASREOPENED] = $this->GetProperty('wasreopened');
|
| 1458 | $_slaProperties[SWIFT_SLA::SLA_TICKETTOTALREPLIES] = $this->GetProperty('totalreplies');
|
| 1459 | $_slaProperties[SWIFT_SLA::SLA_TICKETBAYESCATEGORY] = $this->GetProperty('bayescategoryid');
|
| 1460 |
|
| 1461 | return $_slaProperties;
|
| 1462 | }
|
| 1463 |
|
| 1464 | /**
|
| 1465 | * process the SLA Overdue time
|
| 1466 | *
|
| 1467 | * @author Varun Shoor
|
| 1468 | * @param bool $_processResolutionDue (OPTIONAL) Whether to process the resolution due dateline
|
| 1469 | * @return bool "true" on Success, "false" otherwise
|
| 1470 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1471 | */
|
| 1472 | public function ProcessSLAOverdue($_processResolutionDue = false) {
|
| 1473 | $_SWIFT = SWIFT::GetInstance();
|
| 1474 | chdir(SWIFT_BASEPATH);
|
| 1475 | if (!$this->GetIsClassLoaded()) {
|
| 1476 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1477 |
|
| 1478 | return false;
|
| 1479 | }
|
| 1480 |
|
| 1481 | if ($this->_noSLACalculation == true) {
|
| 1482 | return false;
|
| 1483 | }
|
| 1484 |
|
| 1485 | $this->Load->Library('SLA:SLAManager');
|
| 1486 |
|
| 1487 | $_slaManagerResult = $this->SLAManager->GetDueTime($this);
|
| 1488 | if (count($_slaManagerResult) != 2) {
|
| 1489 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 1490 | }
|
| 1491 |
|
| 1492 | $_SWIFT_SLAPlanObject = $_slaManagerResult[0];
|
| 1493 | $_overDueSeconds = $_slaManagerResult[1];
|
| 1494 |
|
| 1495 | if ($_SWIFT_SLAPlanObject instanceof SWIFT_SLA && $_SWIFT_SLAPlanObject->GetIsClassLoaded()) {
|
| 1496 | // Notification Rule
|
| 1497 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_SLAPLAN, $this->GetProperty('slaplanid'), $_SWIFT_SLAPlanObject->GetSLAPlanID());
|
| 1498 |
|
| 1499 | /*
|
| 1500 | * BUG FIX - Varun Shoor
|
| 1501 | *
|
| 1502 | * SWIFT-970 Resolution time is not updated according to SLA plan, while changing the ticket department using Mass Action
|
| 1503 | *
|
| 1504 | * Comments: We now force resolution due time recalculation if SLA plan changes
|
| 1505 | */
|
| 1506 | if ($this->GetProperty('slaplanid') != $_SWIFT_SLAPlanObject->GetSLAPlanID()) {
|
| 1507 | $_processResolutionDue = true;
|
| 1508 | }
|
| 1509 |
|
| 1510 | $this->UpdatePool('slaplanid', $_SWIFT_SLAPlanObject->GetSLAPlanID());
|
| 1511 | $this->UpdatePool('isescalatedvolatile', '0');
|
| 1512 |
|
| 1513 |
|
| 1514 | /**
|
| 1515 | * BUG FIX - Parminder Singh
|
| 1516 | *
|
| 1517 | * SWIFT-795: Issue with SLA plan retention
|
| 1518 | *
|
| 1519 | * Comments: If no SLA found then clear the exising one.
|
| 1520 | */
|
| 1521 | } else {
|
| 1522 | // $this->UpdatePool('slaplanid', '0');
|
| 1523 | }
|
| 1524 |
|
| 1525 | /**
|
| 1526 | * BUG FIX - Parminder Singh
|
| 1527 | *
|
| 1528 | * SWIFT-1583: "Clear the Due Time" setting under Ticket Statuses settings, does not work properly
|
| 1529 | *
|
| 1530 | * Comments: If the setting 'Clear the Due Time' is disabled and overdue seconds ($_overDueSeconds) are coming blank then no need for SLA/ overdue hours.
|
| 1531 | */
|
| 1532 | $_ticketStatusCache = $this->Cache->Get('statuscache');
|
| 1533 | if (isset($_ticketStatusCache[$this->GetProperty('ticketstatusid')])) {
|
| 1534 | $_ticketStatusContainer = $_ticketStatusCache[$this->GetProperty('ticketstatusid')];
|
| 1535 | if ($_ticketStatusContainer['resetduetime'] == '0' && empty($_overDueSeconds) && $this->GetProperty('duetime') != '0') {
|
| 1536 | $this->_noSLACalculation = true;
|
| 1537 |
|
| 1538 | return true;
|
| 1539 | }
|
| 1540 | }
|
| 1541 |
|
| 1542 | // Create Audit Log
|
| 1543 | $_renderedDate = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_overDueSeconds);
|
| 1544 | if (empty($_overDueSeconds)) {
|
| 1545 | $_renderedDate = $this->Language->Get('duetimecleared');
|
| 1546 | }
|
| 1547 |
|
| 1548 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 1549 | sprintf($_SWIFT->Language->Get('al_due'), $_renderedDate),
|
| 1550 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('duetime'), '', $_overDueSeconds, '');
|
| 1551 |
|
| 1552 | $this->UpdatePool('duetime', intval($_overDueSeconds));
|
| 1553 |
|
| 1554 | if ($_processResolutionDue == true) {
|
| 1555 | if (!$_SWIFT_SLAPlanObject instanceof SWIFT_SLA || !$_SWIFT_SLAPlanObject->GetIsClassLoaded())
|
| 1556 | {
|
| 1557 | $_SWIFT_SLAPlanObject = null;
|
| 1558 | }
|
| 1559 |
|
| 1560 | $_slaManagerResult_ResolutionDue = $this->SLAManager->GetResolutionTime($this, $_SWIFT_SLAPlanObject);
|
| 1561 | $_resolutionOverDueSeconds = $_slaManagerResult_ResolutionDue[1];
|
| 1562 |
|
| 1563 | // Create Audit Log
|
| 1564 | $_resolutionRenderedDate = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_resolutionOverDueSeconds);
|
| 1565 | if (empty($_resolutionOverDueSeconds)) {
|
| 1566 | $_resolutionRenderedDate = $this->Language->Get('duetimecleared');
|
| 1567 | }
|
| 1568 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 1569 | sprintf($_SWIFT->Language->Get('al_resolutiondue'), $_resolutionRenderedDate),
|
| 1570 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('resolutionduedateline'), '', $_resolutionOverDueSeconds, '');
|
| 1571 |
|
| 1572 | $this->UpdatePool('resolutionduedateline', intval($_resolutionOverDueSeconds));
|
| 1573 | }
|
| 1574 |
|
| 1575 | $this->_noSLACalculation = true;
|
| 1576 |
|
| 1577 | return true;
|
| 1578 | }
|
| 1579 |
|
| 1580 | /**
|
| 1581 | * Queue the SLA Overdue calculation on shutdown
|
| 1582 | *
|
| 1583 | * @author Varun Shoor
|
| 1584 | * @param bool $_processResolutionDue (OPTIONAL) Whether to process the resolution due dateline
|
| 1585 | * @return bool "true" on Success, "false" otherwise
|
| 1586 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1587 | */
|
| 1588 | public function QueueSLAOverdue($_processResolutionDue = false) {
|
| 1589 | if (!$this->GetIsClassLoaded()) {
|
| 1590 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1591 |
|
| 1592 | return false;
|
| 1593 | }
|
| 1594 |
|
| 1595 | if ($this->_slaOverdueQueued != -1) {
|
| 1596 | return true;
|
| 1597 | }
|
| 1598 |
|
| 1599 | $this->_slaOverdueQueued = $_processResolutionDue;
|
| 1600 |
|
| 1601 | register_shutdown_function(array($this, 'ProcessSLAOverdue'), $this->_slaOverdueQueued);
|
| 1602 |
|
| 1603 | return true;
|
| 1604 | }
|
| 1605 |
|
| 1606 | /**
|
| 1607 | * Set a fixed SLA Plan for this Ticket
|
| 1608 | *
|
| 1609 | * @author Varun Shoor
|
| 1610 | * @param SWIFT_SLA $_SWIFT_SLAObject The SWIFT_SLA Object Pointer
|
| 1611 | * @return bool "true" on Success, "false" otherwise
|
| 1612 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 1613 | */
|
| 1614 | public function SetSLA(SWIFT_SLA $_SWIFT_SLAObject) {
|
| 1615 | $_SWIFT = SWIFT::GetInstance();
|
| 1616 |
|
| 1617 | if (!$this->GetIsClassLoaded()) {
|
| 1618 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1619 |
|
| 1620 | return false;
|
| 1621 | } else if (!$_SWIFT_SLAObject instanceof SWIFT_SLA || !$_SWIFT_SLAObject->GetIsClassLoaded()) {
|
| 1622 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 1623 | }
|
| 1624 |
|
| 1625 | // If the current sla plan and the one provided matches then bail out
|
| 1626 | if ($this->GetProperty('ticketslaplanid') == $_SWIFT_SLAObject->GetSLAPlanID()) {
|
| 1627 | return true;
|
| 1628 | }
|
| 1629 |
|
| 1630 | $_slaPlanCache = $this->Cache->Get('slaplancache');
|
| 1631 |
|
| 1632 | // Create Audit Log
|
| 1633 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATESLA,
|
| 1634 | sprintf($_SWIFT->Language->Get('al_sla'), $_SWIFT_SLAObject->GetProperty('title')),
|
| 1635 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('ticketslaplanid'), '', $_SWIFT_SLAObject->GetSLAPlanID(), '');
|
| 1636 |
|
| 1637 | // Notification Rule
|
| 1638 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_SLAPLAN, $this->GetProperty('ticketslaplanid'), $_SWIFT_SLAObject->GetSLAPlanID());
|
| 1639 |
|
| 1640 | // Notification Update
|
| 1641 | $_oldTicketSLAPlanID = $this->GetProperty('ticketslaplanid');
|
| 1642 | $_oldSLATitle = $_newSLATitle = '';
|
| 1643 | if ($_oldTicketSLAPlanID != '0') {
|
| 1644 | if (isset($_slaPlanCache[$_oldTicketSLAPlanID])) {
|
| 1645 | $_oldSLATitle = $_slaPlanCache[$_oldTicketSLAPlanID]['title'];
|
| 1646 | } else {
|
| 1647 | $_oldSLATitle = $this->Language->Get('na');
|
| 1648 | }
|
| 1649 | }
|
| 1650 |
|
| 1651 | $_newSLATitle = $_SWIFT_SLAObject->GetProperty('title');
|
| 1652 |
|
| 1653 | $this->Notification->Update($this->Language->Get('notification_sla'), $_oldSLATitle, $_newSLATitle);
|
| 1654 |
|
| 1655 | $this->UpdatePool('ticketslaplanid', intval($_SWIFT_SLAObject->GetSLAPlanID()));
|
| 1656 | $this->UpdatePool('slaplanid', intval($_SWIFT_SLAObject->GetSLAPlanID()));
|
| 1657 | $this->UpdatePool('isescalatedvolatile', '0');
|
| 1658 |
|
| 1659 | // We set these to 0 and expect the sla processing engine to set the correct values
|
| 1660 | // $this->UpdatePool('duetime', '0');
|
| 1661 | // $this->UpdatePool('resolutionduedateline', '0');
|
| 1662 |
|
| 1663 | $this->_noSLACalculation = false;
|
| 1664 | $this->ProcessSLAOverdue(true);
|
| 1665 | // $this->QueueSLAOverdue(true);
|
| 1666 |
|
| 1667 | // Load and Process Workflow Rules
|
| 1668 | self::AddToWorkflowQueue($this);
|
| 1669 |
|
| 1670 | return true;
|
| 1671 | }
|
| 1672 |
|
| 1673 | /**
|
| 1674 | * Clear the fixed Ticket SLA Plan
|
| 1675 | *
|
| 1676 | * @author Varun Shoor
|
| 1677 | * @return bool "true" on Success, "false" otherwise
|
| 1678 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1679 | */
|
| 1680 | public function ClearSLA() {
|
| 1681 | $_SWIFT = SWIFT::GetInstance();
|
| 1682 |
|
| 1683 | if (!$this->GetIsClassLoaded()) {
|
| 1684 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1685 |
|
| 1686 | return false;
|
| 1687 | }
|
| 1688 |
|
| 1689 | if ($this->GetProperty('ticketslaplanid') == '0') {
|
| 1690 | return true;
|
| 1691 | }
|
| 1692 |
|
| 1693 | $_slaPlanCache = $this->Cache->Get('slaplancache');
|
| 1694 |
|
| 1695 | // Create Audit Log
|
| 1696 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATESLA,
|
| 1697 | $_SWIFT->Language->Get('al_slaclear'),
|
| 1698 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('ticketslaplanid'), '', 0, '');
|
| 1699 |
|
| 1700 | // Notification Update
|
| 1701 | $_oldTicketSLAPlanID = $this->GetProperty('ticketslaplanid');
|
| 1702 | $_oldSLATitle = $_newSLATitle = '';
|
| 1703 | if ($_oldTicketSLAPlanID != '0') {
|
| 1704 | if (isset($_slaPlanCache[$_oldTicketSLAPlanID])) {
|
| 1705 | $_oldSLATitle = $_slaPlanCache[$_oldTicketSLAPlanID]['title'];
|
| 1706 | } else {
|
| 1707 | $_oldSLATitle = $this->Language->Get('na');
|
| 1708 | }
|
| 1709 | }
|
| 1710 |
|
| 1711 | $_newSLATitle = $this->Language->Get('notificationcleared');
|
| 1712 |
|
| 1713 | $this->Notification->Update($this->Language->Get('notification_sla'), $_oldSLATitle, $_newSLATitle);
|
| 1714 |
|
| 1715 | $this->UpdatePool('ticketslaplanid', 0);
|
| 1716 |
|
| 1717 | $this->QueueSLAOverdue();
|
| 1718 |
|
| 1719 | // Load and Process Workflow Rules
|
| 1720 | self::AddToWorkflowQueue($this);
|
| 1721 |
|
| 1722 | return true;
|
| 1723 | }
|
| 1724 |
|
| 1725 | /**
|
| 1726 | * Escalate this Ticket
|
| 1727 | *
|
| 1728 | * @author Varun Shoor
|
| 1729 | * @param SWIFT_EscalationRule $_SWIFT_EscalationRuleObject
|
| 1730 | * @return bool "true" on Success, "false" otherwise
|
| 1731 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 1732 | */
|
| 1733 | public function Escalate(SWIFT_EscalationRule $_SWIFT_EscalationRuleObject) {
|
| 1734 | $_SWIFT = SWIFT::GetInstance();
|
| 1735 |
|
| 1736 | if (!$this->GetIsClassLoaded()) {
|
| 1737 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1738 |
|
| 1739 | return false;
|
| 1740 | } else if (!$_SWIFT_EscalationRuleObject instanceof SWIFT_EscalationRule || !$_SWIFT_EscalationRuleObject->GetIsClassLoaded()) {
|
| 1741 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 1742 | }
|
| 1743 |
|
| 1744 | $_staffCache = $this->Cache->Get('staffcache');
|
| 1745 |
|
| 1746 | // We execute this before all arguments so that if a custom SLA plan is set, it can override this value.
|
| 1747 | $this->UpdatePool('isescalatedvolatile', '1');
|
| 1748 |
|
| 1749 | SWIFT_EscalationPath::Create($this, $this->GetProperty('slaplanid'), $_SWIFT_EscalationRuleObject->GetEscalationRuleID(),
|
| 1750 | $this->GetProperty('ownerstaffid'), $this->GetProperty('departmentid'), $this->GetProperty('ticketstatusid'),
|
| 1751 | $this->GetProperty('priorityid'), $this->GetProperty('tickettypeid'), $this->GetProperty('flagtype'));
|
| 1752 |
|
| 1753 | if ($_SWIFT_EscalationRuleObject->GetProperty('staffid') != '-1' && $_SWIFT_EscalationRuleObject->GetProperty('staffid') != '0' && isset($_staffCache[$_SWIFT_EscalationRuleObject->GetProperty('staffid')]))
|
| 1754 | {
|
| 1755 | $this->SetOwner($_SWIFT_EscalationRuleObject->GetProperty('staffid'));
|
| 1756 | }
|
| 1757 |
|
| 1758 | if ($_SWIFT_EscalationRuleObject->GetProperty('departmentid') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('departmentid') != '-1')
|
| 1759 | {
|
| 1760 | $this->SetDepartment($_SWIFT_EscalationRuleObject->GetProperty('departmentid'));
|
| 1761 | }
|
| 1762 |
|
| 1763 | if ($_SWIFT_EscalationRuleObject->GetProperty('ticketstatusid') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('ticketstatusid') != '-1')
|
| 1764 | {
|
| 1765 | $this->SetStatus($_SWIFT_EscalationRuleObject->GetProperty('ticketstatusid'));
|
| 1766 | }
|
| 1767 |
|
| 1768 | if ($_SWIFT_EscalationRuleObject->GetProperty('priorityid') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('priorityid') != '-1')
|
| 1769 | {
|
| 1770 | $this->SetPriority($_SWIFT_EscalationRuleObject->GetProperty('priorityid'));
|
| 1771 | }
|
| 1772 |
|
| 1773 | if ($_SWIFT_EscalationRuleObject->GetProperty('tickettypeid') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('tickettypeid') != '-1')
|
| 1774 | {
|
| 1775 | $this->SetType($_SWIFT_EscalationRuleObject->GetProperty('tickettypeid'));
|
| 1776 | }
|
| 1777 |
|
| 1778 | if ($_SWIFT_EscalationRuleObject->GetProperty('flagtype') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('flagtype') != '-1')
|
| 1779 | {
|
| 1780 | $this->SetFlag($_SWIFT_EscalationRuleObject->GetProperty('flagtype'));
|
| 1781 | }
|
| 1782 |
|
| 1783 | if ($_SWIFT_EscalationRuleObject->GetProperty('newslaplanid') != '0' && $_SWIFT_EscalationRuleObject->GetProperty('newslaplanid') != '-1')
|
| 1784 | {
|
| 1785 | $this->SetSLA(new SWIFT_SLA(new SWIFT_DataID($_SWIFT_EscalationRuleObject->GetProperty('newslaplanid'))));
|
| 1786 | }
|
| 1787 |
|
| 1788 | if ($_SWIFT_EscalationRuleObject->GetProperty('addtags') != '')
|
| 1789 | {
|
| 1790 | $_tagContainer = json_decode($_SWIFT_EscalationRuleObject->GetProperty('addtags'));
|
| 1791 | if (is_array($_tagContainer)) {
|
| 1792 | SWIFT_Tag::AddTags(SWIFT_TagLink::TYPE_TICKET, $this->GetTicketID(),
|
| 1793 | $_tagContainer, false);
|
| 1794 | }
|
| 1795 | }
|
| 1796 |
|
| 1797 | if ($_SWIFT_EscalationRuleObject->GetProperty('removetags') != '')
|
| 1798 | {
|
| 1799 | $_tagContainer = json_decode($_SWIFT_EscalationRuleObject->GetProperty('removetags'));
|
| 1800 | if (is_array($_tagContainer)) {
|
| 1801 | SWIFT_Tag::RemoveTags(SWIFT_TagLink::TYPE_TICKET, array($this->GetTicketID()),
|
| 1802 | $_tagContainer, false);
|
| 1803 | }
|
| 1804 |
|
| 1805 | }
|
| 1806 |
|
| 1807 | $this->UpdatePool('escalationruleid', $_SWIFT_EscalationRuleObject->GetEscalationRuleID());
|
| 1808 | $this->UpdatePool('isescalated', '1');
|
| 1809 | $this->UpdatePool('escalatedtime', DATENOW);
|
| 1810 | $this->UpdatePool('escalationlevelcount', ($this->GetProperty('escalationlevelcount')+1));
|
| 1811 |
|
| 1812 | // Load and Process Workflow Rules
|
| 1813 | self::AddToWorkflowQueue($this);
|
| 1814 |
|
| 1815 | return true;
|
| 1816 | }
|
| 1817 |
|
| 1818 | /**
|
| 1819 | * Mark the ticket as watched
|
| 1820 | *
|
| 1821 | * @author Varun Shoor
|
| 1822 | * @return bool "true" on Success, "false" otherwise
|
| 1823 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1824 | */
|
| 1825 | public function MarkAsWatched() {
|
| 1826 | $_SWIFT = SWIFT::GetInstance();
|
| 1827 |
|
| 1828 | if (!$this->GetIsClassLoaded()) {
|
| 1829 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1830 |
|
| 1831 | return false;
|
| 1832 | }
|
| 1833 |
|
| 1834 | $this->UpdatePool('iswatched', '1');
|
| 1835 |
|
| 1836 | return true;
|
| 1837 | }
|
| 1838 |
|
| 1839 | /**
|
| 1840 | * Mark the ticket as overdue
|
| 1841 | *
|
| 1842 | * @author Varun Shoor
|
| 1843 | * @return bool "true" on Success, "false" otherwise
|
| 1844 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1845 | */
|
| 1846 | public function MarkAsDue() {
|
| 1847 | $_SWIFT = SWIFT::GetInstance();
|
| 1848 |
|
| 1849 | if (!$this->GetIsClassLoaded()) {
|
| 1850 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1851 |
|
| 1852 | return false;
|
| 1853 | }
|
| 1854 |
|
| 1855 | // Create Audit Log
|
| 1856 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 1857 | $_SWIFT->Language->Get('al_duestaffoverdue'),
|
| 1858 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('duetime'), '', DATENOW, '');
|
| 1859 |
|
| 1860 | // Notification Update
|
| 1861 | $_newDueDate = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, DATENOW);
|
| 1862 | $this->Notification->Update($this->Language->Get('notification_due'), '', $_newDueDate);
|
| 1863 |
|
| 1864 |
|
| 1865 | $this->UpdatePool('duetime', DATENOW);
|
| 1866 |
|
| 1867 | // Prevent SLA Calculation
|
| 1868 | $this->_noSLACalculation = true;
|
| 1869 |
|
| 1870 | // Load and Process Workflow Rules
|
| 1871 | self::AddToWorkflowQueue($this);
|
| 1872 |
|
| 1873 | return true;
|
| 1874 | }
|
| 1875 |
|
| 1876 | /**
|
| 1877 | * Clear the overdue time
|
| 1878 | *
|
| 1879 | * @author Varun Shoor
|
| 1880 | * @return bool "true" on Success, "false" otherwise
|
| 1881 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1882 | */
|
| 1883 | public function ClearOverdue() {
|
| 1884 | $_SWIFT = SWIFT::GetInstance();
|
| 1885 |
|
| 1886 | if (!$this->GetIsClassLoaded()) {
|
| 1887 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1888 |
|
| 1889 | return false;
|
| 1890 | }
|
| 1891 |
|
| 1892 | if ($this->GetProperty('duetime') == '0') {
|
| 1893 | return true;
|
| 1894 | }
|
| 1895 | // Create Audit Log
|
| 1896 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 1897 | $_SWIFT->Language->Get('al_duestaffclear'),
|
| 1898 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('duetime'), '', 0, '');
|
| 1899 |
|
| 1900 | // Notification Update
|
| 1901 | $_oldDueDate = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $this->GetProperty('duetime'));
|
| 1902 | $_newDueDate = $this->Language->Get('notificationcleared');
|
| 1903 |
|
| 1904 | $this->Notification->Update($this->Language->Get('notification_due'), $_oldDueDate, $_newDueDate);
|
| 1905 |
|
| 1906 | $this->UpdatePool('duetime', '0');
|
| 1907 |
|
| 1908 | // Prevent calculation of SLA due time on this ticket
|
| 1909 | $this->_noSLACalculation = true;
|
| 1910 |
|
| 1911 | // Load and Process Workflow Rules
|
| 1912 | self::AddToWorkflowQueue($this);
|
| 1913 |
|
| 1914 | return true;
|
| 1915 | }
|
| 1916 |
|
| 1917 | /**
|
| 1918 | * Set the Template Group
|
| 1919 | *
|
| 1920 | * @author Varun Shoor
|
| 1921 | * @param int $_templateGroupID The Template Group ID
|
| 1922 | * @return bool "true" on Success, "false" otherwise
|
| 1923 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 1924 | */
|
| 1925 | public function SetTemplateGroup($_templateGroupID)
|
| 1926 | {
|
| 1927 | if (!$this->GetIsClassLoaded())
|
| 1928 | {
|
| 1929 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 1930 |
|
| 1931 | return false;
|
| 1932 | }
|
| 1933 |
|
| 1934 | $this->UpdatePool('tgroupid', intval($_templateGroupID));
|
| 1935 |
|
| 1936 | return true;
|
| 1937 | }
|
| 1938 |
|
| 1939 | /**
|
| 1940 | * Clear the resolution time
|
| 1941 | *
|
| 1942 | * @author Varun Shoor
|
| 1943 | * @return bool "true" on Success, "false" otherwise
|
| 1944 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 1945 | */
|
| 1946 | public function ClearResolutionDue() {
|
| 1947 | $_SWIFT = SWIFT::GetInstance();
|
| 1948 |
|
| 1949 | if (!$this->GetIsClassLoaded()) {
|
| 1950 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1951 |
|
| 1952 | return false;
|
| 1953 | }
|
| 1954 |
|
| 1955 | if ($this->GetProperty('resolutionduedateline') == '0') {
|
| 1956 | return true;
|
| 1957 | }
|
| 1958 |
|
| 1959 | // Create Audit Log
|
| 1960 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 1961 | $_SWIFT->Language->Get('al_resduestaffclear'),
|
| 1962 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('resolutionduedateline'), '', 0, '');
|
| 1963 |
|
| 1964 | // Notification Update
|
| 1965 | $_oldDueDate = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $this->GetProperty('resolutionduedateline'));
|
| 1966 | $_newDueDate = $this->Language->Get('notificationcleared');
|
| 1967 |
|
| 1968 | $this->Notification->Update($this->Language->Get('notification_resolutiondue'), $_oldDueDate, $_newDueDate);
|
| 1969 |
|
| 1970 | $this->UpdatePool('resolutionduedateline', '0');
|
| 1971 |
|
| 1972 | // Prevent calculation of SLA due time on this ticket
|
| 1973 | $this->_noSLACalculation = true;
|
| 1974 |
|
| 1975 | // Load and Process Workflow Rules
|
| 1976 | self::AddToWorkflowQueue($this);
|
| 1977 |
|
| 1978 | return true;
|
| 1979 | }
|
| 1980 |
|
| 1981 | /**
|
| 1982 | * Set a flag on this ticket
|
| 1983 | *
|
| 1984 | * @author Varun Shoor
|
| 1985 | * @param constant $_flagType The Flag Type
|
| 1986 | * @return bool "true" on Success, "false" otherwise
|
| 1987 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 1988 | */
|
| 1989 | public function SetFlag($_flagType) {
|
| 1990 | $_SWIFT = SWIFT::GetInstance();
|
| 1991 |
|
| 1992 | if (!$this->GetIsClassLoaded()) {
|
| 1993 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 1994 |
|
| 1995 | return false;
|
| 1996 | }
|
| 1997 |
|
| 1998 | $this->Load->Library('Flag:TicketFlag');
|
| 1999 | $_flagContainer = $this->TicketFlag->GetFlagContainer();
|
| 2000 |
|
| 2001 | if ($_flagType == '0') {
|
| 2002 | // Notification Update
|
| 2003 | $_oldFlagTitle = '';
|
| 2004 | if (isset($_flagContainer[$this->GetProperty('flagtype')])) {
|
| 2005 | $_oldFlagTitle = $_flagContainer[$this->GetProperty('flagtype')][0];
|
| 2006 | }
|
| 2007 | $_newFlagTitle = $this->Language->Get('notificationcleared');
|
| 2008 |
|
| 2009 | $this->Notification->Update($this->Language->Get('notification_flag'), $_oldFlagTitle, $_newFlagTitle);
|
| 2010 |
|
| 2011 | $this->UpdatePool('flagtype', '0');
|
| 2012 |
|
| 2013 | $this->QueueSLAOverdue();
|
| 2014 |
|
| 2015 | return true;
|
| 2016 | }
|
| 2017 |
|
| 2018 | if (!SWIFT_TicketFlag::IsValidFlagType($_flagType)) {
|
| 2019 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2020 | }
|
| 2021 |
|
| 2022 | // If this ticket already has a flag set which matches the one specified.. then move on
|
| 2023 | if ($this->GetProperty('flagtype') == $_flagType) {
|
| 2024 | return true;
|
| 2025 | }
|
| 2026 |
|
| 2027 | // Create Audit Log
|
| 2028 | $_flagTitle = $_flagContainer[$_flagType][0];
|
| 2029 |
|
| 2030 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATEFLAG,
|
| 2031 | sprintf($_SWIFT->Language->Get('al_flag'), $_flagTitle),
|
| 2032 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('flagtype'), '', $_flagType, '');
|
| 2033 |
|
| 2034 | // Notification Rule
|
| 2035 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_FLAGTYPE, $this->GetProperty('flagtype'), $_flagType);
|
| 2036 |
|
| 2037 | // Notification Update
|
| 2038 | $_oldFlagTitle = '';
|
| 2039 | if (isset($_flagContainer[$this->GetProperty('flagtype')])) {
|
| 2040 | $_oldFlagTitle = $_flagContainer[$this->GetProperty('flagtype')][0];
|
| 2041 | }
|
| 2042 | $_newFlagTitle = $_flagTitle;
|
| 2043 |
|
| 2044 | $this->Notification->Update($this->Language->Get('notification_flag'), $_oldFlagTitle, $_newFlagTitle);
|
| 2045 |
|
| 2046 | $this->UpdatePool('flagtype', intval($_flagType));
|
| 2047 |
|
| 2048 | $this->QueueSLAOverdue();
|
| 2049 |
|
| 2050 | // Load and Process Workflow Rules
|
| 2051 | self::AddToWorkflowQueue($this);
|
| 2052 |
|
| 2053 | return true;
|
| 2054 | }
|
| 2055 |
|
| 2056 | /**
|
| 2057 | * Clear a flag on a ticket
|
| 2058 | *
|
| 2059 | * @author Varun Shoor
|
| 2060 | * @return bool "true" on Success, "false" otherwise
|
| 2061 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2062 | */
|
| 2063 | public function ClearFlag() {
|
| 2064 | $_SWIFT = SWIFT::GetInstance();
|
| 2065 |
|
| 2066 | if (!$this->GetIsClassLoaded()) {
|
| 2067 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2068 |
|
| 2069 | return false;
|
| 2070 | }
|
| 2071 |
|
| 2072 | // If there is no flag set, then ignore.
|
| 2073 | if ($this->GetProperty('flagtype') == '0') {
|
| 2074 | return true;
|
| 2075 | }
|
| 2076 |
|
| 2077 | $_SWIFT_TicketFlagObject = new SWIFT_TicketFlag();
|
| 2078 | $_flagContainer = $_SWIFT_TicketFlagObject->GetFlagContainer();
|
| 2079 |
|
| 2080 | // Create Audit Log
|
| 2081 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATEFLAG,
|
| 2082 | $_SWIFT->Language->Get('al_flagclear'),
|
| 2083 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('flagtype'), '', 0, '');
|
| 2084 |
|
| 2085 | // Notification Update
|
| 2086 | $_oldFlagTitle = '';
|
| 2087 | if (isset($_flagContainer[$this->GetProperty('flagtype')])) {
|
| 2088 | $_oldFlagTitle = $_flagContainer[$this->GetProperty('flagtype')][0];
|
| 2089 | }
|
| 2090 | $_newFlagTitle = $this->Language->Get('notificationcleared');
|
| 2091 |
|
| 2092 | $this->Notification->Update($this->Language->Get('notification_flag'), $_oldFlagTitle, $_newFlagTitle);
|
| 2093 |
|
| 2094 | $this->UpdatePool('flagtype', 0);
|
| 2095 |
|
| 2096 | $this->QueueSLAOverdue();
|
| 2097 |
|
| 2098 | // Load and Process Workflow Rules
|
| 2099 | self::AddToWorkflowQueue($this);
|
| 2100 |
|
| 2101 | return true;
|
| 2102 | }
|
| 2103 |
|
| 2104 | /**
|
| 2105 | * Change the department for the ticket
|
| 2106 | *
|
| 2107 | * @author Varun Shoor
|
| 2108 | * @param int $_departmentID The department id
|
| 2109 | * @return bool "true" on Success, "false" otherwise
|
| 2110 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or if Invalid Data is Provided
|
| 2111 | */
|
| 2112 | public function SetDepartment($_departmentID) {
|
| 2113 | $_SWIFT = SWIFT::GetInstance();
|
| 2114 |
|
| 2115 | if (!$this->GetIsClassLoaded()) {
|
| 2116 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2117 |
|
| 2118 | return false;
|
| 2119 | } else if (empty($_departmentID)) {
|
| 2120 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2121 | }
|
| 2122 |
|
| 2123 | $_departmentCache = $this->Cache->Get('departmentcache');
|
| 2124 | if (!isset($_departmentCache[$_departmentID])) {
|
| 2125 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2126 | }
|
| 2127 |
|
| 2128 | // If the ticket is already in this department then bail out
|
| 2129 | if ($this->GetProperty('departmentid') == $_departmentID) {
|
| 2130 | return true;
|
| 2131 | }
|
| 2132 |
|
| 2133 | // Add old and new department to recount queue
|
| 2134 | // SWIFT_TicketManager::Recount($this->GetProperty('departmentid'));
|
| 2135 | // SWIFT_TicketManager::Recount($_departmentID);
|
| 2136 | SWIFT_TicketManager::Recount(false);
|
| 2137 |
|
| 2138 | // Create Audit Log
|
| 2139 | $_oldDepartmentTitle = $_newDepartmentTitle = '';
|
| 2140 | if (isset($_departmentCache[$this->GetProperty('departmentid')])) {
|
| 2141 | $_oldDepartmentTitle = $_departmentCache[$this->GetProperty('departmentid')]['title'];
|
| 2142 | }
|
| 2143 |
|
| 2144 | if ($this->GetProperty('departmentid') == '0') {
|
| 2145 | $_oldDepartmentTitle = $this->Language->Get('trash');
|
| 2146 | }
|
| 2147 |
|
| 2148 | $_newDepartmentTitle = $_departmentCache[$_departmentID]['title'];
|
| 2149 |
|
| 2150 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATEDEPARTMENT,
|
| 2151 | sprintf($_SWIFT->Language->Get('al_department'), $_oldDepartmentTitle, $_newDepartmentTitle),
|
| 2152 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('departmentid'), '', $_departmentID, '');
|
| 2153 |
|
| 2154 | // Notification Rule
|
| 2155 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_DEPARTMENT, $this->GetProperty('departmentid'), $_departmentID);
|
| 2156 |
|
| 2157 | // Notification Update
|
| 2158 | $_oldNotificationDepartmentTitle = $_newNotificationDepartmentTitle = '';
|
| 2159 | if ($_oldDepartmentTitle == '') {
|
| 2160 | $_oldNotificationDepartmentTitle = $this->Language->Get('na');
|
| 2161 | } else {
|
| 2162 | $_oldNotificationDepartmentTitle = $_oldDepartmentTitle;
|
| 2163 | }
|
| 2164 |
|
| 2165 | $_newNotificationDepartmentTitle = $_newDepartmentTitle;
|
| 2166 |
|
| 2167 | $_oldUserNotificationDepartmentTitle = $_oldNotificationDepartmentTitle;
|
| 2168 | $_newUserNotificationDepartmentTitle = $_newNotificationDepartmentTitle;
|
| 2169 |
|
| 2170 | if (isset($_departmentCache[$this->GetProperty('departmentid')]) && $_departmentCache[$this->GetProperty('departmentid')]['departmenttype'] == SWIFT_PRIVATE) {
|
| 2171 | $_oldUserNotificationDepartmentTitle = $this->Language->Get('private');
|
| 2172 | }
|
| 2173 |
|
| 2174 | if (isset($_departmentCache[$_departmentID]) && $_departmentCache[$_departmentID]['departmenttype'] == SWIFT_PRIVATE) {
|
| 2175 | $_newUserNotificationDepartmentTitle = $this->Language->Get('private');
|
| 2176 | }
|
| 2177 |
|
| 2178 | $this->Notification->Update($this->Language->Get('notification_department'), $_oldNotificationDepartmentTitle, $_newNotificationDepartmentTitle, $_oldUserNotificationDepartmentTitle, $_newUserNotificationDepartmentTitle);
|
| 2179 |
|
| 2180 | $this->UpdatePool('departmentid', intval($_departmentID));
|
| 2181 | $this->UpdatePool('departmenttitle', $_newDepartmentTitle);
|
| 2182 |
|
| 2183 | $this->QueueSLAOverdue();
|
| 2184 |
|
| 2185 | // Load and Process Workflow Rules
|
| 2186 | self::AddToWorkflowQueue($this);
|
| 2187 |
|
| 2188 | return true;
|
| 2189 | }
|
| 2190 |
|
| 2191 | /**
|
| 2192 | * Set the Ticket Type
|
| 2193 | *
|
| 2194 | * @author Varun Shoor
|
| 2195 | * @param int $_ticketTypeID The Ticket Type ID
|
| 2196 | * @return bool "true" on Success, "false" otherwise
|
| 2197 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 2198 | */
|
| 2199 | public function SetType($_ticketTypeID) {
|
| 2200 | $_SWIFT = SWIFT::GetInstance();
|
| 2201 |
|
| 2202 | if (!$this->GetIsClassLoaded()) {
|
| 2203 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2204 |
|
| 2205 | return false;
|
| 2206 | } else if (empty($_ticketTypeID)) {
|
| 2207 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2208 | }
|
| 2209 |
|
| 2210 | // Verify value of ticket type
|
| 2211 | $_ticketTypeCache = $this->Cache->Get('tickettypecache');
|
| 2212 | if (!isset($_ticketTypeCache[$_ticketTypeID])) {
|
| 2213 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2214 | }
|
| 2215 |
|
| 2216 | $_ticketTypeContainer = $_ticketTypeCache[$_ticketTypeID];
|
| 2217 |
|
| 2218 | // If current ticket type is same as the new type then bail out
|
| 2219 | if ($this->GetProperty('tickettypeid') == $_ticketTypeID) {
|
| 2220 | return true;
|
| 2221 | }
|
| 2222 |
|
| 2223 | // Verify the department id link of ticket type
|
| 2224 |
|
| 2225 | /*
|
| 2226 | * BUG FIX - Varun Shoor
|
| 2227 | *
|
| 2228 | * SWIFT-1298 Issue with ticket types and ticket statuses, if they are linked with Parent department
|
| 2229 | *
|
| 2230 | * Comments: None
|
| 2231 | */
|
| 2232 | $_departmentCache = $this->Cache->Get('departmentcache');
|
| 2233 | $_parentDepartmentID = false;
|
| 2234 | if (isset($_departmentCache[$this->GetProperty('departmentid')])) {
|
| 2235 | $_parentDepartmentID = $_departmentCache[$this->GetProperty('departmentid')]['parentdepartmentid'];
|
| 2236 | }
|
| 2237 |
|
| 2238 | if ($_ticketTypeContainer['departmentid'] != '0' && $_ticketTypeContainer['departmentid'] != $this->GetProperty('departmentid') && $_ticketTypeContainer['departmentid'] != $_parentDepartmentID) {
|
| 2239 | throw new SWIFT_Ticket_Exception('Ticket Type (' . intval($_ticketTypeID) . ') & Department ID (' . intval($this->GetProperty('departmentid')) . ') Mismatch');
|
| 2240 | }
|
| 2241 |
|
| 2242 | // Create Audit Log
|
| 2243 | $_oldTypeTitle = $_newTypeTitle = '';
|
| 2244 | if (isset($_ticketTypeCache[$this->GetProperty('tickettypeid')])) {
|
| 2245 | $_oldTypeTitle = $_ticketTypeCache[$this->GetProperty('tickettypeid')]['title'];
|
| 2246 | }
|
| 2247 |
|
| 2248 | $_newTypeTitle = $_ticketTypeCache[$_ticketTypeID]['title'];
|
| 2249 |
|
| 2250 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETYPE,
|
| 2251 | sprintf($_SWIFT->Language->Get('al_type'), $_oldTypeTitle, $_newTypeTitle),
|
| 2252 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('tickettypeid'), '', $_ticketTypeID, '');
|
| 2253 |
|
| 2254 | // Notification Rule
|
| 2255 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_TICKETTYPE, $this->GetProperty('tickettypeid'), $_ticketTypeID);
|
| 2256 |
|
| 2257 | // Notification Update
|
| 2258 | $_oldNotificationTypeTitle = $_newNotificationTypeTitle = '';
|
| 2259 | if ($_oldTypeTitle == '') {
|
| 2260 | $_oldNotificationTypeTitle = $this->Language->Get('na');
|
| 2261 | } else {
|
| 2262 | $_oldNotificationTypeTitle = $_oldTypeTitle;
|
| 2263 | }
|
| 2264 |
|
| 2265 | $_newNotificationTypeTitle = $_newTypeTitle;
|
| 2266 |
|
| 2267 | $_oldUserNotificationTypeTitle = $_oldNotificationTypeTitle;
|
| 2268 | $_newUserNotificationTypeTitle = $_newNotificationTypeTitle;
|
| 2269 |
|
| 2270 | if ($_ticketTypeCache[$this->GetProperty('tickettypeid')]['type'] == SWIFT_PRIVATE) {
|
| 2271 | $_oldUserNotificationTypeTitle = $this->Language->Get('private');
|
| 2272 | }
|
| 2273 |
|
| 2274 | if ($_ticketTypeCache[$_ticketTypeID]['type'] == SWIFT_PRIVATE) {
|
| 2275 | $_newUserNotificationTypeTitle = $this->Language->Get('private');
|
| 2276 | }
|
| 2277 |
|
| 2278 | $this->Notification->Update($this->Language->Get('notification_type'), $_oldNotificationTypeTitle, $_newNotificationTypeTitle, $_oldUserNotificationTypeTitle, $_newUserNotificationTypeTitle);
|
| 2279 |
|
| 2280 |
|
| 2281 | $this->UpdatePool('tickettypeid', intval($_ticketTypeID));
|
| 2282 | $this->UpdatePool('tickettypetitle', $_newTypeTitle);
|
| 2283 |
|
| 2284 | // SWIFT_TicketManager::Recount($this->GetProperty('departmentid'));
|
| 2285 | SWIFT_TicketManager::Recount(false);
|
| 2286 |
|
| 2287 | $this->QueueSLAOverdue();
|
| 2288 |
|
| 2289 | // Load and Process Workflow Rules
|
| 2290 | self::AddToWorkflowQueue($this);
|
| 2291 |
|
| 2292 | return true;
|
| 2293 | }
|
| 2294 |
|
| 2295 | /**
|
| 2296 | * Set the Has Status Changed Property
|
| 2297 | *
|
| 2298 | * @author Varun Shoor
|
| 2299 | * @param bool $_hasStatusChanged
|
| 2300 | * @return bool "true" on Success, "false" otherwise
|
| 2301 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 2302 | */
|
| 2303 | protected function SetHasStatusChanged($_hasStatusChanged)
|
| 2304 | {
|
| 2305 | if (!$this->GetIsClassLoaded()) {
|
| 2306 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 2307 |
|
| 2308 | return false;
|
| 2309 | }
|
| 2310 |
|
| 2311 | $this->_hasStatusChanged = $_hasStatusChanged;
|
| 2312 |
|
| 2313 | return true;
|
| 2314 | }
|
| 2315 |
|
| 2316 | /**
|
| 2317 | * Retrieve the Has Status Changed Property
|
| 2318 | *
|
| 2319 | * @author Varun Shoor
|
| 2320 | * @return bool "true" on Success, "false" otherwise
|
| 2321 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 2322 | */
|
| 2323 | public function GetHasStatusChanged()
|
| 2324 | {
|
| 2325 | if (!$this->GetIsClassLoaded()) {
|
| 2326 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 2327 |
|
| 2328 | return false;
|
| 2329 | }
|
| 2330 |
|
| 2331 | return $this->_hasStatusChanged;
|
| 2332 | }
|
| 2333 |
|
| 2334 | /**
|
| 2335 | * Set the Ticket Status
|
| 2336 | *
|
| 2337 | * @author Varun Shoor
|
| 2338 | * @param int $_ticketStatusID The Ticket Status ID
|
| 2339 | * @param bool $_isViaAutoClose (OPTIONAL) If the status change is via auto close
|
| 2340 | * @param bool $_suppressSurveyEmail (OPTIONAL) Whether to suppress survey email
|
| 2341 | * @return bool "true" on Success, "false" otherwise
|
| 2342 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 2343 | */
|
| 2344 | public function SetStatus($_ticketStatusID, $_isViaAutoClose = false, $_suppressSurveyEmail = false) {
|
| 2345 | $_SWIFT = SWIFT::GetInstance();
|
| 2346 |
|
| 2347 | if (!$this->GetIsClassLoaded()) {
|
| 2348 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2349 |
|
| 2350 | } else if (empty($_ticketStatusID)) {
|
| 2351 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2352 | }
|
| 2353 |
|
| 2354 | $_ticketStatusCache = $this->Cache->Get('statuscache');
|
| 2355 | if (!isset($_ticketStatusCache[$_ticketStatusID])) {
|
| 2356 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2357 | }
|
| 2358 |
|
| 2359 | $_ticketStatusContainer = $_ticketStatusCache[$_ticketStatusID];
|
| 2360 |
|
| 2361 | $this->SetHasStatusChanged(true);
|
| 2362 |
|
| 2363 | // If the current ticket status id matches then bail out
|
| 2364 | if ($this->GetProperty('ticketstatusid') == $_ticketStatusID) {
|
| 2365 | return true;
|
| 2366 | }
|
| 2367 |
|
| 2368 | // Verify the department id link of ticket status
|
| 2369 |
|
| 2370 | /*
|
| 2371 | * BUG FIX - Varun Shoor
|
| 2372 | *
|
| 2373 | * SWIFT-1298 Issue with ticket types and ticket statuses, if they are linked with Parent department
|
| 2374 | *
|
| 2375 | * Comments: None
|
| 2376 | */
|
| 2377 | $_departmentCache = $this->Cache->Get('departmentcache');
|
| 2378 | $_parentDepartmentID = false;
|
| 2379 | if (isset($_departmentCache[$this->GetProperty('departmentid')])) {
|
| 2380 | $_parentDepartmentID = $_departmentCache[$this->GetProperty('departmentid')]['parentdepartmentid'];
|
| 2381 | }
|
| 2382 |
|
| 2383 | if ($_ticketStatusContainer['departmentid'] != '0' && $_ticketStatusContainer['departmentid'] != $this->GetProperty('departmentid') && $_ticketStatusContainer['departmentid'] != $_parentDepartmentID) {
|
| 2384 | throw new SWIFT_Ticket_Exception('Ticket Status (' . intval($_ticketStatusID) . ') & Department ID (' . intval($this->GetProperty('departmentid')) . ') Mismatch');
|
| 2385 | }
|
| 2386 |
|
| 2387 | // Create Audit Log
|
| 2388 | $_oldStatusTitle = $_newStatusTitle = '';
|
| 2389 | if (isset($_ticketStatusCache[$this->GetProperty('ticketstatusid')])) {
|
| 2390 | $_oldStatusTitle = $_ticketStatusCache[$this->GetProperty('ticketstatusid')]['title'];
|
| 2391 | }
|
| 2392 |
|
| 2393 | $_newStatusTitle = $_ticketStatusCache[$_ticketStatusID]['title'];
|
| 2394 |
|
| 2395 | $_statusLanguageKey = 'al_status';
|
| 2396 | if ($_isViaAutoClose) {
|
| 2397 | $_statusLanguageKey = 'al_statusautoclose';
|
| 2398 | }
|
| 2399 |
|
| 2400 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATESTATUS,
|
| 2401 | sprintf($_SWIFT->Language->Get($_statusLanguageKey), $_oldStatusTitle, $_newStatusTitle),
|
| 2402 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('ticketstatusid'), '', $_ticketStatusID, '');
|
| 2403 |
|
| 2404 | // Notification Rule
|
| 2405 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_TICKETSTATUS, $this->GetProperty('ticketstatusid'), $_ticketStatusID);
|
| 2406 |
|
| 2407 | // Notification Update
|
| 2408 | $_oldNotificationStatusTitle = $_newNotificationStatusTitle = '';
|
| 2409 | if ($_oldStatusTitle == '') {
|
| 2410 | $_oldNotificationStatusTitle = $this->Language->Get('na');
|
| 2411 | } else {
|
| 2412 | $_oldNotificationStatusTitle = $_oldStatusTitle;
|
| 2413 | }
|
| 2414 |
|
| 2415 | $_newNotificationStatusTitle = $_newStatusTitle;
|
| 2416 |
|
| 2417 | $_oldUserNotificationStatusTitle = $_oldNotificationStatusTitle;
|
| 2418 | $_newUserNotificationStatusTitle = $_newNotificationStatusTitle;
|
| 2419 |
|
| 2420 | if ($_ticketStatusCache[$this->GetProperty('ticketstatusid')]['statustype'] == SWIFT_PRIVATE) {
|
| 2421 | $_oldUserNotificationStatusTitle = $this->Language->Get('private');
|
| 2422 | }
|
| 2423 |
|
| 2424 | if ($_ticketStatusCache[$_ticketStatusID]['statustype'] == SWIFT_PRIVATE) {
|
| 2425 | $_newUserNotificationStatusTitle = $this->Language->Get('private');
|
| 2426 | }
|
| 2427 |
|
| 2428 | $this->Notification->Update($this->Language->Get('notification_status'), $_oldNotificationStatusTitle, $_newNotificationStatusTitle, $_oldUserNotificationStatusTitle, $_newUserNotificationStatusTitle);
|
| 2429 |
|
| 2430 | $this->UpdatePool('ticketstatusid', intval($_ticketStatusID));
|
| 2431 | $this->UpdatePool('ticketstatustitle', $_newStatusTitle);
|
| 2432 |
|
| 2433 | // SWIFT_TicketManager::Recount($this->GetProperty('departmentid'));
|
| 2434 | SWIFT_TicketManager::Recount(false);
|
| 2435 |
|
| 2436 | // Was reopened?
|
| 2437 | if ($_ticketStatusContainer['markasresolved'] == '0' && $this->GetProperty('isresolved') == '1') {
|
| 2438 | $this->UpdatePool('wasreopened', '1');
|
| 2439 | $this->UpdatePool('reopendateline', DATENOW);
|
| 2440 | }
|
| 2441 |
|
| 2442 | if ($_ticketStatusContainer['resetduetime'] == '1') {
|
| 2443 | $this->ClearOverdue();
|
| 2444 | }
|
| 2445 |
|
| 2446 | if ($_ticketStatusContainer['markasresolved'] == '1')
|
| 2447 | {
|
| 2448 | $this->UpdatePool('isresolved', '1');
|
| 2449 | $this->UpdatePool('resolutiondateline', DATENOW);
|
| 2450 | $this->UpdatePool('repliestoresolution', $this->GetProperty('totalreplies'));
|
| 2451 |
|
| 2452 | // How much time did it take to resolve this ticket?
|
| 2453 | $this->UpdatePool('resolutionseconds', DATENOW-$this->GetProperty('dateline'));
|
| 2454 | } else {
|
| 2455 | $this->UpdatePool('isresolved', '0');
|
| 2456 |
|
| 2457 | // Are we changing to an unresolved status and ticket is marked as auto closed or pending closure?
|
| 2458 | if ($this->GetProperty('autoclosestatus') != self::AUTOCLOSESTATUS_NONE) {
|
| 2459 | $this->UpdatePool('autoclosestatus', self::AUTOCLOSESTATUS_NONE);
|
| 2460 | $this->UpdatePool('isautoclosed', '0');
|
| 2461 | $this->UpdatePool('autoclosetimeline', '0');
|
| 2462 | }
|
| 2463 | }
|
| 2464 |
|
| 2465 | // If the status is set to resolved then we reset the resolution due time
|
| 2466 | $_processResolutionDue = false;
|
| 2467 | if ($_ticketStatusContainer['markasresolved'] == '1') {
|
| 2468 | $this->UpdatePool('resolutionduedateline', '0');
|
| 2469 | $this->UpdatePool('duetime', '0');
|
| 2470 | $this->UpdatePool('slaplanid', '0');
|
| 2471 |
|
| 2472 | $this->_noSLACalculation = true;
|
| 2473 |
|
| 2474 | // Otherwise if its not, and resolutionduedateline is 0 then we force it to recalculate the resolution due time
|
| 2475 | } else if ($_ticketStatusContainer['markasresolved'] == '0' && $this->GetProperty('resolutionduedateline') == '0') {
|
| 2476 | $_processResolutionDue = true;
|
| 2477 | }
|
| 2478 |
|
| 2479 | // Do we have to trigger a survey?
|
| 2480 | if ($_ticketStatusContainer['triggersurvey'] == '1' && !$_suppressSurveyEmail)
|
| 2481 | {
|
| 2482 | $this->Load->Library('Ticket:TicketEmailDispatch', array($this));
|
| 2483 | $this->TicketEmailDispatch->DispatchSurvey();
|
| 2484 | }
|
| 2485 |
|
| 2486 | $this->QueueSLAOverdue($_processResolutionDue);
|
| 2487 |
|
| 2488 | // Is First Contact Resolved?
|
| 2489 | if ($this->GetProperty('totalreplies') == '0' && $_ticketStatusContainer['markasresolved'] == '1' && $this->GetProperty('isfirstcontactresolved') == '0') {
|
| 2490 | $this->UpdatePool('isfirstcontactresolved', '1');
|
| 2491 | }
|
| 2492 |
|
| 2493 | // Load and Process Workflow Rules
|
| 2494 | self::AddToWorkflowQueue($this);
|
| 2495 |
|
| 2496 | return true;
|
| 2497 | }
|
| 2498 |
|
| 2499 | /**
|
| 2500 | * Set the Ticket Priority
|
| 2501 | *
|
| 2502 | * @author Varun Shoor
|
| 2503 | * @param int $_ticketPriorityID The Ticket Priority ID
|
| 2504 | * @return bool "true" on Success, "false" otherwise
|
| 2505 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 2506 | */
|
| 2507 | public function SetPriority($_ticketPriorityID) {
|
| 2508 | $_SWIFT = SWIFT::GetInstance();
|
| 2509 |
|
| 2510 | if (!$this->GetIsClassLoaded()) {
|
| 2511 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2512 |
|
| 2513 | return false;
|
| 2514 | } else if (empty($_ticketPriorityID)) {
|
| 2515 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2516 | }
|
| 2517 |
|
| 2518 | $_ticketPriorityCache = $this->Cache->Get('prioritycache');
|
| 2519 | if (!isset($_ticketPriorityCache[$_ticketPriorityID])) {
|
| 2520 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2521 | }
|
| 2522 |
|
| 2523 | $_ticketPriorityContainer = $_ticketPriorityCache[$_ticketPriorityID];
|
| 2524 |
|
| 2525 | // If the current ticket priority id matches then bail out
|
| 2526 | if ($this->GetProperty('priorityid') == $_ticketPriorityID) {
|
| 2527 | return true;
|
| 2528 | }
|
| 2529 |
|
| 2530 | // Create Audit Log
|
| 2531 | $_oldPriorityTitle = $_newPriorityTitle = '';
|
| 2532 | if (isset($_ticketPriorityCache[$this->GetProperty('priorityid')])) {
|
| 2533 | $_oldPriorityTitle = $_ticketPriorityCache[$this->GetProperty('priorityid')]['title'];
|
| 2534 | }
|
| 2535 |
|
| 2536 | $_newPriorityTitle = $_ticketPriorityCache[$_ticketPriorityID]['title'];
|
| 2537 |
|
| 2538 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATEPRIORITY,
|
| 2539 | sprintf($_SWIFT->Language->Get('al_priority'), $_oldPriorityTitle, $_newPriorityTitle),
|
| 2540 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('priorityid'), '', $_ticketPriorityID, '');
|
| 2541 |
|
| 2542 | // Notification Rule
|
| 2543 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_TICKETPRIORITY, $this->GetProperty('priorityid'), $_ticketPriorityID);
|
| 2544 |
|
| 2545 | // Notification Update
|
| 2546 | $_oldNotificationPriorityTitle = $_newNotificationPriorityTitle = '';
|
| 2547 | if ($_oldPriorityTitle == '') {
|
| 2548 | $_oldNotificationPriorityTitle = $this->Language->Get('na');
|
| 2549 | } else {
|
| 2550 | $_oldNotificationPriorityTitle = $_oldPriorityTitle;
|
| 2551 | }
|
| 2552 |
|
| 2553 | $_newNotificationPriorityTitle = $_newPriorityTitle;
|
| 2554 |
|
| 2555 | $_oldUserNotificationPriorityTitle = $_oldNotificationPriorityTitle;
|
| 2556 | $_newUserNotificationPriorityTitle = $_newNotificationPriorityTitle;
|
| 2557 |
|
| 2558 | if ($_ticketPriorityCache[$this->GetProperty('priorityid')]['type'] == SWIFT_PRIVATE) {
|
| 2559 | $_oldUserNotificationPriorityTitle = $this->Language->Get('private');
|
| 2560 | }
|
| 2561 |
|
| 2562 | if ($_ticketPriorityCache[$_ticketPriorityID]['type'] == SWIFT_PRIVATE) {
|
| 2563 | $_newUserNotificationPriorityTitle = $this->Language->Get('private');
|
| 2564 | }
|
| 2565 |
|
| 2566 | $this->Notification->Update($this->Language->Get('notification_priority'), $_oldNotificationPriorityTitle, $_newNotificationPriorityTitle, $_oldUserNotificationPriorityTitle, $_newUserNotificationPriorityTitle);
|
| 2567 |
|
| 2568 | $this->UpdatePool('priorityid', intval($_ticketPriorityID));
|
| 2569 | $this->UpdatePool('prioritytitle', $_newPriorityTitle);
|
| 2570 |
|
| 2571 | // SWIFT_TicketManager::Recount($this->GetProperty('departmentid'));
|
| 2572 | SWIFT_TicketManager::Recount(false);
|
| 2573 |
|
| 2574 | $this->QueueSLAOverdue();
|
| 2575 |
|
| 2576 | // Load and Process Workflow Rules
|
| 2577 | self::AddToWorkflowQueue($this);
|
| 2578 |
|
| 2579 | return true;
|
| 2580 | }
|
| 2581 |
|
| 2582 | /**
|
| 2583 | * Set the Ticket Owner
|
| 2584 | *
|
| 2585 | * @author Varun Shoor
|
| 2586 | * @param int $_staffID The Owner Staff ID
|
| 2587 | * @return bool "true" on Success, "false" otherwise
|
| 2588 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 2589 | */
|
| 2590 | public function SetOwner($_staffID) {
|
| 2591 | $_SWIFT = SWIFT::GetInstance();
|
| 2592 |
|
| 2593 | if (!$this->GetIsClassLoaded()) {
|
| 2594 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2595 |
|
| 2596 | return false;
|
| 2597 | }
|
| 2598 |
|
| 2599 | $_staffCache = $this->Cache->Get('staffcache');
|
| 2600 | if ($_staffID != 0 && !isset($_staffCache[$_staffID])) {
|
| 2601 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2602 | }
|
| 2603 |
|
| 2604 | // If the current owner matches the one provided then bail out
|
| 2605 | if ($this->GetProperty('ownerstaffid') == $_staffID) {
|
| 2606 | return true;
|
| 2607 | }
|
| 2608 |
|
| 2609 | // Create Audit Log
|
| 2610 | $_oldOwnerTitle = $_newOwnerTitle = '';
|
| 2611 | if (isset($_staffCache[$this->GetProperty('ownerstaffid')])) {
|
| 2612 | $_oldOwnerTitle = $_staffCache[$this->GetProperty('ownerstaffid')]['fullname'];
|
| 2613 | }
|
| 2614 |
|
| 2615 | if ($this->GetProperty('ownerstaffid') == '0') {
|
| 2616 | $_oldOwnerTitle = $this->Language->Get('unassigned');
|
| 2617 | }
|
| 2618 |
|
| 2619 | if ($_staffID == '0') {
|
| 2620 | $_newOwnerTitle = $this->Language->Get('unassigned');
|
| 2621 | } else {
|
| 2622 | $_newOwnerTitle = $_staffCache[$_staffID]['fullname'];
|
| 2623 | }
|
| 2624 |
|
| 2625 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATEOWNER,
|
| 2626 | sprintf($_SWIFT->Language->Get('al_owner'), $_oldOwnerTitle, $_newOwnerTitle),
|
| 2627 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('ownerstaffid'), '', $_staffID, '');
|
| 2628 |
|
| 2629 | // Notification Event
|
| 2630 | $this->NotificationManager->SetEvent('ticketassigned');
|
| 2631 |
|
| 2632 | // Notification Rule
|
| 2633 | $this->NotificationManager->Changed(SWIFT_NotificationRule::CRITERIA_OWNER, $this->GetProperty('ownerstaffid'), $_staffID);
|
| 2634 |
|
| 2635 | // Notification Update
|
| 2636 | $_oldNotificationOwnerTitle = $_newNotificationOwnerTitle = '';
|
| 2637 | if ($_oldOwnerTitle == '') {
|
| 2638 | $_oldNotificationOwnerTitle = $this->Language->Get('na');
|
| 2639 | } else {
|
| 2640 | $_oldNotificationOwnerTitle = $_oldOwnerTitle;
|
| 2641 | }
|
| 2642 |
|
| 2643 | $_newNotificationOwnerTitle = $_newOwnerTitle;
|
| 2644 |
|
| 2645 | $this->Notification->Update($this->Language->Get('notification_staff'), $_oldNotificationOwnerTitle, $_newNotificationOwnerTitle);
|
| 2646 |
|
| 2647 |
|
| 2648 | $this->UpdatePool('ownerstaffid', intval($_staffID));
|
| 2649 |
|
| 2650 | $_staffName = '';
|
| 2651 | if (isset($_staffCache[$_staffID])) {
|
| 2652 | $_staffName = $_staffCache[$_staffID]['fullname'];
|
| 2653 | }
|
| 2654 |
|
| 2655 | $this->UpdatePool('ownerstaffname', $_staffName);
|
| 2656 |
|
| 2657 | // How many owners did it take to resolve this ticket?
|
| 2658 | $this->UpdatePool('resolutionlevel', intval($this->GetProperty('resolutionlevel'))+1);
|
| 2659 |
|
| 2660 | // SWIFT_TicketManager::Recount($this->GetProperty('departmentid'));
|
| 2661 | SWIFT_TicketManager::Recount(false);
|
| 2662 |
|
| 2663 | $this->QueueSLAOverdue();
|
| 2664 |
|
| 2665 | // Load the last notification message for ticket assigned alert
|
| 2666 | $this->LoadLastPostNotificationMessage();
|
| 2667 |
|
| 2668 | // Load and Process Workflow Rules
|
| 2669 | self::AddToWorkflowQueue($this);
|
| 2670 |
|
| 2671 | return true;
|
| 2672 | }
|
| 2673 |
|
| 2674 | /**
|
| 2675 | * Set the Due Time
|
| 2676 | *
|
| 2677 | * @author Varun Shoor
|
| 2678 | * @param string $_dueDateline The Due Dateline
|
| 2679 | * @return bool "true" on Success, "false" otherwise
|
| 2680 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2681 | */
|
| 2682 | public function SetDue($_dueDateline) {
|
| 2683 | $_SWIFT = SWIFT::GetInstance();
|
| 2684 |
|
| 2685 | if (!$this->GetIsClassLoaded()) {
|
| 2686 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2687 |
|
| 2688 | return false;
|
| 2689 | } else if (empty($_dueDateline)) {
|
| 2690 | return false;
|
| 2691 | }
|
| 2692 |
|
| 2693 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 2694 | sprintf($_SWIFT->Language->Get('al_due'), SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_dueDateline)),
|
| 2695 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('duetime'), '', $_dueDateline, '');
|
| 2696 |
|
| 2697 | // Notification Update
|
| 2698 | $_oldNotificationDueTitle = $_newNotificationDueTitle = '';
|
| 2699 | if ($this->GetProperty('duetime') == '0') {
|
| 2700 | $_oldNotificationDueTitle = $this->Language->Get('na');
|
| 2701 | } else {
|
| 2702 | $_oldNotificationDueTitle = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $this->GetProperty('duetime'));
|
| 2703 | }
|
| 2704 |
|
| 2705 | $_newNotificationDueTitle = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_dueDateline);
|
| 2706 |
|
| 2707 | $this->Notification->Update($this->Language->Get('notification_due'), $_oldNotificationDueTitle, $_newNotificationDueTitle);
|
| 2708 |
|
| 2709 | // Prevent calculation of SLA due time on this ticket
|
| 2710 | $this->_noSLACalculation = true;
|
| 2711 |
|
| 2712 | $this->UpdatePool('duetime', intval($_dueDateline));
|
| 2713 |
|
| 2714 | return true;
|
| 2715 | }
|
| 2716 |
|
| 2717 | /**
|
| 2718 | * Set the Resolution Due Time
|
| 2719 | *
|
| 2720 | * @author Varun Shoor
|
| 2721 | * @param string $_dueDateline The Due Dateline
|
| 2722 | * @return bool "true" on Success, "false" otherwise
|
| 2723 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2724 | */
|
| 2725 | public function SetResolutionDue($_dueDateline) {
|
| 2726 | $_SWIFT = SWIFT::GetInstance();
|
| 2727 |
|
| 2728 | if (!$this->GetIsClassLoaded()) {
|
| 2729 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2730 |
|
| 2731 | return false;
|
| 2732 | } else if (empty($_dueDateline)) {
|
| 2733 | return false;
|
| 2734 | }
|
| 2735 |
|
| 2736 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_UPDATETICKET,
|
| 2737 | sprintf($_SWIFT->Language->Get('al_resolutiondue'), SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_dueDateline)),
|
| 2738 | SWIFT_TicketAuditLog::VALUE_NONE, $this->GetProperty('duetime'), '', $_dueDateline, '');
|
| 2739 |
|
| 2740 | // Notification Update
|
| 2741 | $_oldNotificationDueTitle = $_newNotificationDueTitle = '';
|
| 2742 | if ($this->GetProperty('resolutionduedateline') == '0') {
|
| 2743 | $_oldNotificationDueTitle = $this->Language->Get('na');
|
| 2744 | } else {
|
| 2745 | $_oldNotificationDueTitle = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $this->GetProperty('resolutionduedateline'));
|
| 2746 | }
|
| 2747 |
|
| 2748 | $_newNotificationDueTitle = SWIFT_Date::Get(SWIFT_Date::TYPE_DATETIME, $_dueDateline);
|
| 2749 |
|
| 2750 | $this->Notification->Update($this->Language->Get('notification_resolutiondue'), $_oldNotificationDueTitle, $_newNotificationDueTitle);
|
| 2751 |
|
| 2752 | // Prevent calculation of SLA due time on this ticket
|
| 2753 | $this->_noSLACalculation = true;
|
| 2754 |
|
| 2755 | $this->UpdatePool('resolutionduedateline', intval($_dueDateline));
|
| 2756 |
|
| 2757 | return true;
|
| 2758 | }
|
| 2759 |
|
| 2760 | /**
|
| 2761 | * Retrieve the linked tickets in the active chain
|
| 2762 | *
|
| 2763 | * @author Varun Shoor
|
| 2764 | * @return array The Linked Ticket Container
|
| 2765 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2766 | */
|
| 2767 | public function GetLinks() {
|
| 2768 | if (!$this->GetIsClassLoaded()) {
|
| 2769 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2770 |
|
| 2771 | return false;
|
| 2772 | }
|
| 2773 |
|
| 2774 | if ($this->GetProperty('islinked') == '0') {
|
| 2775 | return array();
|
| 2776 | }
|
| 2777 |
|
| 2778 | // First get all the chain hashes where this ticket is part of
|
| 2779 | $_chainHashList = array();
|
| 2780 | $this->Database->Query("SELECT chainhash FROM " . TABLE_PREFIX . "ticketlinkchains WHERE ticketid = '" . intval($this->GetTicketID()) .
|
| 2781 | "'");
|
| 2782 | while ($this->Database->NextRecord()) {
|
| 2783 | $_chainHashList[] = $this->Database->Record['chainhash'];
|
| 2784 | }
|
| 2785 |
|
| 2786 | if (!count($_chainHashList)) {
|
| 2787 | return array();
|
| 2788 | }
|
| 2789 |
|
| 2790 | // Now get all the tickets that are part of the chain hashes
|
| 2791 | $_ticketLinkContainer = array();
|
| 2792 | $this->Database->Query("SELECT tickets.*, ticketlinkchains.ticketlinktypeid FROM " . TABLE_PREFIX . "ticketlinkchains AS ticketlinkchains
|
| 2793 | LEFT JOIN " . TABLE_PREFIX . "tickets AS tickets ON (ticketlinkchains.ticketid = tickets.ticketid) WHERE
|
| 2794 | chainhash IN (" . BuildIN($_chainHashList) . ")");
|
| 2795 | while ($this->Database->NextRecord()) {
|
| 2796 | if ($this->Database->Record['ticketid'] == $this->GetTicketID()) {
|
| 2797 | continue;
|
| 2798 | }
|
| 2799 |
|
| 2800 | $_ticketLinkContainer[$this->Database->Record['ticketlinktypeid']][$this->Database->Record['ticketid']] =
|
| 2801 | new SWIFT_Ticket(new SWIFT_DataStore($this->Database->Record));
|
| 2802 | }
|
| 2803 |
|
| 2804 | return $_ticketLinkContainer;
|
| 2805 | }
|
| 2806 |
|
| 2807 | /**
|
| 2808 | * Mark ticket as linked
|
| 2809 | *
|
| 2810 | * @author Varun Shoor
|
| 2811 | * @return bool "true" on Success, "false" otherwise
|
| 2812 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2813 | */
|
| 2814 | public function MarkAsLinked() {
|
| 2815 | if (!$this->GetIsClassLoaded()) {
|
| 2816 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2817 |
|
| 2818 | return false;
|
| 2819 | }
|
| 2820 |
|
| 2821 | $this->UpdatePool('islinked', '1');
|
| 2822 |
|
| 2823 | return true;
|
| 2824 | }
|
| 2825 |
|
| 2826 | /**
|
| 2827 | * Mark ticket as unlinked
|
| 2828 | *
|
| 2829 | * @author Varun Shoor
|
| 2830 | * @return bool "true" on Success, "false" otherwise
|
| 2831 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2832 | */
|
| 2833 | public function MarkAsUnlinked() {
|
| 2834 | if (!$this->GetIsClassLoaded()) {
|
| 2835 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2836 |
|
| 2837 | return false;
|
| 2838 | }
|
| 2839 |
|
| 2840 | $this->UpdatePool('islinked', '0');
|
| 2841 |
|
| 2842 | return true;
|
| 2843 | }
|
| 2844 |
|
| 2845 | /**
|
| 2846 | * Lock a Ticket
|
| 2847 | *
|
| 2848 | * @author Varun Shoor
|
| 2849 | * @param SWIFT_Staff $_SWIFT_StaffObject The SWIFT_Staff Object Pointer
|
| 2850 | * @return bool "true" on Success, "false" otherwise
|
| 2851 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 2852 | */
|
| 2853 | public function Lock(SWIFT_Staff $_SWIFT_StaffObject) {
|
| 2854 | if (!$this->GetIsClassLoaded()) {
|
| 2855 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2856 |
|
| 2857 | return false;
|
| 2858 | } else if (!$_SWIFT_StaffObject instanceof SWIFT_Staff || !$_SWIFT_StaffObject->GetIsClassLoaded()) {
|
| 2859 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 2860 | }
|
| 2861 |
|
| 2862 | SWIFT_TicketLock::Create($this, $_SWIFT_StaffObject);
|
| 2863 |
|
| 2864 | return true;
|
| 2865 | }
|
| 2866 |
|
| 2867 | /**
|
| 2868 | * Unlock the ticket completely
|
| 2869 | *
|
| 2870 | * @author Varun Shoor
|
| 2871 | * @return bool "true" on Success, "false" otherwise
|
| 2872 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2873 | */
|
| 2874 | public function Unlock() {
|
| 2875 | if (!$this->GetIsClassLoaded()) {
|
| 2876 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2877 |
|
| 2878 | return false;
|
| 2879 | }
|
| 2880 |
|
| 2881 | SWIFT_TicketLock::DeleteOnTicket(array($this->GetTicketID()));
|
| 2882 |
|
| 2883 | return true;
|
| 2884 | }
|
| 2885 |
|
| 2886 | /**
|
| 2887 | * Rebuild the Ticket Properties (hasnotes, hasattachments etc.)
|
| 2888 | *
|
| 2889 | * @author Varun Shoor
|
| 2890 | * @return bool "true" on Success, "false" otherwise
|
| 2891 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 2892 | */
|
| 2893 | public function RebuildProperties() {
|
| 2894 | if (!$this->GetIsClassLoaded()) {
|
| 2895 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 2896 |
|
| 2897 | return false;
|
| 2898 | }
|
| 2899 |
|
| 2900 | $_ticketStatusCache = $this->Cache->Get('statuscache');
|
| 2901 |
|
| 2902 | /**
|
| 2903 | * BUG FIX - Parminder Singh
|
| 2904 | *
|
| 2905 | * SWIFT-1894: 'Trash' count does not clear the ticket count in case a department is deleted
|
| 2906 | *
|
| 2907 | */
|
| 2908 |
|
| 2909 | $_departmentCache = $this->Cache->Get('departmentcache');
|
| 2910 |
|
| 2911 | if ($this->GetProperty('trasholddepartmentid') != '0' && !isset($_departmentCache[$this->GetProperty('trasholddepartmentid')])) {
|
| 2912 | $this->UpdatePool('trasholddepartmentid', '0');
|
| 2913 | }
|
| 2914 |
|
| 2915 | // First Post, Last Post & Total Replies
|
| 2916 | $_ticketPostIDContainer = $this->Database->QueryFetch("SELECT MIN(ticketpostid) AS firstpostid, MAX(ticketpostid) AS lastpostid,
|
| 2917 | COUNT(*) AS totalreplies FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 2918 | if (isset($_ticketPostIDContainer['firstpostid']) && !empty($_ticketPostIDContainer['firstpostid']))
|
| 2919 | {
|
| 2920 | $this->UpdatePool('firstpostid', intval($_ticketPostIDContainer['firstpostid']));
|
| 2921 | }
|
| 2922 |
|
| 2923 | if (isset($_ticketPostIDContainer['lastpostid']) && !empty($_ticketPostIDContainer['lastpostid']))
|
| 2924 | {
|
| 2925 | $this->UpdatePool('lastpostid', intval($_ticketPostIDContainer['lastpostid']));
|
| 2926 |
|
| 2927 | $_lastTicketPostContainer = $this->Database->QueryFetch("SELECT fullname, dateline FROM " . TABLE_PREFIX . "ticketposts WHERE
|
| 2928 | ticketpostid = '" . intval($_ticketPostIDContainer['lastpostid']) . "'");
|
| 2929 |
|
| 2930 | if (isset($_lastTicketPostContainer['fullname']) && !empty($_lastTicketPostContainer['fullname']))
|
| 2931 | {
|
| 2932 | $this->UpdatePool('lastreplier', $_lastTicketPostContainer['fullname']);
|
| 2933 | }
|
| 2934 |
|
| 2935 | if (isset($_lastTicketPostContainer['dateline']) && $_lastTicketPostContainer['dateline'] > $this->GetProperty('lastactivity'))
|
| 2936 | {
|
| 2937 | $this->UpdatePool('lastactivity', intval($_lastTicketPostContainer['dateline']));
|
| 2938 | }
|
| 2939 | }
|
| 2940 |
|
| 2941 | if (isset($_ticketPostIDContainer['totalreplies']))
|
| 2942 | {
|
| 2943 | // We deduct by 1 to ignore the original ticket post as a reply
|
| 2944 | if ($_ticketPostIDContainer['totalreplies'] > 0)
|
| 2945 | {
|
| 2946 | $_ticketPostIDContainer['totalreplies']--;
|
| 2947 | }
|
| 2948 |
|
| 2949 | $this->UpdatePool('totalreplies', intval($_ticketPostIDContainer['totalreplies']));
|
| 2950 | }
|
| 2951 |
|
| 2952 | // Has Notes?
|
| 2953 | $_hasNotesContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalnotes FROM " . TABLE_PREFIX . "ticketnotes WHERE
|
| 2954 | linktypeid = '" . intval($this->GetTicketID()) . "' AND linktype = '" . SWIFT_TicketNoteManager::LINKTYPE_TICKET . "'");
|
| 2955 |
|
| 2956 | $this->UpdatePool('hasnotes', IIF($_hasNotesContainer['totalnotes'] > 0, '1', '0'));
|
| 2957 |
|
| 2958 | // Has Attachments?
|
| 2959 | $_hasAttachmentsContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalattachments FROM " . TABLE_PREFIX . "attachments WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 2960 |
|
| 2961 | $this->UpdatePool('hasattachments', IIF($_hasAttachmentsContainer['totalattachments'] > 0, '1', '0'));
|
| 2962 |
|
| 2963 | /**
|
| 2964 | * BUG FIX - Saloni Dhall
|
| 2965 | *
|
| 2966 | * SWIFT-2576: 'hasattachments' field is not getting saved if ticket is having attachments
|
| 2967 | *
|
| 2968 | */
|
| 2969 | $_storeTicketIDList = $this->GetTicketPostIDList();
|
| 2970 | if (is_array($_storeTicketIDList) && !empty($_storeTicketIDList)) {
|
| 2971 | foreach ($_storeTicketIDList as $_ticketPostID)
|
| 2972 | {
|
| 2973 | $_hasAttachmentsContainer = $this->Database->QueryFetch("SELECT COUNT(*) as attachmentcount FROM " . TABLE_PREFIX . "attachments WHERE linktypeid = '" . $_ticketPostID . "'");
|
| 2974 | $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($_ticketPostID));
|
| 2975 | $_SWIFT_TicketPostObject->UpdatePool('hasattachments', IIF($_hasAttachmentsContainer['attachmentcount'] > 0, '1', '0'));
|
| 2976 | }
|
| 2977 | }
|
| 2978 |
|
| 2979 | // Has Draft?
|
| 2980 | $_hasDraftContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "ticketdrafts WHERE
|
| 2981 | ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 2982 |
|
| 2983 | $this->UpdatePool('hasdraft', IIF($_hasDraftContainer['totalitems'] > 0, '1', '0'));
|
| 2984 |
|
| 2985 | // Has Billing Entries?
|
| 2986 | $_hasBillingContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickettimetracks WHERE
|
| 2987 | ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 2988 |
|
| 2989 | $this->UpdatePool('hasbilling', IIF($_hasBillingContainer['totalitems'] > 0, '1', '0'));
|
| 2990 |
|
| 2991 | // Has Follow-Up's?
|
| 2992 | $_hasFollowUpContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "ticketfollowups WHERE
|
| 2993 | ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 2994 |
|
| 2995 | $this->UpdatePool('hasfollowup', IIF($_hasFollowUpContainer['totalitems'] > 0, '1', '0'));
|
| 2996 | $this->UpdatePool('followupcount', intval($_hasFollowUpContainer['totalitems']));
|
| 2997 |
|
| 2998 | // Update time worked + time billed
|
| 2999 | $_ticketTimeWorked = $_ticketTimeBillable = 0;
|
| 3000 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickettimetracks WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 3001 | while ($this->Database->NextRecord())
|
| 3002 | {
|
| 3003 | $_ticketTimeWorked += intval($this->Database->Record['timespent']);
|
| 3004 | $_ticketTimeBillable += intval($this->Database->Record['timebillable']);
|
| 3005 | }
|
| 3006 |
|
| 3007 | $this->UpdateTimeTrack($_ticketTimeWorked, $_ticketTimeBillable);
|
| 3008 |
|
| 3009 | // Is Resolved
|
| 3010 | if (isset($_ticketStatusCache[$this->GetProperty('ticketstatusid')])) {
|
| 3011 | if ($_ticketStatusCache[$this->GetProperty('ticketstatusid')]['markasresolved'] == '1')
|
| 3012 | {
|
| 3013 | $this->UpdatePool('isresolved', '1');
|
| 3014 | $this->UpdatePool('repliestoresolution', $this->GetProperty('totalreplies'));
|
| 3015 | } else {
|
| 3016 | $this->UpdatePool('isresolved', '0');
|
| 3017 | }
|
| 3018 | }
|
| 3019 |
|
| 3020 | // Rebuild the titles & names
|
| 3021 | $this->RebuildTitles();
|
| 3022 |
|
| 3023 | // Calculate the additional properties
|
| 3024 | $this->CalculateProperties();
|
| 3025 |
|
| 3026 | // Load and Process Workflow Rules
|
| 3027 | self::AddToWorkflowQueue($this);
|
| 3028 |
|
| 3029 | return true;
|
| 3030 | }
|
| 3031 |
|
| 3032 | /**
|
| 3033 | * Rebuilds the titles associated with the ticket
|
| 3034 | *
|
| 3035 | * @author Varun Shoor
|
| 3036 | * @return bool "true" on Success, "false" otherwise
|
| 3037 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 3038 | */
|
| 3039 | protected function RebuildTitles()
|
| 3040 | {
|
| 3041 | if (!$this->GetIsClassLoaded()) {
|
| 3042 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 3043 |
|
| 3044 | return false;
|
| 3045 | }
|
| 3046 |
|
| 3047 | $_departmentCache = $this->Cache->Get('departmentcache');
|
| 3048 | $_staffCache = $this->Cache->Get('staffcache');
|
| 3049 | $_ticketStatusCache = $this->Cache->Get('statuscache');
|
| 3050 | $_ticketPriorityCache = $this->Cache->Get('prioritycache');
|
| 3051 | $_ticketTypeCache = $this->Cache->Get('tickettypecache');
|
| 3052 | $_slaPlanCache = $this->Cache->Get('slaplancache');
|
| 3053 | $_escalationRuleCache = $this->Cache->Get('escalationrulecache');
|
| 3054 |
|
| 3055 | // Build local properties
|
| 3056 | if (isset($_departmentCache[$this->GetProperty('departmentid')])) {
|
| 3057 | $this->UpdatePool('departmenttitle', $_departmentCache[$this->GetProperty('departmentid')]['title']);
|
| 3058 | }
|
| 3059 |
|
| 3060 | if (isset($_staffCache[$this->GetProperty('ownerstaffid')])) {
|
| 3061 | $this->UpdatePool('ownerstaffname', $_staffCache[$this->GetProperty('ownerstaffid')]['fullname']);
|
| 3062 | }
|
| 3063 |
|
| 3064 | if (isset($_ticketStatusCache[$this->GetProperty('ticketstatusid')])) {
|
| 3065 | $this->UpdatePool('ticketstatustitle', $_ticketStatusCache[$this->GetProperty('ticketstatusid')]['title']);
|
| 3066 | }
|
| 3067 |
|
| 3068 | if (isset($_ticketPriorityCache[$this->GetProperty('priorityid')])) {
|
| 3069 | $this->UpdatePool('prioritytitle', $_ticketPriorityCache[$this->GetProperty('priorityid')]['title']);
|
| 3070 | }
|
| 3071 |
|
| 3072 | if (isset($_ticketTypeCache[$this->GetProperty('tickettypeid')])) {
|
| 3073 | $this->UpdatePool('tickettypetitle', $_ticketTypeCache[$this->GetProperty('tickettypeid')]['title']);
|
| 3074 | }
|
| 3075 |
|
| 3076 | // Ticket Drafts
|
| 3077 | $_ticketDraftUpdateContainer = array();
|
| 3078 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "ticketdrafts WHERE ticketid = '" . $this->GetTicketID() . "'");
|
| 3079 | while ($this->Database->NextRecord()) {
|
| 3080 | $_ticketDraftUpdateContainer[$this->Database->Record['ticketdraftid']] = $this->Database->Record;
|
| 3081 |
|
| 3082 | if (isset($_staffCache[$this->Database->Record['staffid']])) {
|
| 3083 | $_ticketDraftUpdateContainer[$this->Database->Record['staffname']] = $_staffCache[$this->Database->Record['staffid']]['fullname'];
|
| 3084 | }
|
| 3085 |
|
| 3086 | if (isset($_staffCache[$this->Database->Record['editedbystaffid']])) {
|
| 3087 | $_ticketDraftUpdateContainer[$this->Database->Record['editedstaffname']] = $_staffCache[$this->Database->Record['editedbystaffid']]['fullname'];
|
| 3088 | }
|
| 3089 | }
|
| 3090 |
|
| 3091 | foreach ($_ticketDraftUpdateContainer as $_ticketDraftID => $_ticketDraft) {
|
| 3092 | SWIFT_TicketDraft::UpdateStaffName($_ticketDraftID, $_ticketDraft['staffname'], $_ticketDraft['editedstaffname']);
|
| 3093 | }
|
| 3094 | unset($_ticketDraftUpdateContainer);
|
| 3095 |
|
| 3096 | // Ticket Audit Logs
|
| 3097 | $_ticketAuditLogUpdateContainer = array();
|
| 3098 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "ticketauditlogs WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 3099 | while ($this->Database->NextRecord()) {
|
| 3100 | $_ticketAuditLogUpdateContainer[$this->Database->Record['ticketauditlogid']] = $this->Database->Record;
|
| 3101 |
|
| 3102 | if (isset($_departmentCache[$this->Database->Record['departmentid']])) {
|
| 3103 | $_ticketAuditLogUpdateContainer[$this->Database->Record['ticketauditlogid']]['departmenttitle'] = $_departmentCache[$this->Database->Record['departmentid']]['title'];
|
| 3104 | }
|
| 3105 |
|
| 3106 | if ($this->Database->Record['creatortype'] == SWIFT_TicketAuditLog::CREATOR_STAFF && isset($_staffCache[$this->Database->Record['creatorid']])) {
|
| 3107 | $_ticketAuditLogUpdateContainer[$this->Database->Record['ticketauditlogid']]['creatorfullname'] = $_staffCache[$this->Database->Record['creatorid']]['fullname'];
|
| 3108 | }
|
| 3109 | }
|
| 3110 |
|
| 3111 | foreach ($_ticketAuditLogUpdateContainer as $_ticketAuditLogID => $_ticketAuditLog) {
|
| 3112 | SWIFT_TicketAuditLog::UpdateProperties($_ticketAuditLogID, $_ticketAuditLog['departmenttitle'], $_ticketAuditLog['creatorfullname']);
|
| 3113 | }
|
| 3114 | unset($_ticketAuditLogUpdateContainer);
|
| 3115 |
|
| 3116 | // Ticket Notes
|
| 3117 | $_ticketNoteUpdateContainer = array();
|
| 3118 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "ticketnotes
|
| 3119 | WHERE linktype = '" . SWIFT_TicketNote::LINKTYPE_TICKET . "' AND linktypeid = '" . intval($this->GetTicketID()) . "'");
|
| 3120 | while ($this->Database->NextRecord()) {
|
| 3121 | $_ticketNoteUpdateContainer[$this->Database->Record['ticketnoteid']] = $this->Database->Record;
|
| 3122 |
|
| 3123 | if (isset($_staffCache[$this->Database->Record['staffid']])) {
|
| 3124 | $_ticketNoteUpdateContainer[$this->Database->Record['ticketnoteid']]['staffname'] = $_staffCache[$this->Database->Record['staffid']]['fullname'];
|
| 3125 | }
|
| 3126 |
|
| 3127 | if (isset($_staffCache[$this->Database->Record['editedstaffid']])) {
|
| 3128 | $_ticketNoteUpdateContainer[$this->Database->Record['ticketnoteid']]['editedstaffname'] = $_staffCache[$this->Database->Record['editedstaffid']]['fullname'];
|
| 3129 | }
|
| 3130 | }
|
| 3131 |
|
| 3132 | foreach ($_ticketNoteUpdateContainer as $_ticketNoteID => $_ticketNote) {
|
| 3133 | SWIFT_TicketNoteManager::UpdateProperties($_ticketNoteID, $_ticketNote['staffname'], $_ticketNote['editedstaffname']);
|
| 3134 | }
|
| 3135 |
|
| 3136 | unset($_ticketNoteUpdateContainer);
|
| 3137 |
|
| 3138 | // Ticket Time Tracks
|
| 3139 | $_ticketTimeTrackUpdateContainer = array();
|
| 3140 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickettimetracks WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 3141 | while ($this->Database->NextRecord()) {
|
| 3142 | $_ticketTimeTrackUpdateContainer[$this->Database->Record['tickettimetrackid']] = $this->Database->Record;
|
| 3143 |
|
| 3144 | if (isset($_staffCache[$this->Database->Record['creatorstaffid']])) {
|
| 3145 | $_ticketTimeTrackUpdateContainer[$this->Database->Record['tickettimetrackid']]['creatorstaffname'] = $_staffCache[$this->Database->Record['creatorstaffid']]['fullname'];
|
| 3146 | }
|
| 3147 |
|
| 3148 | if (isset($_staffCache[$this->Database->Record['editedstaffid']])) {
|
| 3149 | $_ticketTimeTrackUpdateContainer[$this->Database->Record['tickettimetrackid']]['editedstaffname'] = $_staffCache[$this->Database->Record['editedstaffid']]['fullname'];
|
| 3150 | }
|
| 3151 |
|
| 3152 | if (isset($_staffCache[$this->Database->Record['workerstaffid']])) {
|
| 3153 | $_ticketTimeTrackUpdateContainer[$this->Database->Record['tickettimetrackid']]['workerstaffname'] = $_staffCache[$this->Database->Record['workerstaffid']]['fullname'];
|
| 3154 | }
|
| 3155 | }
|
| 3156 |
|
| 3157 | foreach ($_ticketTimeTrackUpdateContainer as $_ticketTimeTrackID => $_ticketTimeTrack) {
|
| 3158 | SWIFT_TicketTimeTrack::UpdateProperties($_ticketTimeTrackID, $_ticketTimeTrack['creatorstaffname'], $_ticketTimeTrack['editedstaffname'], $_ticketTimeTrack['workerstaffname']);
|
| 3159 | }
|
| 3160 | unset($_ticketTimeTrackUpdateContainer);
|
| 3161 |
|
| 3162 | // Escalation Paths
|
| 3163 | $_escalationPathUpdateContainer = array();
|
| 3164 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "escalationpaths WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 3165 | while ($this->Database->NextRecord()) {
|
| 3166 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']] = $this->Database->Record;
|
| 3167 |
|
| 3168 | if (isset($_slaPlanCache[$this->Database->Record['slaplanid']])) {
|
| 3169 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['slaplantitle'] = $_slaPlanCache[$this->Database->Record['slaplanid']]['title'];
|
| 3170 | }
|
| 3171 |
|
| 3172 | if (isset($_escalationRuleCache[$this->Database->Record['escalationruleid']])) {
|
| 3173 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['escalationruletitle'] = $_escalationRuleCache[$this->Database->Record['escalationruleid']]['title'];
|
| 3174 | }
|
| 3175 |
|
| 3176 | if (isset($_staffCache[$this->Database->Record['ownerstaffid']])) {
|
| 3177 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['ownerstaffname'] = $_staffCache[$this->Database->Record['ownerstaffid']]['fullname'];
|
| 3178 | }
|
| 3179 |
|
| 3180 | if (isset($_departmentCache[$this->Database->Record['departmentid']])) {
|
| 3181 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['departmenttitle'] = $_departmentCache[$this->Database->Record['departmentid']]['title'];
|
| 3182 | }
|
| 3183 |
|
| 3184 | if (isset($_ticketStatusCache[$this->Database->Record['ticketstatusid']])) {
|
| 3185 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['ticketstatustitle'] = $_ticketStatusCache[$this->Database->Record['ticketstatusid']]['title'];
|
| 3186 | }
|
| 3187 |
|
| 3188 | if (isset($_ticketPriorityCache[$this->Database->Record['priorityid']])) {
|
| 3189 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['prioritytitle'] = $_ticketPriorityCache[$this->Database->Record['priorityid']]['title'];
|
| 3190 | }
|
| 3191 |
|
| 3192 | if (isset($_ticketTypeCache[$this->Database->Record['tickettypeid']])) {
|
| 3193 | $_escalationPathUpdateContainer[$this->Database->Record['escalationpathid']]['tickettypetitle'] = $_ticketTypeCache[$this->Database->Record['tickettypeid']]['title'];
|
| 3194 | }
|
| 3195 | }
|
| 3196 |
|
| 3197 | foreach ($_escalationPathUpdateContainer as $_escalationPathID => $_escalationPath) {
|
| 3198 | SWIFT_EscalationPath::UpdateProperties($_escalationPathID, $_escalationPath['slaplantitle'], $_escalationPath['escalationruletitle'], $_escalationPath['ownerstaffname'],
|
| 3199 | $_escalationPath['departmenttitle'], $_escalationPath['ticketstatustitle'], $_escalationPath['prioritytitle'], $_escalationPath['tickettypetitle']);
|
| 3200 | }
|
| 3201 | unset($_escalationPathUpdateContainer);
|
| 3202 |
|
| 3203 | return true;
|
| 3204 | }
|
| 3205 |
|
| 3206 | /**
|
| 3207 | * Calculate the Ticket Properties like is firstcontactresolved etc.
|
| 3208 | *
|
| 3209 | * @author Varun Shoor
|
| 3210 | * @return bool "true" on Success, "false" otherwise
|
| 3211 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 3212 | */
|
| 3213 | public function CalculateProperties() {
|
| 3214 | if (!$this->GetIsClassLoaded()) {
|
| 3215 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 3216 |
|
| 3217 | return false;
|
| 3218 | }
|
| 3219 |
|
| 3220 | $_SWIFT_TicketPostObject_Last = false;
|
| 3221 | try {
|
| 3222 | $_SWIFT_TicketPostObject_Last = new SWIFT_TicketPost(new SWIFT_DataID($this->GetProperty('lastpostid')));
|
| 3223 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 3224 | }
|
| 3225 |
|
| 3226 | // Is First Contact Resolved?
|
| 3227 | if ($this->GetProperty('totalreplies') == '1' && $_SWIFT_TicketPostObject_Last instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject_Last->GetIsClassLoaded() && $_SWIFT_TicketPostObject_Last->GetProperty('creator') == SWIFT_TicketPost::CREATOR_STAFF
|
| 3228 | && $this->GetProperty('isresolved') == '1' && $this->GetProperty('isfirstcontactresolved') == '0') {
|
| 3229 | $this->UpdatePool('isfirstcontactresolved', '1');
|
| 3230 | }
|
| 3231 |
|
| 3232 | $_lastActivity = $this->GetProperty('lastactivity');
|
| 3233 | $_lastPostActivity = $_lastActivity;
|
| 3234 | if ($_SWIFT_TicketPostObject_Last instanceof SWIFT_TicketPost && $_SWIFT_TicketPostObject_Last->GetIsClassLoaded()) {
|
| 3235 | $_lastPostActivity = $_SWIFT_TicketPostObject_Last->GetProperty('dateline');
|
| 3236 | }
|
| 3237 |
|
| 3238 | $_finalLastActivity = $_lastActivity;
|
| 3239 | if ($_lastPostActivity > $_finalLastActivity) {
|
| 3240 | $_finalLastActivity = $_lastPostActivity;
|
| 3241 | }
|
| 3242 |
|
| 3243 | if ($this->GetProperty('isresolved') == '1') {
|
| 3244 | $this->UpdatePool('resolutiondateline', $_finalLastActivity);
|
| 3245 |
|
| 3246 | // How much time did it take to resolve this ticket?
|
| 3247 | $this->UpdatePool('resolutionseconds', $_finalLastActivity-$this->GetProperty('dateline'));
|
| 3248 | } else {
|
| 3249 | $this->UpdatePool('resolutiondateline', '0');
|
| 3250 | $this->UpdatePool('resolutionseconds', '0');
|
| 3251 | }
|
| 3252 |
|
| 3253 | // Is watched?
|
| 3254 | $_ticketWatcherCountContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "ticketwatchers WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 3255 | if (isset($_ticketWatcherCountContainer['totalitems']) && $_ticketWatcherCountContainer['totalitems'] > 0) {
|
| 3256 | $this->UpdatePool('iswatched', '1');
|
| 3257 | } else {
|
| 3258 | $this->UpdatePool('iswatched', '0');
|
| 3259 | }
|
| 3260 |
|
| 3261 | // Calculate the average response time
|
| 3262 | $this->UpdatePool('averageresponsetime', '0');
|
| 3263 | $this->UpdatePool('averageresponsetimehits', '0');
|
| 3264 |
|
| 3265 | $_ticketPostContainer = array();
|
| 3266 | $_oldPostDateline = $_lastPostDateline = 0;
|
| 3267 | $this->Database->Query("SELECT ticketpostid, dateline, creator FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid = '" . intval($this->GetTicketID()) . "' ORDER BY ticketpostid ASC");
|
| 3268 | while ($this->Database->NextRecord()) {
|
| 3269 | $_ticketPostContainer[$this->Database->Record['ticketpostid']] = $this->Database->Record;
|
| 3270 | }
|
| 3271 |
|
| 3272 | $_firstResponseTime = 0;
|
| 3273 |
|
| 3274 | foreach ($_ticketPostContainer as $_ticketPostID => $_ticketPost) {
|
| 3275 | if (!empty($_lastPostDateline)) {
|
| 3276 | $_responseTime = $_ticketPost['dateline'] - $_lastPostDateline;
|
| 3277 |
|
| 3278 | $_postFirstResponseTime = 0;
|
| 3279 |
|
| 3280 | if (empty($_firstResponseTime) && $_ticketPost['creator'] == SWIFT_TicketPost::CREATOR_STAFF) {
|
| 3281 | $_firstResponseTime = $_ticketPost['dateline'] - $this->GetProperty('dateline');
|
| 3282 | $_postFirstResponseTime = $_firstResponseTime;
|
| 3283 | }
|
| 3284 |
|
| 3285 | $_updateContainer = array();
|
| 3286 | $_updateContainer['responsetime'] = $_responseTime;
|
| 3287 |
|
| 3288 | if (!empty($_postFirstResponseTime)) {
|
| 3289 | $_updateContainer['firstresponsetime'] = $_postFirstResponseTime;
|
| 3290 | }
|
| 3291 |
|
| 3292 | $this->Database->AutoExecute(TABLE_PREFIX . 'ticketposts', $_updateContainer, 'UPDATE', "ticketpostid = '" . intval($_ticketPostID) . "'");
|
| 3293 | }
|
| 3294 |
|
| 3295 | if ($_ticketPost['creator'] != SWIFT_TicketPost::CREATOR_STAFF) {
|
| 3296 | $_oldPostDateline = $_ticketPost['dateline'];
|
| 3297 | } else if (!empty($_oldPostDateline) && $_ticketPost['creator'] == SWIFT_TicketPost::CREATOR_STAFF) {
|
| 3298 | $_responseTime = $_ticketPost['dateline']-$_oldPostDateline;
|
| 3299 | $this->UpdateAverageResponseTime($_responseTime);
|
| 3300 |
|
| 3301 | $_oldPostDateline = 0;
|
| 3302 | }
|
| 3303 |
|
| 3304 | $_lastPostDateline = $_ticketPost['dateline'];
|
| 3305 | }
|
| 3306 |
|
| 3307 | if (!empty($_firstResponseTime)) {
|
| 3308 | $this->UpdatePool('firstresponsetime', intval($_firstResponseTime));
|
| 3309 | }
|
| 3310 |
|
| 3311 | return true;
|
| 3312 | }
|
| 3313 |
|
| 3314 | /**
|
| 3315 | * Change the ticket's hasattachments property to true
|
| 3316 | *
|
| 3317 | * @author Varun Shoor
|
| 3318 | * @return bool "true" on Success, "false" otherwise
|
| 3319 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3320 | */
|
| 3321 | public function MarkHasAttachments() {
|
| 3322 | if (!$this->GetIsClassLoaded()) {
|
| 3323 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3324 |
|
| 3325 | return false;
|
| 3326 | }
|
| 3327 |
|
| 3328 | $this->UpdatePool('hasattachments', '1');
|
| 3329 |
|
| 3330 | return true;
|
| 3331 | }
|
| 3332 |
|
| 3333 | /**
|
| 3334 | * Change the ticket's hasratings property to true
|
| 3335 | *
|
| 3336 | * @author Varun Shoor
|
| 3337 | * @return bool "true" on Success, "false" otherwise
|
| 3338 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3339 | */
|
| 3340 | public function MarkHasRatings() {
|
| 3341 | if (!$this->GetIsClassLoaded()) {
|
| 3342 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3343 |
|
| 3344 | return false;
|
| 3345 | }
|
| 3346 |
|
| 3347 | $this->UpdatePool('hasratings', '1');
|
| 3348 |
|
| 3349 | return true;
|
| 3350 | }
|
| 3351 |
|
| 3352 | /**
|
| 3353 | * Change the ticket's hasfollowup property to true
|
| 3354 | *
|
| 3355 | * @author Varun Shoor
|
| 3356 | * @return bool "true" on Success, "false" otherwise
|
| 3357 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3358 | */
|
| 3359 | public function MarkHasFollowUp() {
|
| 3360 | if (!$this->GetIsClassLoaded()) {
|
| 3361 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3362 |
|
| 3363 | return false;
|
| 3364 | }
|
| 3365 |
|
| 3366 | $this->UpdatePool('hasfollowup', '1');
|
| 3367 |
|
| 3368 | return true;
|
| 3369 | }
|
| 3370 |
|
| 3371 | /**
|
| 3372 | * Change the ticket's hasdraft property to true
|
| 3373 | *
|
| 3374 | * @author Varun Shoor
|
| 3375 | * @return bool "true" on Success, "false" otherwise
|
| 3376 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3377 | */
|
| 3378 | public function MarkHasDraft() {
|
| 3379 | if (!$this->GetIsClassLoaded()) {
|
| 3380 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3381 |
|
| 3382 | return false;
|
| 3383 | }
|
| 3384 |
|
| 3385 | $this->UpdatePool('hasdraft', '1');
|
| 3386 |
|
| 3387 | return true;
|
| 3388 | }
|
| 3389 |
|
| 3390 | /**
|
| 3391 | * Change the ticket's hasdraft property to false
|
| 3392 | *
|
| 3393 | * @author Varun Shoor
|
| 3394 | * @return bool "true" on Success, "false" otherwise
|
| 3395 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3396 | */
|
| 3397 | public function ClearHasDraft() {
|
| 3398 | if (!$this->GetIsClassLoaded()) {
|
| 3399 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3400 |
|
| 3401 | return false;
|
| 3402 | }
|
| 3403 |
|
| 3404 | $this->UpdatePool('hasdraft', '0');
|
| 3405 |
|
| 3406 | return true;
|
| 3407 | }
|
| 3408 |
|
| 3409 | /**
|
| 3410 | * Change the ticket's hasnotes property to true
|
| 3411 | *
|
| 3412 | * @author Varun Shoor
|
| 3413 | * @return bool "true" on Success, "false" otherwise
|
| 3414 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3415 | */
|
| 3416 | public function MarkHasNotes() {
|
| 3417 | if (!$this->GetIsClassLoaded()) {
|
| 3418 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3419 |
|
| 3420 | return false;
|
| 3421 | }
|
| 3422 |
|
| 3423 | $this->UpdatePool('hasnotes', '1');
|
| 3424 |
|
| 3425 | return true;
|
| 3426 | }
|
| 3427 |
|
| 3428 | /**
|
| 3429 | * Change the ticket's hasbilling property to true
|
| 3430 | *
|
| 3431 | * @author Varun Shoor
|
| 3432 | * @return bool "true" on Success, "false" otherwise
|
| 3433 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3434 | */
|
| 3435 | public function MarkHasBilling() {
|
| 3436 | if (!$this->GetIsClassLoaded()) {
|
| 3437 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3438 |
|
| 3439 | return false;
|
| 3440 | }
|
| 3441 |
|
| 3442 | $this->UpdatePool('hasbilling', '1');
|
| 3443 |
|
| 3444 | return true;
|
| 3445 | }
|
| 3446 |
|
| 3447 | /**
|
| 3448 | * Update the time tracking information
|
| 3449 | *
|
| 3450 | * @author Varun Shoor
|
| 3451 | * @param int $_timeSpent The Time Spent
|
| 3452 | * @param int $_timeBilled The Time Billed
|
| 3453 | * @return bool "true" on Success, "false" otherwise
|
| 3454 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 3455 | */
|
| 3456 | public function UpdateTimeTrack($_timeSpent, $_timeBilled)
|
| 3457 | {
|
| 3458 | if (!$this->GetIsClassLoaded())
|
| 3459 | {
|
| 3460 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 3461 |
|
| 3462 | return false;
|
| 3463 | }
|
| 3464 |
|
| 3465 | $this->UpdatePool('timeworked', intval($_timeSpent));
|
| 3466 | $this->UpdatePool('timebilled', intval($_timeBilled));
|
| 3467 |
|
| 3468 | return true;
|
| 3469 | }
|
| 3470 |
|
| 3471 | /**
|
| 3472 | * Set the Message ID for this Ticket
|
| 3473 | *
|
| 3474 | * @author Varun Shoor
|
| 3475 | * @param string $_messageID The Message ID
|
| 3476 | * @return bool "true" on Success, "false" otherwise
|
| 3477 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 3478 | */
|
| 3479 | public function SetMessageID($_messageID) {
|
| 3480 | if (!$this->GetIsClassLoaded()) {
|
| 3481 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3482 |
|
| 3483 | return false;
|
| 3484 | } else if (empty($_messageID)) {
|
| 3485 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3486 | }
|
| 3487 |
|
| 3488 | $this->UpdatePool('messageid', $_messageID);
|
| 3489 |
|
| 3490 | return true;
|
| 3491 | }
|
| 3492 |
|
| 3493 | /**
|
| 3494 | * Check to see if the given staff/user can access the ticket
|
| 3495 | *
|
| 3496 | * @author Varun Shoor
|
| 3497 | * @param SWIFT_Base $_SWIFT_BaseObject The SWIFT_Base Object Pointer
|
| 3498 | * @return bool "true" on Success, "false" otherwise
|
| 3499 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 3500 | */
|
| 3501 | public function CanAccess($_SWIFT_BaseObject) {
|
| 3502 | if (!$this->GetIsClassLoaded()) {
|
| 3503 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3504 |
|
| 3505 | return false;
|
| 3506 | } else if ((!$_SWIFT_BaseObject instanceof SWIFT_Staff || !$_SWIFT_BaseObject->GetIsClassLoaded()) &&
|
| 3507 | (!$_SWIFT_BaseObject instanceof SWIFT_User || !$_SWIFT_BaseObject->GetIsClassLoaded())) {
|
| 3508 | return false;
|
| 3509 | }
|
| 3510 |
|
| 3511 | // Staff Check
|
| 3512 | if ($_SWIFT_BaseObject instanceof SWIFT_Staff)
|
| 3513 | {
|
| 3514 | $_assignedDepartmentIDList = $_SWIFT_BaseObject->GetAssignedDepartments(APP_TICKETS);
|
| 3515 |
|
| 3516 | if (in_array($this->GetProperty('departmentid'), $_assignedDepartmentIDList)) {
|
| 3517 | return true;
|
| 3518 | } else if ($this->GetProperty('departmentid') == '0'
|
| 3519 | && ($this->GetProperty('trasholddepartmentid') == '0' || in_array($this->GetProperty('trasholddepartmentid'), $_assignedDepartmentIDList))) {
|
| 3520 | return true;
|
| 3521 | }
|
| 3522 |
|
| 3523 | // User Check
|
| 3524 | } else if ($_SWIFT_BaseObject instanceof SWIFT_User) {
|
| 3525 | $_userEmailList = array();
|
| 3526 | $_userID = $_SWIFT_BaseObject->GetUserID();
|
| 3527 | $_userEmailList = array_merge($_userEmailList, $_SWIFT_BaseObject->GetEmailList());
|
| 3528 |
|
| 3529 | $_userIDList = array($_SWIFT_BaseObject->GetUserID());
|
| 3530 |
|
| 3531 | // Does this user have a shared organization or he is a manager in an organization?
|
| 3532 | $_SWIFT_UserOrganizationObject = $_SWIFT_BaseObject->GetOrganization();
|
| 3533 |
|
| 3534 | if (($_SWIFT_BaseObject->GetProperty('userrole') == SWIFT_User::ROLE_MANAGER && $_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded()) ||
|
| 3535 | ($_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded() && $_SWIFT_UserOrganizationObject->GetProperty('organizationtype') == SWIFT_UserOrganization::TYPE_SHARED))
|
| 3536 | {
|
| 3537 | $_userIDList_Organization = array();
|
| 3538 | $this->Database->Query("SELECT userid FROM " . TABLE_PREFIX . "users
|
| 3539 | WHERE userorganizationid = '" . intval($_SWIFT_UserOrganizationObject->GetUserOrganizationID()) . "'");
|
| 3540 | while ($this->Database->NextRecord())
|
| 3541 | {
|
| 3542 | $_userIDList_Organization[] = $this->Database->Record['userid'];
|
| 3543 |
|
| 3544 | $_userIDList[] = $this->Database->Record['userid'];
|
| 3545 | }
|
| 3546 |
|
| 3547 | $_userEmailList = array_merge($_userEmailList, SWIFT_UserEmail::RetrieveListOnUserIDList($_userIDList_Organization));
|
| 3548 | }
|
| 3549 |
|
| 3550 | if ($this->GetProperty('userid') != '0' && in_array($this->GetProperty('userid'), $_userIDList))
|
| 3551 | {
|
| 3552 | return true;
|
| 3553 | } else if (in_array(mb_strtolower($this->GetProperty('email')), $_userEmailList)) {
|
| 3554 | return true;
|
| 3555 | } else if ($this->GetProperty('creator') == SWIFT_Ticket::CREATOR_STAFF && in_array(mb_strtolower($this->GetProperty('replyto')), $_userEmailList)) {
|
| 3556 | return true;
|
| 3557 | }
|
| 3558 | }
|
| 3559 |
|
| 3560 | return false;
|
| 3561 | }
|
| 3562 |
|
| 3563 | /**
|
| 3564 | * Return the Ticket ID to be displayed according to relevant setting
|
| 3565 | *
|
| 3566 | * @author Varun Shoor
|
| 3567 | * @return mixed Ticket Mask ID or Ticket ID
|
| 3568 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3569 | */
|
| 3570 | public function GetTicketDisplayID() {
|
| 3571 | if (!$this->GetIsClassLoaded()) {
|
| 3572 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3573 |
|
| 3574 | return false;
|
| 3575 | }
|
| 3576 |
|
| 3577 | return IIF($this->Settings->Get('t_eticketid') == 'seq', $this->GetProperty('ticketid'), $this->GetProperty('ticketmaskid'));
|
| 3578 | }
|
| 3579 |
|
| 3580 | /**
|
| 3581 | * Recalculate the Ticket Link Property
|
| 3582 | *
|
| 3583 | * @author Varun Shoor
|
| 3584 | * @param array $_ticketIDList The Ticket ID List
|
| 3585 | * @return bool "true" on Success, "false" otherwise
|
| 3586 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3587 | */
|
| 3588 | static public function RecalculateTicketLinkProperty($_ticketIDList) {
|
| 3589 | $_SWIFT = SWIFT::GetInstance();
|
| 3590 |
|
| 3591 | if (!_is_array($_ticketIDList)) {
|
| 3592 | return false;
|
| 3593 | }
|
| 3594 |
|
| 3595 | $_ticketContainer = $_ticketLinkStatus = array();
|
| 3596 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 3597 | while ($_SWIFT->Database->NextRecord()) {
|
| 3598 | $_ticketContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 3599 | }
|
| 3600 |
|
| 3601 | // Calculate the link chains
|
| 3602 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "ticketlinkchains WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 3603 | while ($_SWIFT->Database->NextRecord()) {
|
| 3604 | $_ticketLinkStatus[] = $_SWIFT->Database->Record['ticketid'];
|
| 3605 | }
|
| 3606 |
|
| 3607 | foreach ($_ticketContainer as $_ticketID => $_SWIFT_TicketObject) {
|
| 3608 | if (in_array($_ticketID, $_ticketLinkStatus)) {
|
| 3609 | $_SWIFT_TicketObject->MarkAsLinked();
|
| 3610 | } else {
|
| 3611 | $_SWIFT_TicketObject->MarkAsUnlinked();
|
| 3612 | }
|
| 3613 | }
|
| 3614 |
|
| 3615 | return true;
|
| 3616 | }
|
| 3617 |
|
| 3618 | /**
|
| 3619 | * Get the ticket post count
|
| 3620 | *
|
| 3621 | * @author Varun Shoor
|
| 3622 | * @return int The Ticket Post Count
|
| 3623 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3624 | */
|
| 3625 | public function GetTicketPostCount() {
|
| 3626 | if (!$this->GetIsClassLoaded()) {
|
| 3627 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3628 |
|
| 3629 | return false;
|
| 3630 | }
|
| 3631 |
|
| 3632 | $_totalCount = 0;
|
| 3633 |
|
| 3634 | $_totalItemContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid = '" .
|
| 3635 | intval($this->GetTicketID()) . "'");
|
| 3636 | if (isset($_totalItemContainer['totalitems'])) {
|
| 3637 | $_totalCount = intval($_totalItemContainer['totalitems']);
|
| 3638 | }
|
| 3639 |
|
| 3640 | return $_totalCount;
|
| 3641 | }
|
| 3642 |
|
| 3643 | /**
|
| 3644 | * Retrieve the ticket posts associated with this ticket
|
| 3645 | *
|
| 3646 | * @author Varun Shoor
|
| 3647 | * @param int $_offset (OPTIONAL) The Starting Offset
|
| 3648 | * @param int $_limit (OPTIONAL) The Number of Results to Return
|
| 3649 | * @param string $_sortOrder (OPTIONAL) ASC/DESC The Sort Order
|
| 3650 | * @param constant $_creator (OPTIONAL) Filter by the Creator
|
| 3651 | * @return array The Ticket Post Object Container
|
| 3652 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 3653 | */
|
| 3654 | public function GetTicketPosts($_offset = 0, $_limit = false, $_sortOrder = 'ASC', $_creator = false) {
|
| 3655 | $_SWIFT = SWIFT::GetInstance();
|
| 3656 |
|
| 3657 | if (!$this->GetIsClassLoaded()) {
|
| 3658 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3659 |
|
| 3660 | return false;
|
| 3661 | }
|
| 3662 |
|
| 3663 | $_ticketPostObjectContainer = array();
|
| 3664 |
|
| 3665 | $_sqlQuery = "SELECT * FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid = '" . intval($this->GetTicketID()) . "' ORDER BY ticketpostid " .
|
| 3666 | $_sortOrder;
|
| 3667 | if (!empty($_limit)) {
|
| 3668 | $this->Database->QueryLimit($_sqlQuery, $_limit, $_offset);
|
| 3669 | } else {
|
| 3670 | $this->Database->Query($_sqlQuery);
|
| 3671 | }
|
| 3672 |
|
| 3673 | while ($this->Database->NextRecord()) {
|
| 3674 | if (!empty($_creator) && $_creator != $this->Database->Record['creator']) {
|
| 3675 | continue;
|
| 3676 | }
|
| 3677 |
|
| 3678 | $_ticketPostObjectContainer[$this->Database->Record['ticketpostid']] = new SWIFT_TicketPost(new SWIFT_DataStore($this->Database->Record));
|
| 3679 | }
|
| 3680 |
|
| 3681 | return $_ticketPostObjectContainer;
|
| 3682 | }
|
| 3683 |
|
| 3684 | /**
|
| 3685 | * Train the given tickets
|
| 3686 | *
|
| 3687 | * @author Varun Shoor
|
| 3688 | * @param array $_ticketIDList The Ticket ID List
|
| 3689 | * @return bool "true" on Success, "false" otherwise
|
| 3690 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3691 | */
|
| 3692 | static public function TrainBayesList($_ticketIDList, $_bayesCategoryID) {
|
| 3693 | $_SWIFT = SWIFT::GetInstance();
|
| 3694 |
|
| 3695 | if (!_is_array($_ticketIDList)) {
|
| 3696 | return false;
|
| 3697 | } else if (empty($_bayesCategoryID)) {
|
| 3698 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3699 | }
|
| 3700 |
|
| 3701 | $_bayesianCategoryCache = $_SWIFT->Cache->Get('bayesiancategorycache');
|
| 3702 |
|
| 3703 | $_SWIFT_BayesianObject = new SWIFT_Bayesian();
|
| 3704 | if (!$_SWIFT_BayesianObject instanceof SWIFT_Bayesian || !$_SWIFT_BayesianObject->GetIsClassLoaded()) {
|
| 3705 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3706 | }
|
| 3707 |
|
| 3708 | if (!isset($_bayesianCategoryCache[$_bayesCategoryID]))
|
| 3709 | {
|
| 3710 | throw new SWIFT_Ticket_Exception('Bayesian Category does not exist');
|
| 3711 | }
|
| 3712 |
|
| 3713 | $_ticketObjectContainer = array();
|
| 3714 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 3715 | while ($_SWIFT->Database->NextRecord()) {
|
| 3716 | $_ticketObjectContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 3717 | }
|
| 3718 |
|
| 3719 | foreach ($_ticketObjectContainer as $_ticketID => $_SWIFT_TicketObject) {
|
| 3720 | $_ticketPostContainer = $_SWIFT_TicketObject->GetTicketPosts(0, false, 'ASC', SWIFT_Ticket::CREATOR_CLIENT);
|
| 3721 | if (!_is_array($_ticketPostContainer)) {
|
| 3722 | continue;
|
| 3723 | }
|
| 3724 |
|
| 3725 | $_finalTicketPostText = $_SWIFT_TicketObject->GetProperty('subject');
|
| 3726 | foreach ($_ticketPostContainer as $_ticketPostID => $_SWIFT_TicketPostObject) {
|
| 3727 | $_finalTicketPostText .= $_SWIFT_TicketPostObject->GetProperty('contents') . SWIFT_CRLF;
|
| 3728 | }
|
| 3729 |
|
| 3730 | $_SWIFT_BayesianObject->Train($_ticketID, $_bayesCategoryID, $_finalTicketPostText);
|
| 3731 | }
|
| 3732 |
|
| 3733 | return true;
|
| 3734 | }
|
| 3735 |
|
| 3736 | /**
|
| 3737 | * Train the Bayesian
|
| 3738 | *
|
| 3739 | * @author Varun Shoor
|
| 3740 | * @param int $_bayesCategoryID The Bayesian Category ID
|
| 3741 | * @return bool "true" on Success, "false" otherwise
|
| 3742 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 3743 | */
|
| 3744 | public function TrainBayes($_bayesCategoryID)
|
| 3745 | {
|
| 3746 | if (!$this->GetIsClassLoaded())
|
| 3747 | {
|
| 3748 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3749 |
|
| 3750 | return false;
|
| 3751 | } else if (empty($_bayesCategoryID)) {
|
| 3752 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3753 | }
|
| 3754 |
|
| 3755 | self::TrainBayesList(array($this->GetTicketID()), $_bayesCategoryID);
|
| 3756 |
|
| 3757 | return true;
|
| 3758 | }
|
| 3759 |
|
| 3760 | /**
|
| 3761 | * Mark the given ticket ids as spam
|
| 3762 | *
|
| 3763 | * @author Varun Shoor
|
| 3764 | * @param array $_ticketIDList The Ticket ID List
|
| 3765 | * @return bool "true" on Success, "false" otherwise
|
| 3766 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3767 | */
|
| 3768 | static public function MarkAsSpamList($_ticketIDList) {
|
| 3769 | $_SWIFT = SWIFT::GetInstance();
|
| 3770 |
|
| 3771 | if (!_is_array($_ticketIDList)) {
|
| 3772 | return false;
|
| 3773 | }
|
| 3774 |
|
| 3775 | $_bayesianCategoryCache = $_SWIFT->Cache->Get('bayesiancategorycache');
|
| 3776 |
|
| 3777 | $_SWIFT_BayesianObject = new SWIFT_Bayesian();
|
| 3778 | if (!$_SWIFT_BayesianObject instanceof SWIFT_Bayesian || !$_SWIFT_BayesianObject->GetIsClassLoaded()) {
|
| 3779 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3780 | }
|
| 3781 |
|
| 3782 | $_bayesCategoryID = false;
|
| 3783 | foreach ($_bayesianCategoryCache as $_bayesianCategoryID => $_bayesianCategoryContainer) {
|
| 3784 | if ($_bayesianCategoryContainer['categorytype'] == SWIFT_BayesianCategory::CATEGORY_SPAM) {
|
| 3785 | $_bayesCategoryID = $_bayesianCategoryContainer['bayescategoryid'];
|
| 3786 |
|
| 3787 | break;
|
| 3788 | }
|
| 3789 | }
|
| 3790 |
|
| 3791 | if (!$_bayesCategoryID) {
|
| 3792 | throw new SWIFT_Ticket_Exception('Spam Bayesian Category not found');
|
| 3793 | }
|
| 3794 |
|
| 3795 | $_ticketObjectContainer = array();
|
| 3796 |
|
| 3797 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 3798 | while ($_SWIFT->Database->NextRecord()) {
|
| 3799 | $_ticketObjectContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 3800 | }
|
| 3801 |
|
| 3802 | foreach ($_ticketObjectContainer as $_ticketID => $_SWIFT_TicketObject) {
|
| 3803 | $_ticketPostContainer = $_SWIFT_TicketObject->GetTicketPosts(0, false, 'ASC', SWIFT_Ticket::CREATOR_CLIENT);
|
| 3804 | if (!_is_array($_ticketPostContainer)) {
|
| 3805 | continue;
|
| 3806 | }
|
| 3807 |
|
| 3808 | $_finalTicketPostText = $_SWIFT_TicketObject->GetProperty('subject');
|
| 3809 | foreach ($_ticketPostContainer as $_ticketPostID => $_SWIFT_TicketPostObject) {
|
| 3810 | $_finalTicketPostText .= $_SWIFT_TicketPostObject->GetProperty('contents') . SWIFT_CRLF;
|
| 3811 | }
|
| 3812 |
|
| 3813 | $_SWIFT_BayesianObject->Train($_ticketID, $_bayesCategoryID, $_finalTicketPostText);
|
| 3814 | }
|
| 3815 |
|
| 3816 | if ($_SWIFT->Settings->Get('t_spammovetotrash') == '1') {
|
| 3817 | self::TrashList($_ticketIDList);
|
| 3818 | }
|
| 3819 |
|
| 3820 | if ($_SWIFT->Settings->Get('t_spamban') == '1') {
|
| 3821 | self::BanList($_ticketIDList, $_SWIFT->Staff->GetStaffID());
|
| 3822 | }
|
| 3823 |
|
| 3824 | return true;
|
| 3825 | }
|
| 3826 |
|
| 3827 | /**
|
| 3828 | * Watch a ticket list
|
| 3829 | *
|
| 3830 | * @author Varun Shoor
|
| 3831 | * @param array $_ticketIDList The Ticket ID List
|
| 3832 | * @return bool "true" on Success, "false" otherwise
|
| 3833 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3834 | */
|
| 3835 | static public function Watch($_ticketIDList, SWIFT_Staff $_SWIFT_StaffObject) {
|
| 3836 | $_SWIFT = SWIFT::GetInstance();
|
| 3837 |
|
| 3838 | if (!$_SWIFT_StaffObject instanceof SWIFT_Staff || !$_SWIFT_StaffObject->GetIsClassLoaded()) {
|
| 3839 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3840 | } else if (!_is_array($_ticketIDList)) {
|
| 3841 | return false;
|
| 3842 | }
|
| 3843 |
|
| 3844 | $_ticketObjectContainer = array();
|
| 3845 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 3846 | while ($_SWIFT->Database->NextRecord()) {
|
| 3847 | $_ticketObjectContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 3848 | }
|
| 3849 |
|
| 3850 | if (!count($_ticketObjectContainer)) {
|
| 3851 | return false;
|
| 3852 | }
|
| 3853 |
|
| 3854 | foreach ($_ticketObjectContainer as $_ticketID => $_SWIFT_TicketObject) {
|
| 3855 | // Create Audit Log
|
| 3856 | SWIFT_TicketAuditLog::AddToLog($_SWIFT_TicketObject, null, SWIFT_TicketAuditLog::ACTION_WATCH,
|
| 3857 | sprintf($_SWIFT->Language->Get('al_watch'), $_SWIFT_TicketObject->GetTicketDisplayID(), $_SWIFT_StaffObject->GetProperty('fullname')),
|
| 3858 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 3859 |
|
| 3860 | SWIFT_TicketWatcher::Create($_SWIFT_TicketObject, $_SWIFT_StaffObject);
|
| 3861 | }
|
| 3862 |
|
| 3863 | return true;
|
| 3864 | }
|
| 3865 |
|
| 3866 | /**
|
| 3867 | * Unwatch a ticket list
|
| 3868 | *
|
| 3869 | * @author Varun Shoor
|
| 3870 | * @param array $_ticketIDList The Ticket ID List
|
| 3871 | * @return bool "true" on Success, "false" otherwise
|
| 3872 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3873 | */
|
| 3874 | static public function UnWatch($_ticketIDList, SWIFT_Staff $_SWIFT_StaffObject) {
|
| 3875 | $_SWIFT = SWIFT::GetInstance();
|
| 3876 |
|
| 3877 | if (!$_SWIFT_StaffObject instanceof SWIFT_Staff || !$_SWIFT_StaffObject->GetIsClassLoaded()) {
|
| 3878 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3879 | } else if (!_is_array($_ticketIDList)) {
|
| 3880 | return false;
|
| 3881 | }
|
| 3882 |
|
| 3883 | SWIFT_TicketWatcher::DeleteOnTicket($_ticketIDList, array($_SWIFT_StaffObject->GetStaffID()));
|
| 3884 |
|
| 3885 | return true;
|
| 3886 | }
|
| 3887 |
|
| 3888 | /**
|
| 3889 | * Add the object to the active workflow queue
|
| 3890 | *
|
| 3891 | * @author Varun Shoor
|
| 3892 | * @param SWIFT_Ticket $_SWIFT_TicketObject The SWIFT_Ticket Object Pointer
|
| 3893 | * @return bool "true" on Success, "false" otherwise
|
| 3894 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3895 | */
|
| 3896 | static public function AddToWorkflowQueue(SWIFT_Ticket $_SWIFT_TicketObject) {
|
| 3897 | $_SWIFT = SWIFT::GetInstance();
|
| 3898 |
|
| 3899 | if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
|
| 3900 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3901 | } else if (isset(self::$_workflowQueue[$_SWIFT_TicketObject->GetTicketID()])) {
|
| 3902 | return true;
|
| 3903 | }
|
| 3904 |
|
| 3905 | self::$_workflowQueue[$_SWIFT_TicketObject->GetTicketID()] = $_SWIFT_TicketObject;
|
| 3906 |
|
| 3907 | if (self::$_isWorkflowQueueActive) {
|
| 3908 | return true;
|
| 3909 | }
|
| 3910 |
|
| 3911 | self::$_isWorkflowQueueActive = true;
|
| 3912 |
|
| 3913 | SWIFT::Shutdown('SWIFT_Ticket', 'ProcessWorkflowQueue', 9, false);
|
| 3914 |
|
| 3915 | return true;
|
| 3916 | }
|
| 3917 |
|
| 3918 | /**
|
| 3919 | * Process the workflow queue for each active ticket
|
| 3920 | *
|
| 3921 | * @author Varun Shoor
|
| 3922 | * @return bool "true" on Success, "false" otherwise
|
| 3923 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 3924 | */
|
| 3925 | static public function ProcessWorkflowQueue() {
|
| 3926 | $_SWIFT = SWIFT::GetInstance();
|
| 3927 |
|
| 3928 | if (!count(self::$_workflowQueue)) {
|
| 3929 | return true;
|
| 3930 | }
|
| 3931 |
|
| 3932 | $_ticketWorkflowIDContainer = $_ticketObjectContainer = $_ticketIDList = array();
|
| 3933 |
|
| 3934 | foreach (self::$_workflowQueue as $_ticketID => $_SWIFT_TicketObject) {
|
| 3935 | $_ticketWorkflowIDList = SWIFT_TicketWorkflow::ExecuteAll($_SWIFT_TicketObject);
|
| 3936 | $_ticketWorkflowIDContainer[$_SWIFT_TicketObject->GetTicketID()] = $_ticketWorkflowIDList;
|
| 3937 | $_ticketObjectContainer[$_SWIFT_TicketObject->GetTicketID()] = $_SWIFT_TicketObject;
|
| 3938 |
|
| 3939 | $_ticketIDList[] = $_SWIFT_TicketObject->GetTicketID();
|
| 3940 | }
|
| 3941 |
|
| 3942 | if (!count($_ticketWorkflowIDContainer)) {
|
| 3943 | self::$_workflowQueue = array();
|
| 3944 | self::$_isWorkflowQueueActive = false;
|
| 3945 |
|
| 3946 | return false;
|
| 3947 | }
|
| 3948 |
|
| 3949 | SWIFT_TicketLinkedTable::DeleteOnTicket($_ticketIDList, SWIFT_TicketLinkedTable::LINKTYPE_WORKFLOW);
|
| 3950 |
|
| 3951 | foreach ($_ticketWorkflowIDContainer as $_ticketID => $_ticketWorkflowIDList) {
|
| 3952 | if (!isset($_ticketObjectContainer[$_ticketID])) {
|
| 3953 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 3954 | }
|
| 3955 |
|
| 3956 | $_SWIFT_TicketObject = $_ticketObjectContainer[$_ticketID];
|
| 3957 | // Add the workflows to the ticket
|
| 3958 | if (_is_array($_ticketWorkflowIDList)) {
|
| 3959 | $_ticketLinkContainer = array();
|
| 3960 | $_ticketLinkContainer[SWIFT_TicketLinkedTable::LINKTYPE_WORKFLOW] = $_ticketWorkflowIDList;
|
| 3961 |
|
| 3962 | SWIFT_TicketLinkedTable::CreateIfNotExists($_SWIFT_TicketObject, $_ticketLinkContainer);
|
| 3963 | }
|
| 3964 | }
|
| 3965 |
|
| 3966 | self::$_workflowQueue = array();
|
| 3967 | self::$_isWorkflowQueueActive = false;
|
| 3968 |
|
| 3969 | return true;
|
| 3970 | }
|
| 3971 |
|
| 3972 | /**
|
| 3973 | * Processes the POST attachment field (ticketattachments) and adds the attachments to the ticket
|
| 3974 | *
|
| 3975 | * @author Varun Shoor
|
| 3976 | * @param SWIFT_TicketPost $_SWIFT_TicketPostObject (OPTIONAL) The Ticket Post Object
|
| 3977 | * @param string $_fieldName (OPTIONAL) The Custom Field Name
|
| 3978 | * @return bool "true" on Success, "false" otherwise
|
| 3979 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 3980 | */
|
| 3981 | public function ProcessPostAttachments(SWIFT_TicketPost $_SWIFT_TicketPostObject = null, $_fieldName = '') {
|
| 3982 | if (!$this->GetIsClassLoaded()) {
|
| 3983 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 3984 |
|
| 3985 | return false;
|
| 3986 | }
|
| 3987 |
|
| 3988 | $_finalFieldName = 'ticketattachments';
|
| 3989 | if (!empty($_fieldName))
|
| 3990 | {
|
| 3991 | $_finalFieldName = $_fieldName;
|
| 3992 | }
|
| 3993 |
|
| 3994 | $_listFieldName = $_finalFieldName . 'list';
|
| 3995 |
|
| 3996 | // Link with first post if none specified
|
| 3997 | if ($_SWIFT_TicketPostObject == null) {
|
| 3998 | $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($this->GetProperty('firstpostid')));
|
| 3999 | }
|
| 4000 |
|
| 4001 | if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded()) {
|
| 4002 | throw new SWIFT_Ticket_Exception(SWIFT_INVALIDDATA);
|
| 4003 | }
|
| 4004 |
|
| 4005 | $_attachmentCount = 0;
|
| 4006 |
|
| 4007 | if (isset($_POST[$_listFieldName]) && _is_array($_POST[$_listFieldName]))
|
| 4008 | {
|
| 4009 | foreach ($_POST[$_listFieldName] as $_attachmentID)
|
| 4010 | {
|
| 4011 | $_SWIFT_AttachmentObject = new SWIFT_Attachment($_attachmentID);
|
| 4012 |
|
| 4013 | SWIFT_Attachment::CloneOnTicket($this, $_SWIFT_TicketPostObject, $_SWIFT_AttachmentObject);
|
| 4014 |
|
| 4015 | $this->AddToNotificationAttachments($_SWIFT_AttachmentObject->GetProperty('filename'), $_SWIFT_AttachmentObject->GetProperty('filetype'),
|
| 4016 | $_SWIFT_AttachmentObject->Get());
|
| 4017 |
|
| 4018 | $_attachmentCount++;
|
| 4019 |
|
| 4020 | }
|
| 4021 |
|
| 4022 | if ($_attachmentCount > 0) {
|
| 4023 | $this->UpdatePool('hasattachments', '1');
|
| 4024 | }
|
| 4025 |
|
| 4026 | unset($_POST[$_listFieldName]);
|
| 4027 | }
|
| 4028 |
|
| 4029 | if (!isset($_FILES[$_finalFieldName]) || !_is_array($_FILES[$_finalFieldName]) || !_is_array($_FILES[$_finalFieldName]['name'])) {
|
| 4030 | return false;
|
| 4031 | }
|
| 4032 |
|
| 4033 | // Create the attachments
|
| 4034 | foreach ($_FILES[$_finalFieldName]['name'] as $_fileIndex => $_fileName) {
|
| 4035 | if (empty($_fileName) || empty($_FILES[$_finalFieldName]['type'][$_fileIndex]) || empty($_FILES[$_finalFieldName]['size'][$_fileIndex]) ||
|
| 4036 | !is_uploaded_file($_FILES[$_finalFieldName]['tmp_name'][$_fileIndex]))
|
| 4037 | {
|
| 4038 | continue;
|
| 4039 | }
|
| 4040 |
|
| 4041 | $_SWIFT_AttachmentStoreObject = new SWIFT_AttachmentStoreFile($_FILES[$_finalFieldName]['tmp_name'][$_fileIndex],
|
| 4042 | $_FILES[$_finalFieldName]['type'][$_fileIndex], $_fileName);
|
| 4043 |
|
| 4044 | $_SWIFT_AttachmentObject = SWIFT_Attachment::CreateOnTicket($this, $_SWIFT_TicketPostObject, $_SWIFT_AttachmentStoreObject);
|
| 4045 |
|
| 4046 | $this->AddToNotificationAttachments($_fileName, $_FILES[$_finalFieldName]['type'][$_fileIndex], file_get_contents($_FILES[$_finalFieldName]['tmp_name'][$_fileIndex]));
|
| 4047 |
|
| 4048 | $_attachmentCount++;
|
| 4049 | }
|
| 4050 |
|
| 4051 | if ($_attachmentCount > 0) {
|
| 4052 | $this->UpdatePool('hasattachments', '1');
|
| 4053 | }
|
| 4054 |
|
| 4055 | return true;
|
| 4056 | }
|
| 4057 |
|
| 4058 | /**
|
| 4059 | * Checks for valid input for attachments
|
| 4060 | *
|
| 4061 | * @author Varun Shoor
|
| 4062 | * @param string $_inputType The Input Type (staff/supportcenter/parser)
|
| 4063 | * @return array (result - bool, invalid file list)
|
| 4064 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 4065 | */
|
| 4066 | static public function CheckForValidAttachments($_inputType) {
|
| 4067 | $_SWIFT = SWIFT::GetInstance();
|
| 4068 |
|
| 4069 | // Always accept staff input
|
| 4070 | if ($_inputType == 'staff') {
|
| 4071 | return true;
|
| 4072 | }
|
| 4073 |
|
| 4074 | // If its coming from support center and we cant find anything then return true
|
| 4075 | if ($_inputType == 'supportcenter' && (!isset($_FILES['ticketattachments']) || !_is_array($_FILES['ticketattachments']) || !_is_array($_FILES['ticketattachments']['name']))) {
|
| 4076 | return true;
|
| 4077 | }
|
| 4078 |
|
| 4079 | $_fileTypeCache = $_SWIFT->Cache->Get('filetypecache');
|
| 4080 | $_fileTypeCacheMap = array();
|
| 4081 |
|
| 4082 | // Do we need to sanitize the data?
|
| 4083 | if ($_SWIFT->Settings->Get('tickets_resattachments') == '0') {
|
| 4084 | return true;
|
| 4085 | }
|
| 4086 |
|
| 4087 | // Sanitize the data.. do we need to sanitize the data?
|
| 4088 | foreach ($_fileTypeCache as $_ticketFileTypeID => $_ticketFileTypeContainer) {
|
| 4089 | $_fileTypeCacheMap[mb_strtolower($_ticketFileTypeContainer['extension'])] = $_ticketFileTypeContainer;
|
| 4090 | }
|
| 4091 |
|
| 4092 | $_resultArray = array();
|
| 4093 | $_result = true;
|
| 4094 |
|
| 4095 | // Check the attachments
|
| 4096 | foreach ($_FILES['ticketattachments']['name'] as $_fileIndex => $_fileName) {
|
| 4097 | $_fileExtension = mb_strtolower(substr($_fileName, (strrpos($_fileName, '.')+1)));
|
| 4098 |
|
| 4099 | // Extension isnt added in the list? || Check whether we can accept it from support center? || Invalid File Size?
|
| 4100 | if (!isset($_fileTypeCacheMap[$_fileExtension]) ||
|
| 4101 | ($_inputType == 'supportcenter' && $_fileTypeCacheMap[$_fileExtension]['acceptsupportcenter'] == '0') ||
|
| 4102 | ($_inputType == 'parser' && $_fileTypeCacheMap[$_fileExtension]['acceptmailparser'] == '0') ||
|
| 4103 | ($_fileTypeCacheMap[$_fileExtension]['maxsize'] != '0' && ($_FILES['ticketattachments']['size'][$_fileIndex]/1024) >= $_fileTypeCacheMap[$_fileExtension]['maxsize']))
|
| 4104 | {
|
| 4105 | $_result = false;
|
| 4106 | $_resultArray[] = $_fileName;
|
| 4107 | }
|
| 4108 | }
|
| 4109 |
|
| 4110 | return array($_result, $_resultArray);
|
| 4111 | }
|
| 4112 |
|
| 4113 | /**
|
| 4114 | * Retrieve the ticket attachment container
|
| 4115 | *
|
| 4116 | * @author Varun Shoor
|
| 4117 | * @return array $_ticketAttachmentContainer
|
| 4118 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4119 | */
|
| 4120 | public function GetAttachmentContainer() {
|
| 4121 | if (!$this->GetIsClassLoaded()) {
|
| 4122 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4123 |
|
| 4124 | return false;
|
| 4125 | }
|
| 4126 |
|
| 4127 | $_ticketAttachmentContainer = array();
|
| 4128 |
|
| 4129 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "attachments WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 4130 | while ($this->Database->NextRecord()) {
|
| 4131 | $_ticketAttachmentContainer[$this->Database->Record['linktypeid']][$this->Database->Record['attachmentid']] = $this->Database->Record;
|
| 4132 | }
|
| 4133 |
|
| 4134 | return $_ticketAttachmentContainer;
|
| 4135 | }
|
| 4136 |
|
| 4137 | /**
|
| 4138 | * Retrieve the history count for this user based on his userid & email address
|
| 4139 | *
|
| 4140 | * @author Varun Shoor
|
| 4141 | * @return int The History Count
|
| 4142 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4143 | */
|
| 4144 | public function GetHistoryCount() {
|
| 4145 | if (!$this->GetIsClassLoaded()) {
|
| 4146 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4147 |
|
| 4148 | return false;
|
| 4149 | }
|
| 4150 |
|
| 4151 | $_userID = '-1';
|
| 4152 | if ($this->GetProperty('userid') != '0')
|
| 4153 | {
|
| 4154 | $_userID = intval($this->GetProperty('userid'));
|
| 4155 | }
|
| 4156 |
|
| 4157 | $_countContainer = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickets WHERE userid = '" .
|
| 4158 | intval($_userID) . "' OR email = '" . $this->Database->Escape($this->GetProperty('email')) . "'");
|
| 4159 |
|
| 4160 | if (isset($_countContainer['totalitems']) && intval($_countContainer['totalitems']) > 0) {
|
| 4161 | return $_countContainer['totalitems'] - 1;
|
| 4162 | }
|
| 4163 |
|
| 4164 | return 0;
|
| 4165 | }
|
| 4166 |
|
| 4167 | /**
|
| 4168 | * Retrieve the history for this ticket
|
| 4169 | *
|
| 4170 | * @author Varun Shoor
|
| 4171 | * @return array The History Container
|
| 4172 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4173 | */
|
| 4174 | public function RetrieveHistory() {
|
| 4175 | if (!$this->GetIsClassLoaded()) {
|
| 4176 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4177 |
|
| 4178 | return false;
|
| 4179 | }
|
| 4180 |
|
| 4181 | $_historyContainer = array();
|
| 4182 |
|
| 4183 | $_sqlExtend = '';
|
| 4184 | if ($this->GetProperty('userid') != '0')
|
| 4185 | {
|
| 4186 | $_sqlExtend = " OR userid = '" . intval($this->GetProperty('userid')) . "'";
|
| 4187 | }
|
| 4188 |
|
| 4189 | $this->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE email = '" . $this->Database->Escape($this->GetProperty('email')) . "'" . $_sqlExtend . " ORDER BY dateline DESC");
|
| 4190 | while ($this->Database->NextRecord()) {
|
| 4191 | $_historyContainer[$this->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($this->Database->Record));
|
| 4192 | }
|
| 4193 |
|
| 4194 | return $_historyContainer;
|
| 4195 | }
|
| 4196 |
|
| 4197 | /**
|
| 4198 | * Retrieve the relevant user object
|
| 4199 | *
|
| 4200 | * @author Varun Shoor
|
| 4201 | * @return mixed "SWIFT_User" (OBJECT) on Success, "false" otherwise
|
| 4202 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4203 | */
|
| 4204 | public function GetUserObject() {
|
| 4205 | if (!$this->GetIsClassLoaded()) {
|
| 4206 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4207 |
|
| 4208 | return false;
|
| 4209 | }
|
| 4210 |
|
| 4211 | // Have we already cached the user object?
|
| 4212 | if ($this->_isUserObjectCached == true) {
|
| 4213 | return $this->_UserObject;
|
| 4214 | }
|
| 4215 |
|
| 4216 | $_SWIFT_UserObject = false;
|
| 4217 | if ($this->GetProperty('userid') != '0') {
|
| 4218 | try {
|
| 4219 | $_SWIFT_UserObject = new SWIFT_User(new SWIFT_DataID($this->GetProperty('userid')));
|
| 4220 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 4221 |
|
| 4222 | return false;
|
| 4223 | }
|
| 4224 | }
|
| 4225 |
|
| 4226 | $this->_UserObject = $_SWIFT_UserObject;
|
| 4227 | $this->_isUserObjectCached = true;
|
| 4228 |
|
| 4229 | return $_SWIFT_UserObject;
|
| 4230 | }
|
| 4231 |
|
| 4232 | /**
|
| 4233 | * Retrieve the relevant user group object
|
| 4234 | *
|
| 4235 | * @author Varun Shoor
|
| 4236 | * @return mixed "SWIFT_UserGroup" (OBJECT) on Success, "false" otherwise
|
| 4237 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4238 | */
|
| 4239 | public function GetUserGroupObject() {
|
| 4240 | if (!$this->GetIsClassLoaded()) {
|
| 4241 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4242 |
|
| 4243 | return false;
|
| 4244 | }
|
| 4245 |
|
| 4246 | // Have we already cached the user object?
|
| 4247 | if ($this->_isUserGroupObjectCached == true) {
|
| 4248 | return $this->_UserGroupObject;
|
| 4249 | }
|
| 4250 |
|
| 4251 | $_SWIFT_UserObject = $this->GetUserObject();
|
| 4252 | $_SWIFT_UserGroupObject = false;
|
| 4253 |
|
| 4254 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 4255 | {
|
| 4256 | try {
|
| 4257 | $_SWIFT_UserGroupObject = new SWIFT_UserGroup($_SWIFT_UserObject->GetProperty('usergroupid'));
|
| 4258 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 4259 |
|
| 4260 | return false;
|
| 4261 | }
|
| 4262 | }
|
| 4263 |
|
| 4264 | $this->_UserGroupObject = $_SWIFT_UserGroupObject;
|
| 4265 | $this->_isUserGroupObjectCached = true;
|
| 4266 |
|
| 4267 | return $_SWIFT_UserGroupObject;
|
| 4268 | }
|
| 4269 |
|
| 4270 | /**
|
| 4271 | * Retrieve the user organization object associated with this ticket
|
| 4272 | *
|
| 4273 | * @author Varun Shoor
|
| 4274 | * @return mixed "SWIFT_UserOrganization" (OBJECT) on Success, "false" otherwise
|
| 4275 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4276 | */
|
| 4277 | public function GetUserOrganizationObject() {
|
| 4278 | if (!$this->GetIsClassLoaded()) {
|
| 4279 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4280 |
|
| 4281 | return false;
|
| 4282 | }
|
| 4283 |
|
| 4284 | // Have we already cached the user organization object?
|
| 4285 | if ($this->_isUserOrganizationObjectCached == true) {
|
| 4286 | return $this->_UserOrganizationObject;
|
| 4287 | }
|
| 4288 |
|
| 4289 | $_SWIFT_UserOrganizationObject = false;
|
| 4290 |
|
| 4291 | $_SWIFT_UserObject = $this->GetUserobject();
|
| 4292 |
|
| 4293 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded() &&
|
| 4294 | $_SWIFT_UserObject->GetProperty('userorganizationid') != '0')
|
| 4295 | {
|
| 4296 | try
|
| 4297 | {
|
| 4298 | $_SWIFT_UserOrganizationObject = new SWIFT_UserOrganization($_SWIFT_UserObject->GetProperty('userorganizationid'));
|
| 4299 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 4300 |
|
| 4301 | }
|
| 4302 | }
|
| 4303 |
|
| 4304 | $this->_UserOrganizationObject = $_SWIFT_UserOrganizationObject;
|
| 4305 | $this->_isUserOrganizationObjectCached = true;
|
| 4306 |
|
| 4307 | return $_SWIFT_UserOrganizationObject;
|
| 4308 | }
|
| 4309 |
|
| 4310 | /**
|
| 4311 | * Get the relevant mail subject based on mail type
|
| 4312 | *
|
| 4313 | * @author Varun Shoor
|
| 4314 | * @param constant $_mailType The Mail Type
|
| 4315 | * @param string $_customSubject (OPTIONAL) The Custom Subject
|
| 4316 | * @return mixed "Mail Subject" on Success, "false" otherwise
|
| 4317 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4318 | */
|
| 4319 | public function GetMailSubject($_mailType, $_customSubject = '') {
|
| 4320 | $_SWIFT = SWIFT::GetInstance();
|
| 4321 |
|
| 4322 | if (!$this->GetIsClassLoaded()) {
|
| 4323 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4324 |
|
| 4325 | return false;
|
| 4326 | }
|
| 4327 |
|
| 4328 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 4329 | $_emailQueueID = $this->GetProperty('emailqueueid');
|
| 4330 | $_templateGroupID = $this->GetProperty('tgroupid');
|
| 4331 |
|
| 4332 | /*
|
| 4333 | * BUG FIX - Varun Shoor
|
| 4334 | *
|
| 4335 | * SWIFT-1327 From name and From email address improvements in autoresponder email, if visitor sends an offline message and help desk create the ticket
|
| 4336 | * SWIFT-1651 From Email Address (in autoresponder email) should set according to the template group under email queue, if ticket is created from client support center in case of multi-domain installation
|
| 4337 | *
|
| 4338 | * Comments: None
|
| 4339 | */
|
| 4340 |
|
| 4341 | // First try to load up the email queue based on template group & department match
|
| 4342 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4343 | {
|
| 4344 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4345 | {
|
| 4346 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid') && $_emailQueueContainer['tgroupid'] == $_templateGroupID)
|
| 4347 | {
|
| 4348 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4349 |
|
| 4350 | break;
|
| 4351 | }
|
| 4352 | }
|
| 4353 | }
|
| 4354 |
|
| 4355 | // No Queue Prefix set, itterate through queues looking for one for ONLY this department
|
| 4356 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4357 | {
|
| 4358 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4359 | {
|
| 4360 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid'))
|
| 4361 | {
|
| 4362 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4363 |
|
| 4364 | break;
|
| 4365 | }
|
| 4366 | }
|
| 4367 | }
|
| 4368 |
|
| 4369 | $_subjectPrefix = $_finalSubjectPrefix = '';
|
| 4370 | if (isset($_emailQueueCache['list'][$_emailQueueID]))
|
| 4371 | {
|
| 4372 | $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
|
| 4373 |
|
| 4374 | $_subjectPrefix = $_emailQueueContainer['prefix'];
|
| 4375 | }
|
| 4376 |
|
| 4377 | if (!empty($_subjectPrefix))
|
| 4378 | {
|
| 4379 | $_finalSubjectPrefix = $_subjectPrefix . ' ';
|
| 4380 | }
|
| 4381 |
|
| 4382 | $_finalSubject = $this->GetProperty('subject');
|
| 4383 | if (!empty($_customSubject)) {
|
| 4384 | $_finalSubject = $_customSubject;
|
| 4385 | }
|
| 4386 |
|
| 4387 | if ($this->Settings->Get('t_cleanmailsubjects') == '1') {
|
| 4388 | return $_finalSubject;
|
| 4389 | }
|
| 4390 |
|
| 4391 | switch ($_mailType) {
|
| 4392 | case self::MAIL_NOTIFICATION:
|
| 4393 | return '[' . $_finalSubjectPrefix . '!' . $this->GetTicketDisplayID() . ']: ' . $_finalSubject;
|
| 4394 | break;
|
| 4395 |
|
| 4396 | case self::MAIL_CLIENT:
|
| 4397 | return '[' . $_finalSubjectPrefix . '#' . $this->GetTicketDisplayID() . ']: ' . $_finalSubject;
|
| 4398 | break;
|
| 4399 |
|
| 4400 | case self::MAIL_THIRDPARTY:
|
| 4401 | return '[' . $_finalSubjectPrefix . '~' . $this->GetTicketDisplayID() . ']: ' . $_finalSubject;
|
| 4402 | break;
|
| 4403 |
|
| 4404 | default:
|
| 4405 | break;
|
| 4406 | }
|
| 4407 |
|
| 4408 | return false;
|
| 4409 | }
|
| 4410 |
|
| 4411 | /**
|
| 4412 | * Retrieve the default from name for the email
|
| 4413 | *
|
| 4414 | * @author Varun Shoor
|
| 4415 | * @param SWIFT_Staff $_SWIFT_StaffObject (OPTIONAL) The SWIFT_Staff Object Pointer
|
| 4416 | * @return string The Default From Name
|
| 4417 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4418 | */
|
| 4419 | public function GetMailFromName(SWIFT_Staff $_SWIFT_StaffObject = null)
|
| 4420 | {
|
| 4421 | $_SWIFT = SWIFT::GetInstance();
|
| 4422 |
|
| 4423 | if (!$this->GetIsClassLoaded())
|
| 4424 | {
|
| 4425 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4426 |
|
| 4427 | return false;
|
| 4428 | }
|
| 4429 |
|
| 4430 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 4431 | $_emailQueueID = $this->GetProperty('emailqueueid');
|
| 4432 | $_templateGroupID = $this->GetProperty('tgroupid');
|
| 4433 | if (empty($_templateGroupID) && isset($_SWIFT->TemplateGroup) && $_SWIFT->TemplateGroup instanceof SWIFT_TemplateGroup) {
|
| 4434 | $_templateGroupID = $_SWIFT->TemplateGroup->GetTemplateGroupID();
|
| 4435 | }
|
| 4436 |
|
| 4437 |
|
| 4438 | /*
|
| 4439 | * BUG FIX - Varun Shoor
|
| 4440 | *
|
| 4441 | * SWIFT-1327 From name and From email address improvements in autoresponder email, if visitor sends an offline message and help desk create the ticket
|
| 4442 | * SWIFT-1651 From Email Address (in autoresponder email) should set according to the template group under email queue, if ticket is created from client support center in case of multi-domain installation
|
| 4443 | *
|
| 4444 | * Comments: None
|
| 4445 | */
|
| 4446 |
|
| 4447 | // First try to lookup based on department and template group
|
| 4448 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4449 | {
|
| 4450 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4451 | {
|
| 4452 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid') && $_emailQueueContainer['tgroupid'] == $_templateGroupID)
|
| 4453 | {
|
| 4454 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4455 |
|
| 4456 | break;
|
| 4457 | }
|
| 4458 | }
|
| 4459 | }
|
| 4460 |
|
| 4461 | // No Queue Prefix set, itterate through queues looking for one for ONLY this department
|
| 4462 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4463 | {
|
| 4464 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4465 | {
|
| 4466 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid'))
|
| 4467 | {
|
| 4468 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4469 |
|
| 4470 | break;
|
| 4471 | }
|
| 4472 | }
|
| 4473 | }
|
| 4474 |
|
| 4475 | // Name Priority: Template Group > Settings > Staff > Email Queue
|
| 4476 |
|
| 4477 | $_defaultFromName = SWIFT::Get('companyname');
|
| 4478 | if (empty($_defaultFromName))
|
| 4479 | {
|
| 4480 | $_defaultFromName = $this->Settings->Get('general_companyname');
|
| 4481 | }
|
| 4482 |
|
| 4483 | if ($_SWIFT_StaffObject instanceof SWIFT_Staff && $_SWIFT_StaffObject->GetIsClassLoaded())
|
| 4484 | {
|
| 4485 | $_defaultFromName = $_SWIFT_StaffObject->GetProperty('fullname');
|
| 4486 | }
|
| 4487 |
|
| 4488 | if (isset($_emailQueueCache['list'][$_emailQueueID]))
|
| 4489 | {
|
| 4490 | $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
|
| 4491 |
|
| 4492 | if (!empty($_emailQueueContainer['customfromname']))
|
| 4493 | {
|
| 4494 | $_defaultFromName = $_emailQueueContainer['customfromname'];
|
| 4495 | }
|
| 4496 | }
|
| 4497 |
|
| 4498 | return $_defaultFromName;
|
| 4499 | }
|
| 4500 |
|
| 4501 | /**
|
| 4502 | * Retrieve the default from email
|
| 4503 | *
|
| 4504 | * @author Varun Shoor
|
| 4505 | * @return string The Default Return Email
|
| 4506 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4507 | */
|
| 4508 | public function GetMailFromEmail()
|
| 4509 | {
|
| 4510 | $_SWIFT = SWIFT::GetInstance();
|
| 4511 |
|
| 4512 | if (!$this->GetIsClassLoaded())
|
| 4513 | {
|
| 4514 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4515 |
|
| 4516 | return false;
|
| 4517 | }
|
| 4518 |
|
| 4519 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 4520 | $_emailQueueID = $this->GetProperty('emailqueueid');
|
| 4521 | $_templateGroupID = $this->GetProperty('tgroupid');
|
| 4522 | if (empty($_templateGroupID) && isset($_SWIFT->TemplateGroup) && $_SWIFT->TemplateGroup instanceof SWIFT_TemplateGroup) {
|
| 4523 | $_templateGroupID = $_SWIFT->TemplateGroup->GetTemplateGroupID();
|
| 4524 | }
|
| 4525 |
|
| 4526 | /*
|
| 4527 | * BUG FIX - Varun Shoor
|
| 4528 | *
|
| 4529 | * SWIFT-1327 From name and From email address improvements in autoresponder email, if visitor sends an offline message and help desk create the ticket
|
| 4530 | * SWIFT-1651 From Email Address (in autoresponder email) should set according to the template group under email queue, if ticket is created from client support center in case of multi-domain installation
|
| 4531 | *
|
| 4532 | * Comments: None
|
| 4533 | */
|
| 4534 |
|
| 4535 | // First check against the template group id and department id
|
| 4536 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4537 | {
|
| 4538 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4539 | {
|
| 4540 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid') && $_templateGroupID == $_emailQueueContainer['tgroupid'])
|
| 4541 | {
|
| 4542 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4543 |
|
| 4544 | break;
|
| 4545 | }
|
| 4546 | }
|
| 4547 | }
|
| 4548 |
|
| 4549 | // No Queue Prefix set, itterate through queues looking for one for ONLY this department
|
| 4550 | if (empty($_emailQueueID) && isset($_emailQueueCache['list']) && _is_array($_emailQueueCache['list']))
|
| 4551 | {
|
| 4552 | foreach ($_emailQueueCache['list'] as $_emailQueueContainer)
|
| 4553 | {
|
| 4554 | if ($_emailQueueContainer['departmentid'] == $this->GetProperty('departmentid'))
|
| 4555 | {
|
| 4556 | $_emailQueueID = $_emailQueueContainer['emailqueueid'];
|
| 4557 |
|
| 4558 | break;
|
| 4559 | }
|
| 4560 | }
|
| 4561 | }
|
| 4562 |
|
| 4563 | // Email Priority: Settings > Email Queue
|
| 4564 | $_defaultFromEmail = $this->Settings->Get('general_returnemail');
|
| 4565 |
|
| 4566 | if (isset($_emailQueueCache['list'][$_emailQueueID]))
|
| 4567 | {
|
| 4568 | $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
|
| 4569 | if (!empty($_emailQueueContainer['customfromemail']))
|
| 4570 | {
|
| 4571 | $_defaultFromEmail = $_emailQueueContainer['customfromemail'];
|
| 4572 | } else {
|
| 4573 | $_defaultFromEmail = $_emailQueueContainer['email'];
|
| 4574 | }
|
| 4575 | }
|
| 4576 |
|
| 4577 | return $_defaultFromEmail;
|
| 4578 | }
|
| 4579 |
|
| 4580 | /**
|
| 4581 | * Load the Core Language Table
|
| 4582 | *
|
| 4583 | * @author Varun Shoor
|
| 4584 | * @return bool "true" on Success, "false" otherwise
|
| 4585 | */
|
| 4586 | static public function LoadLanguageTable() {
|
| 4587 | $_SWIFT = SWIFT::GetInstance();
|
| 4588 |
|
| 4589 | $_SWIFT->Language->Load('tickets_notifications', SWIFT_LanguageEngine::TYPE_FILE);
|
| 4590 | $_SWIFT->Language->Load('tickets_auditlogs', SWIFT_LanguageEngine::TYPE_FILE);
|
| 4591 |
|
| 4592 | return true;
|
| 4593 | }
|
| 4594 |
|
| 4595 | /**
|
| 4596 | * Retrieve the signature for this based on associated queue or given staff/user
|
| 4597 | *
|
| 4598 | * @author Varun Shoor
|
| 4599 | * @param bool $_isHTML Whether the reply is HTML
|
| 4600 | * @param object $_SWIFT_StaffObject (OPTIONAL) The SWIFT_Staff Object
|
| 4601 | * @return bool "true" on Success, "false" otherwise
|
| 4602 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4603 | */
|
| 4604 | public function GetSignature($_isHTML, $_SWIFT_StaffObject = null)
|
| 4605 | {
|
| 4606 | $_SWIFT = SWIFT::GetInstance();
|
| 4607 |
|
| 4608 | if (!$this->GetIsClassLoaded())
|
| 4609 | {
|
| 4610 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4611 |
|
| 4612 | return false;
|
| 4613 | }
|
| 4614 |
|
| 4615 | $_emailQueueCache = $_SWIFT->Cache->Get('queuecache');
|
| 4616 |
|
| 4617 | $_emailQueueID = $this->GetProperty('emailqueueid');
|
| 4618 |
|
| 4619 | $_signatureContents = '';
|
| 4620 |
|
| 4621 | if ($_isHTML == true)
|
| 4622 | {
|
| 4623 | $_signatureContents = '<br />';
|
| 4624 | } else {
|
| 4625 | $_signatureContents = SWIFT_CRLF;
|
| 4626 | }
|
| 4627 |
|
| 4628 | // First priority is given to Staff signature
|
| 4629 | if ($_SWIFT_StaffObject instanceof SWIFT_Staff && $_SWIFT_StaffObject->GetIsClassLoaded())
|
| 4630 | {
|
| 4631 | $_staffSignatureContents = '';
|
| 4632 | try {
|
| 4633 | $_staffSignatureContents = $_SWIFT_StaffObject->GetProperty('signature');
|
| 4634 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 4635 | }
|
| 4636 |
|
| 4637 | if ($_isHTML == true)
|
| 4638 | {
|
| 4639 | $_signatureContents .= nl2br($_staffSignatureContents);
|
| 4640 | } else {
|
| 4641 | $_signatureContents .= preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $_staffSignatureContents);
|
| 4642 | }
|
| 4643 | }
|
| 4644 |
|
| 4645 | if (_is_array($_emailQueueCache) && isset($_emailQueueCache['list'][$_emailQueueID])) {
|
| 4646 | $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
|
| 4647 | if ($_isHTML == true)
|
| 4648 | {
|
| 4649 | $_signatureContents .= nl2br($_emailQueueContainer['contents']);
|
| 4650 | } else {
|
| 4651 | $_signatureContents .= preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $_emailQueueContainer['contents']);
|
| 4652 | }
|
| 4653 | }
|
| 4654 |
|
| 4655 | return $_signatureContents;
|
| 4656 | }
|
| 4657 |
|
| 4658 | /**
|
| 4659 | * Dispatch the auto responder msg
|
| 4660 | *
|
| 4661 | * @author Varun Shoor
|
| 4662 | * @return bool "true" on Success, "false" otherwise
|
| 4663 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4664 | */
|
| 4665 | public function DispatchAutoresponder()
|
| 4666 | {
|
| 4667 | if (!$this->GetIsClassLoaded())
|
| 4668 | {
|
| 4669 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 4670 |
|
| 4671 | return false;
|
| 4672 | }
|
| 4673 |
|
| 4674 | // We dispatch the auto responder to ALL registered emails of the user
|
| 4675 | $_ccEmailList = $this->GetCCUserEmails();
|
| 4676 |
|
| 4677 | $this->Load->Library('Ticket:TicketEmailDispatch', array($this));
|
| 4678 | $this->TicketEmailDispatch->DispatchAutoresponder('', $_ccEmailList);
|
| 4679 |
|
| 4680 | return true;
|
| 4681 | }
|
| 4682 |
|
| 4683 | /**
|
| 4684 | * Retrieves all other emails of the user excluding the one that was used to create the ticket
|
| 4685 | *
|
| 4686 | * @author Varun Shoor
|
| 4687 | * @return array The Email List
|
| 4688 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 4689 | */
|
| 4690 | public function GetCCUserEmails()
|
| 4691 | {
|
| 4692 | if (!$this->GetIsClassLoaded())
|
| 4693 | {
|
| 4694 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 4695 |
|
| 4696 | return false;
|
| 4697 | }
|
| 4698 |
|
| 4699 | $_SWIFT_UserObject = $this->GetUserObject();
|
| 4700 |
|
| 4701 | $_ccEmailList = array();
|
| 4702 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 4703 | {
|
| 4704 | $_userEmailList = $_SWIFT_UserObject->GetEmailList();
|
| 4705 | if (_is_array($_userEmailList))
|
| 4706 | {
|
| 4707 | foreach ($_userEmailList as $_emailAddress)
|
| 4708 | {
|
| 4709 | if (mb_strtolower($_emailAddress) != mb_strtolower($this->GetProperty('email')))
|
| 4710 | {
|
| 4711 | $_ccEmailList[] = $_emailAddress;
|
| 4712 | }
|
| 4713 | }
|
| 4714 | }
|
| 4715 | }
|
| 4716 |
|
| 4717 | return $_ccEmailList;
|
| 4718 | }
|
| 4719 |
|
| 4720 | /**
|
| 4721 | * Retrieve the first ticket post object
|
| 4722 | *
|
| 4723 | * @author Varun Shoor
|
| 4724 | * @return SWIFT_TicketPost The SWIFT_TicketPost Object
|
| 4725 | * @throws SWIFT_Exception If the Class is not Loaded or If Invalid Data is Provided
|
| 4726 | */
|
| 4727 | public function GetFirstPostObject()
|
| 4728 | {
|
| 4729 | if (!$this->GetIsClassLoaded())
|
| 4730 | {
|
| 4731 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 4732 |
|
| 4733 | return false;
|
| 4734 | }
|
| 4735 |
|
| 4736 | $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($this->GetProperty('firstpostid')));
|
| 4737 | if (!$_SWIFT_TicketPostObject instanceof SWIFT_TicketPost || !$_SWIFT_TicketPostObject->GetIsClassLoaded())
|
| 4738 | {
|
| 4739 | throw new SWIFT_Exception(SWIFT_INVALIDDATA);
|
| 4740 | }
|
| 4741 |
|
| 4742 | return $_SWIFT_TicketPostObject;
|
| 4743 | }
|
| 4744 |
|
| 4745 | /**
|
| 4746 | * Retrieve the time tracking count for the ticket
|
| 4747 | *
|
| 4748 | * @author Varun Shoor
|
| 4749 | * @return int The Count
|
| 4750 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 4751 | */
|
| 4752 | public function GetTimeTrackCount()
|
| 4753 | {
|
| 4754 | if (!$this->GetIsClassLoaded())
|
| 4755 | {
|
| 4756 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 4757 |
|
| 4758 | return false;
|
| 4759 | }
|
| 4760 |
|
| 4761 | $_timeTrackCount = $this->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickettimetracks WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 4762 | if (isset($_timeTrackCount['totalitems']))
|
| 4763 | {
|
| 4764 | return intval($_timeTrackCount['totalitems']);
|
| 4765 | }
|
| 4766 |
|
| 4767 | return 0;
|
| 4768 | }
|
| 4769 |
|
| 4770 | /**
|
| 4771 | * Retrieve the list of all possible ticket ids created by a given user
|
| 4772 | *
|
| 4773 | * @author Varun Shoor
|
| 4774 | * @param SWIFT_User $_SWIFT_UserObject The SWIFT_User Object Pointer
|
| 4775 | * @return array The Ticket ID List
|
| 4776 | * @throws SWIFT_Exception If Invalid Data is Provided
|
| 4777 | */
|
| 4778 | static public function GetTicketIDListOnUser(SWIFT_User $_SWIFT_UserObject)
|
| 4779 | {
|
| 4780 | $_SWIFT = SWIFT::GetInstance();
|
| 4781 |
|
| 4782 | if (!$_SWIFT_UserObject instanceof SWIFT_User || !$_SWIFT_UserObject->GetIsClassLoaded())
|
| 4783 | {
|
| 4784 | throw new SWIFT_Exception(SWIFT_INVALIDDATA);
|
| 4785 | }
|
| 4786 |
|
| 4787 | $_ticketIDList = array();
|
| 4788 |
|
| 4789 | $_SWIFT->Database->Query("SELECT ticketid FROM " . TABLE_PREFIX . "tickets WHERE userid = '" . intval($_SWIFT_UserObject->GetUserID()) . "' OR email IN (" . BuildIN($_SWIFT_UserObject->GetEmailList()) . ")");
|
| 4790 | while ($_SWIFT->Database->NextRecord())
|
| 4791 | {
|
| 4792 | $_ticketIDList[] = intval($_SWIFT->Database->Record['ticketid']);
|
| 4793 | }
|
| 4794 |
|
| 4795 | return $_ticketIDList;
|
| 4796 | }
|
| 4797 |
|
| 4798 | /**
|
| 4799 | * Create a Note
|
| 4800 | *
|
| 4801 | * @author Varun Shoor
|
| 4802 | * @param SWIFT_User $_SWIFT_UserObject (OPTIONAL) The User Object
|
| 4803 | * @param string $_noteContents The Note Contents
|
| 4804 | * @param int $_noteColor The Note Color
|
| 4805 | * @param string $_noteType The Note Type
|
| 4806 | * @param int $_forStaffID (OPTIONAL) Restrict view to a given staff
|
| 4807 | * @param SWIFT_Staff $_SWIFT_StaffObject (OPTIONAL) The Staff Object to create note as
|
| 4808 | * @return bool "true" on Success, "false" otherwise
|
| 4809 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 4810 | */
|
| 4811 | public function CreateNote($_SWIFT_UserObject, $_noteContents, $_noteColor, $_noteType, $_forStaffID = false, $_SWIFT_StaffObject = false) {
|
| 4812 | $_SWIFT = SWIFT::GetInstance();
|
| 4813 |
|
| 4814 | if (!$this->GetIsClassLoaded()) {
|
| 4815 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 4816 |
|
| 4817 | return false;
|
| 4818 | }
|
| 4819 |
|
| 4820 | $_isOrganizationNote = false;
|
| 4821 | $_SWIFT_UserOrganizationObject = $this->GetUserOrganizationObject();
|
| 4822 |
|
| 4823 | if ($_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded() &&
|
| 4824 | isset($_noteType) && $_noteType == 'userorganization')
|
| 4825 | {
|
| 4826 | $_isOrganizationNote = true;
|
| 4827 | }
|
| 4828 |
|
| 4829 | // Add notes
|
| 4830 | if (!empty($_noteContents))
|
| 4831 | {
|
| 4832 | if ($_isOrganizationNote)
|
| 4833 | {
|
| 4834 | SWIFT_UserOrganizationNote::Create($_SWIFT_UserOrganizationObject, $_noteContents, intval($_noteColor));
|
| 4835 |
|
| 4836 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_NEWNOTE,
|
| 4837 | $_SWIFT->Language->Get('al_usernote'),
|
| 4838 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 4839 | } else if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded() && isset($_noteType) && $_noteType == 'user') {
|
| 4840 | SWIFT_UserNote::Create($_SWIFT_UserObject, $_noteContents, intval($_noteColor));
|
| 4841 |
|
| 4842 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_NEWNOTE,
|
| 4843 | $_SWIFT->Language->Get('al_usernote'),
|
| 4844 | SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 4845 | } else {
|
| 4846 |
|
| 4847 | $_staffID = 0;
|
| 4848 | $_staffName = $this->Language->Get('system');
|
| 4849 | if ($_SWIFT_StaffObject instanceof SWIFT_Staff && $_SWIFT_StaffObject->GetIsClassLoaded()) {
|
| 4850 | $_staffID = $_SWIFT_StaffObject->GetStaffID();
|
| 4851 | $_staffName = $_SWIFT_StaffObject->GetProperty('fullname');
|
| 4852 | } else if ($_SWIFT->Staff instanceof SWIFT_Staff && $_SWIFT->Staff->GetIsClassLoaded()) {
|
| 4853 | $_staffID = $_SWIFT->Staff->GetStaffID();
|
| 4854 | $_staffName = $_SWIFT->Staff->GetProperty('fullname');
|
| 4855 | }
|
| 4856 |
|
| 4857 | SWIFT_TicketNote::Create($this, intval($_forStaffID), $_staffID, $_staffName, $_noteContents, intval($_noteColor));
|
| 4858 |
|
| 4859 | SWIFT_TicketAuditLog::AddToLog($this, null, SWIFT_TicketAuditLog::ACTION_NEWNOTE, $_SWIFT->Language->Get('al_ticketnote'), SWIFT_TicketAuditLog::VALUE_NONE, 0, '', 0, '');
|
| 4860 | }
|
| 4861 |
|
| 4862 | if ( $this->Settings->Get('t_ticketnoteresetsupdatetime') == 1 ) {
|
| 4863 | $this->UpdatePool('lastactivity', DATENOW);
|
| 4864 | }
|
| 4865 |
|
| 4866 | }
|
| 4867 |
|
| 4868 | return true;
|
| 4869 | }
|
| 4870 |
|
| 4871 | /**
|
| 4872 | * Retrieve the Ticket ID from a Ticket Mask ID
|
| 4873 | *
|
| 4874 | * @author Varun Shoor
|
| 4875 | * @param string $_ticketMaskID The Ticket Mask ID
|
| 4876 | * @return int The Ticket ID
|
| 4877 | * @throws SWIFT_Exception If Invalid Data is Provided
|
| 4878 | */
|
| 4879 | static public function GetTicketIDFromMask($_ticketMaskID)
|
| 4880 | {
|
| 4881 | $_SWIFT = SWIFT::GetInstance();
|
| 4882 |
|
| 4883 | if (empty($_ticketMaskID))
|
| 4884 | {
|
| 4885 | throw new SWIFT_Exception(SWIFT_INVALIDDATA);
|
| 4886 | }
|
| 4887 |
|
| 4888 | $_ticketIDContainer = $_SWIFT->Database->QueryFetch("SELECT ticketid FROM " . TABLE_PREFIX . "tickets WHERE ticketmaskid = '" . $_SWIFT->Database->Escape($_ticketMaskID) . "'");
|
| 4889 | if (isset($_ticketIDContainer['ticketid']) && !empty($_ticketIDContainer['ticketid']))
|
| 4890 | {
|
| 4891 | return $_ticketIDContainer['ticketid'];
|
| 4892 | }
|
| 4893 |
|
| 4894 | return false;
|
| 4895 | }
|
| 4896 |
|
| 4897 | /**
|
| 4898 | * Retrieve the history count for this user based on his userid & email addresses
|
| 4899 | *
|
| 4900 | * @author Varun Shoor
|
| 4901 | * @param SWIFT_User $_SWIFT_UserObject
|
| 4902 | * @param array $_userEmailList
|
| 4903 | * @return int The History Count
|
| 4904 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 4905 | */
|
| 4906 | static public function GetHistoryCountOnUser($_SWIFT_UserObject, $_userEmailList = array()) {
|
| 4907 | $_SWIFT = SWIFT::GetInstance();
|
| 4908 |
|
| 4909 | $_userID = '-1';
|
| 4910 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 4911 | {
|
| 4912 | $_userID = $_SWIFT_UserObject->GetUserID();
|
| 4913 | }
|
| 4914 |
|
| 4915 | if (!_is_array($_userEmailList))
|
| 4916 | {
|
| 4917 | $_userEmailList = $_SWIFT_UserObject->GetEmailList();
|
| 4918 | }
|
| 4919 |
|
| 4920 | $_countContainer = $_SWIFT->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickets WHERE userid = '" .
|
| 4921 | intval($_userID) . "' OR email IN (" . BuildIN($_userEmailList) . ")");
|
| 4922 |
|
| 4923 | if (isset($_countContainer['totalitems']) && intval($_countContainer['totalitems']) > 0) {
|
| 4924 | return $_countContainer['totalitems'];
|
| 4925 | }
|
| 4926 |
|
| 4927 | return 0;
|
| 4928 | }
|
| 4929 |
|
| 4930 | /**
|
| 4931 | * Retrieve the history for this user
|
| 4932 | *
|
| 4933 | * @author Varun Shoor
|
| 4934 | * @param SWIFT_User $_SWIFT_UserObject
|
| 4935 | * @param array $_emailList The Email List
|
| 4936 | * @param string $_sortBy (OPTIONAL) The Custom Sort By
|
| 4937 | * @param string $_sortOrder (OPTIONAL) The Custom Sort Order
|
| 4938 | * @return array The History Container
|
| 4939 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4940 | */
|
| 4941 | static public function RetrieveHistoryOnUser($_SWIFT_UserObject, $_emailList = array(), $_sortBy = false, $_sortOrder = false) {
|
| 4942 | $_SWIFT = SWIFT::GetInstance();
|
| 4943 |
|
| 4944 | $_userID = '-1';
|
| 4945 | $_userEmailList = $_emailList;
|
| 4946 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 4947 | {
|
| 4948 | $_userID = $_SWIFT_UserObject->GetUserID();
|
| 4949 | $_userEmailList = array_merge($_userEmailList, $_SWIFT_UserObject->GetEmailList());
|
| 4950 | }
|
| 4951 |
|
| 4952 | $_historyContainer = array();
|
| 4953 |
|
| 4954 | $_ticketSortBy = 'dateline';
|
| 4955 | $_ticketSortOrder = 'DESC';
|
| 4956 | if (!empty($_sortBy) && !empty($_sortOrder))
|
| 4957 | {
|
| 4958 | $_ticketSortBy = $_sortBy;
|
| 4959 | $_ticketSortOrder = $_sortOrder;
|
| 4960 | }
|
| 4961 |
|
| 4962 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets WHERE userid = '" . intval($_userID) .
|
| 4963 | "' OR email IN (" . BuildIN($_userEmailList) . ") ORDER BY " . $_ticketSortBy . " " . $_ticketSortOrder);
|
| 4964 | while ($_SWIFT->Database->NextRecord()) {
|
| 4965 | $_historyContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 4966 | }
|
| 4967 |
|
| 4968 | return $_historyContainer;
|
| 4969 | }
|
| 4970 |
|
| 4971 | /**
|
| 4972 | * Retrieve the Support Center Tickets for this user
|
| 4973 | *
|
| 4974 | * @author Varun Shoor
|
| 4975 | * @param SWIFT_User $_SWIFT_UserObject
|
| 4976 | * @param string $_sortBy (OPTIONAL) The Custom Sort By
|
| 4977 | * @param string $_sortOrder (OPTIONAL) The Custom Sort Order
|
| 4978 | * @param int $_offset (OPTIONAL) The Starting Offset
|
| 4979 | * @param int $_limit (OPTIONAL) The Number of Results to Return
|
| 4980 | * @param bool $_excludeResolved
|
| 4981 | * @return array The History Container
|
| 4982 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 4983 | */
|
| 4984 | static public function RetrieveSCTicketsOnUser(SWIFT_User $_SWIFT_UserObject, $_sortBy = false, $_sortOrder = false, $_offset = 0, $_limit = false, $_excludeResolved = false) {
|
| 4985 | $_SWIFT = SWIFT::GetInstance();
|
| 4986 |
|
| 4987 | $_userID = '-1';
|
| 4988 | $_userEmailList = array();
|
| 4989 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 4990 | {
|
| 4991 | $_userID = $_SWIFT_UserObject->GetUserID();
|
| 4992 | $_userEmailList = array_merge($_userEmailList, $_SWIFT_UserObject->GetEmailList());
|
| 4993 | }
|
| 4994 |
|
| 4995 | $_historyContainer = array();
|
| 4996 |
|
| 4997 | $_ticketSortBy = 'dateline';
|
| 4998 | $_ticketSortOrder = 'DESC';
|
| 4999 | if (!empty($_sortBy) && !empty($_sortOrder))
|
| 5000 | {
|
| 5001 | $_ticketSortBy = $_sortBy;
|
| 5002 | $_ticketSortOrder = $_sortOrder;
|
| 5003 | }
|
| 5004 |
|
| 5005 | $_userIDList = array($_SWIFT_UserObject->GetUserID());
|
| 5006 |
|
| 5007 | // Does this user have a shared organization or he is a manager in an organization?
|
| 5008 | $_SWIFT_UserOrganizationObject = $_SWIFT_UserObject->GetOrganization();
|
| 5009 |
|
| 5010 | if (($_SWIFT_UserObject->GetProperty('userrole') == SWIFT_User::ROLE_MANAGER && $_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded()) ||
|
| 5011 | ($_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded() && $_SWIFT_UserOrganizationObject->GetProperty('organizationtype') == SWIFT_UserOrganization::TYPE_SHARED))
|
| 5012 | {
|
| 5013 | $_userIDList_Organization = array();
|
| 5014 | $_SWIFT->Database->Query("SELECT userid FROM " . TABLE_PREFIX . "users WHERE userorganizationid = '" . intval($_SWIFT_UserOrganizationObject->GetUserOrganizationID()) . "'");
|
| 5015 | while ($_SWIFT->Database->NextRecord())
|
| 5016 | {
|
| 5017 | $_userIDList_Organization[] = $_SWIFT->Database->Record['userid'];
|
| 5018 |
|
| 5019 | $_userIDList[] = $_SWIFT->Database->Record['userid'];
|
| 5020 | }
|
| 5021 |
|
| 5022 | $_userEmailList = array_merge($_userEmailList, SWIFT_UserEmail::RetrieveListOnUserIDList($_userIDList_Organization));
|
| 5023 | }
|
| 5024 |
|
| 5025 | $_whereExtended = '';
|
| 5026 | if ($_excludeResolved) {
|
| 5027 | $_whereExtended .= ' AND isresolved = "0"';
|
| 5028 | }
|
| 5029 | if ($_limit) {
|
| 5030 | $_SWIFT->Database->QueryLimit("SELECT * FROM " . TABLE_PREFIX . "tickets
|
| 5031 | WHERE (userid IN (" . BuildIN($_userIDList) . ") OR email IN (" . BuildIN($_userEmailList) . ") OR replyto IN (" . BuildIN($_userEmailList) . "))
|
| 5032 | AND departmentid <> '0'
|
| 5033 | " . $_whereExtended . "
|
| 5034 | ORDER BY " . $_ticketSortBy . " " . $_ticketSortOrder, $_limit, $_offset);
|
| 5035 | } else {
|
| 5036 | $_SWIFT->Database->QueryLimit("SELECT * FROM " . TABLE_PREFIX . "tickets
|
| 5037 | WHERE (userid IN (" . BuildIN($_userIDList) . ") OR email IN (" . BuildIN($_userEmailList) . ") OR replyto IN (" . BuildIN($_userEmailList) . "))
|
| 5038 | AND departmentid <> '0'
|
| 5039 | " . $_whereExtended . "
|
| 5040 | ORDER BY " . $_ticketSortBy . " " . $_ticketSortOrder);
|
| 5041 | }
|
| 5042 |
|
| 5043 | while ($_SWIFT->Database->NextRecord()) {
|
| 5044 | if ($_SWIFT->Database->Record['creator'] == SWIFT_Ticket::CREATOR_STAFF && !in_array(mb_strtolower($_SWIFT->Database->Record['replyto']), $_userEmailList))
|
| 5045 | {
|
| 5046 | continue;
|
| 5047 | }
|
| 5048 |
|
| 5049 | $_historyContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 5050 | }
|
| 5051 |
|
| 5052 | return $_historyContainer;
|
| 5053 | }
|
| 5054 |
|
| 5055 | /**
|
| 5056 | * Retrieve the Support Center Tickets count for this user
|
| 5057 | *
|
| 5058 | * @author Varun Shoor
|
| 5059 | * @param SWIFT_User $_SWIFT_UserObject
|
| 5060 | * @param bool $_excludeResolved
|
| 5061 | * @param bool $_resolvedOnly
|
| 5062 | * @return int The History Count
|
| 5063 | * @throws SWIFT_Ticket_Exception If Invalid Data is Provided
|
| 5064 | */
|
| 5065 | static public function RetrieveSCTicketsCountOnUser($_SWIFT_UserObject, $_excludeResolved = false, $_resolvedOnly = false) {
|
| 5066 | $_SWIFT = SWIFT::GetInstance();
|
| 5067 |
|
| 5068 | $_userID = '-1';
|
| 5069 | $_userEmailList = array();
|
| 5070 | if ($_SWIFT_UserObject instanceof SWIFT_User && $_SWIFT_UserObject->GetIsClassLoaded())
|
| 5071 | {
|
| 5072 | $_userID = $_SWIFT_UserObject->GetUserID();
|
| 5073 | $_userEmailList = array_merge($_userEmailList, $_SWIFT_UserObject->GetEmailList());
|
| 5074 | }
|
| 5075 |
|
| 5076 | $_userIDList = array($_SWIFT_UserObject->GetUserID());
|
| 5077 |
|
| 5078 | // Does this user have a shared organization or he is a manager in an organization?
|
| 5079 | $_SWIFT_UserOrganizationObject = $_SWIFT_UserObject->GetOrganization();
|
| 5080 |
|
| 5081 | if (($_SWIFT_UserObject->GetProperty('userrole') == SWIFT_User::ROLE_MANAGER && $_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded()) ||
|
| 5082 | ($_SWIFT_UserOrganizationObject instanceof SWIFT_UserOrganization && $_SWIFT_UserOrganizationObject->GetIsClassLoaded() && $_SWIFT_UserOrganizationObject->GetProperty('organizationtype') == SWIFT_UserOrganization::TYPE_SHARED))
|
| 5083 | {
|
| 5084 | $_userIDList_Organization = array();
|
| 5085 | $_SWIFT->Database->Query("SELECT userid FROM " . TABLE_PREFIX . "users WHERE userorganizationid = '" . intval($_SWIFT_UserOrganizationObject->GetUserOrganizationID()) . "'");
|
| 5086 | while ($_SWIFT->Database->NextRecord())
|
| 5087 | {
|
| 5088 | $_userIDList_Organization[] = $_SWIFT->Database->Record['userid'];
|
| 5089 |
|
| 5090 | $_userIDList[] = $_SWIFT->Database->Record['userid'];
|
| 5091 | }
|
| 5092 |
|
| 5093 | $_userEmailList = array_merge($_userEmailList, SWIFT_UserEmail::RetrieveListOnUserIDList($_userIDList_Organization));
|
| 5094 | }
|
| 5095 |
|
| 5096 | $_whereExtended = '';
|
| 5097 | if ($_excludeResolved) {
|
| 5098 | $_whereExtended = ' AND isresolved = "0"';
|
| 5099 | }
|
| 5100 |
|
| 5101 | if ($_resolvedOnly) {
|
| 5102 | $_whereExtended = ' AND isresolved = "1"';
|
| 5103 | }
|
| 5104 |
|
| 5105 | $_countContainer = $_SWIFT->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickets
|
| 5106 | WHERE (userid = '" . intval($_userID) . "' OR email IN (" . BuildIN($_userEmailList) . ") OR replyto IN (" . BuildIN($_userEmailList) . "))
|
| 5107 | AND departmentid <> '0'
|
| 5108 | " . $_whereExtended . "
|
| 5109 | ");
|
| 5110 |
|
| 5111 | if (isset($_countContainer['totalitems']) && intval($_countContainer['totalitems']) > 0) {
|
| 5112 | return $_countContainer['totalitems'];
|
| 5113 | }
|
| 5114 |
|
| 5115 | return 0;
|
| 5116 | }
|
| 5117 |
|
| 5118 | /**
|
| 5119 | * Set the Watcher Notification Message
|
| 5120 | *
|
| 5121 | * @author Varun Shoor
|
| 5122 | * @param string $_watcherName The Watcher Name
|
| 5123 | * @param string $_watcherMessage The Watcher Message
|
| 5124 | * @return bool "true" on Success, "false" otherwise
|
| 5125 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5126 | */
|
| 5127 | public function SetWatcherProperties($_watcherName, $_watcherMessage)
|
| 5128 | {
|
| 5129 | if (!$this->GetIsClassLoaded())
|
| 5130 | {
|
| 5131 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5132 |
|
| 5133 | return false;
|
| 5134 | }
|
| 5135 |
|
| 5136 | $this->_watcherCustomName = $_watcherName;
|
| 5137 | $this->_watchNotificationMessage = $_watcherMessage;
|
| 5138 |
|
| 5139 | return true;
|
| 5140 | }
|
| 5141 |
|
| 5142 | /**
|
| 5143 | * Process the Notification for Ticket Watchers
|
| 5144 | *
|
| 5145 | * @author Varun Shoor
|
| 5146 | * @return bool "true" on Success, "false" otherwise
|
| 5147 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5148 | */
|
| 5149 | public function ProcessWatchers()
|
| 5150 | {
|
| 5151 | chdir(SWIFT_BASEPATH);
|
| 5152 | $_ticketID = $this->GetTicketID();
|
| 5153 |
|
| 5154 | if (!$this->GetIsClassLoaded())
|
| 5155 | {
|
| 5156 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5157 |
|
| 5158 | return false;
|
| 5159 | } else if (isset(self::$_watcherExecutedCache[$_ticketID]) && self::$_watcherExecutedCache[$_ticketID] == 1) {
|
| 5160 | return true;
|
| 5161 | }
|
| 5162 |
|
| 5163 | $_staffCache = $this->Cache->Get('staffcache');
|
| 5164 |
|
| 5165 | $_emailList = array();
|
| 5166 | $_ticketWatchContainer = SWIFT_TicketWatcher::RetrieveOnTicket($this);
|
| 5167 | if (_is_array($_ticketWatchContainer))
|
| 5168 | {
|
| 5169 | foreach ($_ticketWatchContainer as $_ticketWatch)
|
| 5170 | {
|
| 5171 | $_staffID = $_ticketWatch['staffid'];
|
| 5172 |
|
| 5173 | if (!isset($_staffCache[$_staffID]))
|
| 5174 | {
|
| 5175 | continue;
|
| 5176 | }
|
| 5177 |
|
| 5178 | $_emailList[] = $_staffCache[$_staffID]['email'];
|
| 5179 | }
|
| 5180 | }
|
| 5181 |
|
| 5182 | if (!count($_emailList))
|
| 5183 | {
|
| 5184 | return false;
|
| 5185 | }
|
| 5186 |
|
| 5187 | $this->Notification->Dispatch(SWIFT_TicketNotification::TYPE_CUSTOM, $_emailList, $this->GetProperty('subject'), $this->_watchNotificationMessage, $this->_watcherCustomName, '', true);
|
| 5188 |
|
| 5189 | self::$_watcherExecutedCache[$_ticketID] = 1;
|
| 5190 |
|
| 5191 | return true;
|
| 5192 | }
|
| 5193 |
|
| 5194 | /**
|
| 5195 | * Queue the Watcher Execution
|
| 5196 | *
|
| 5197 | * @author Varun Shoor
|
| 5198 | * @return bool "true" on Success, "false" otherwise
|
| 5199 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5200 | */
|
| 5201 | public function QueueWatcherExecution()
|
| 5202 | {
|
| 5203 | $_ticketID = $this->GetTicketID();
|
| 5204 |
|
| 5205 | if (!$this->GetIsClassLoaded())
|
| 5206 | {
|
| 5207 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5208 |
|
| 5209 | return false;
|
| 5210 | } else if (isset(self::$_watcherPendingCache[$_ticketID]) && self::$_watcherPendingCache[$_ticketID] == '1') {
|
| 5211 | return true;
|
| 5212 | }
|
| 5213 |
|
| 5214 | // SWIFT::Shutdown($this, 'ProcessWatchers', -1, false);
|
| 5215 |
|
| 5216 | self::$_watcherPendingCache[$_ticketID] = 1;
|
| 5217 |
|
| 5218 | return true;
|
| 5219 | }
|
| 5220 |
|
| 5221 | /**
|
| 5222 | * Process the Notification Rules
|
| 5223 | *
|
| 5224 | * @author Varun Shoor
|
| 5225 | * @return bool "true" on Success, "false" otherwise
|
| 5226 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5227 | */
|
| 5228 | public function ProcessNotifications()
|
| 5229 | {
|
| 5230 | chdir(SWIFT_BASEPATH);
|
| 5231 | $_ticketID = $this->GetTicketID();
|
| 5232 |
|
| 5233 | if (!$this->GetIsClassLoaded())
|
| 5234 | {
|
| 5235 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5236 |
|
| 5237 | return false;
|
| 5238 | } else if (isset(self::$_notificationExecutionCache[$_ticketID]) && self::$_notificationExecutionCache[$_ticketID] == '1') {
|
| 5239 | return true;
|
| 5240 | }
|
| 5241 |
|
| 5242 | $this->NotificationManager->Trigger();
|
| 5243 |
|
| 5244 | self::$_notificationExecutionCache[$_ticketID] = 1;
|
| 5245 |
|
| 5246 | return true;
|
| 5247 | }
|
| 5248 |
|
| 5249 | /**
|
| 5250 | * Dispatch a Notification via Email on this Ticket
|
| 5251 | *
|
| 5252 | * @author Varun Shoor
|
| 5253 | * @param constant $_notificationType The Notification Type
|
| 5254 | * @param array $_customEmailList The Custom Email List
|
| 5255 | * @param string $_emailPrefix (OPTIONAL) The Custom Email Prefix
|
| 5256 | * @param string $_notificationEvent (OPTIONAL) The Notification Event
|
| 5257 | * @return bool "true" on Success, "false" otherwise
|
| 5258 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5259 | */
|
| 5260 | public function DispatchNotification($_notificationType, $_customEmailList, $_emailPrefix = '', $_notificationEvent = '')
|
| 5261 | {
|
| 5262 | if (!$this->GetIsClassLoaded())
|
| 5263 | {
|
| 5264 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5265 |
|
| 5266 | return false;
|
| 5267 | }
|
| 5268 |
|
| 5269 | $_finalEmailPrefix = '';
|
| 5270 | if (!empty($_emailPrefix))
|
| 5271 | {
|
| 5272 | $_finalEmailPrefix = $_emailPrefix . ' - ';
|
| 5273 | }
|
| 5274 |
|
| 5275 | $_notificationMessage = $this->_watchNotificationMessage;
|
| 5276 | if (empty($_notificationMessage)) {
|
| 5277 | $_notificationMessage = $this->_lastPostNotificationMessage;
|
| 5278 | }
|
| 5279 |
|
| 5280 | $this->Notification->Dispatch($_notificationType, $_customEmailList, $_finalEmailPrefix . $this->GetProperty('subject'), $_notificationMessage, $this->_watcherCustomName, '', false, $_notificationEvent);
|
| 5281 |
|
| 5282 | return true;
|
| 5283 | }
|
| 5284 |
|
| 5285 | /**
|
| 5286 | * Dispatch a Notification via Pool (DESKTOP APP) on this Ticket
|
| 5287 | *
|
| 5288 | * @author Varun Shoor
|
| 5289 | * @param constant $_notificationType The Notification Type
|
| 5290 | * @param array $_customStaffIDList The Custom Staff ID List
|
| 5291 | * @param string $_notificationEvent (OPTIONAL) The Notification Event
|
| 5292 | * @return bool "true" on Success, "false" otherwise
|
| 5293 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5294 | */
|
| 5295 | public function DispatchNotificationPool($_notificationType, $_customStaffIDList, $_notificationEvent = '')
|
| 5296 | {
|
| 5297 | if (!$this->GetIsClassLoaded())
|
| 5298 | {
|
| 5299 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5300 |
|
| 5301 | return false;
|
| 5302 | }
|
| 5303 |
|
| 5304 | // $this->Notification->DispatchPool($_notificationType, $_customStaffIDList, $this->GetProperty('subject'), $this->_watchNotificationMessage, $this->_watcherCustomName);
|
| 5305 |
|
| 5306 | return true;
|
| 5307 | }
|
| 5308 |
|
| 5309 | /**
|
| 5310 | * Add to Attachments
|
| 5311 | *
|
| 5312 | * @author Varun Shoor
|
| 5313 | * @param string $_fileName The File Name
|
| 5314 | * @param string $_fileType The File Type
|
| 5315 | * @param string $_fileContents The File Contents
|
| 5316 | * @return bool "true" on Success, "false" otherwise
|
| 5317 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5318 | */
|
| 5319 | public function AddToAttachments($_fileName, $_fileType, $_fileContents)
|
| 5320 | {
|
| 5321 | if (!$this->GetIsClassLoaded())
|
| 5322 | {
|
| 5323 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5324 |
|
| 5325 | return false;
|
| 5326 | }
|
| 5327 |
|
| 5328 | if (!isset(self::$_attachmentsContainer[$this->GetTicketID()]))
|
| 5329 | {
|
| 5330 | self::$_attachmentsContainer[$this->GetTicketID()] = array();
|
| 5331 | }
|
| 5332 |
|
| 5333 | self::$_attachmentsContainer[$this->GetTicketID()][] = array('name' => $_fileName, 'type' => $_fileType, 'contents' => $_fileContents);
|
| 5334 |
|
| 5335 | return true;
|
| 5336 | }
|
| 5337 |
|
| 5338 | /**
|
| 5339 | * Retrieve the Attachments Container
|
| 5340 | *
|
| 5341 | * @author Varun Shoor
|
| 5342 | * @return array The Attachments Container
|
| 5343 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5344 | */
|
| 5345 | public function GetAttachments()
|
| 5346 | {
|
| 5347 | if (!$this->GetIsClassLoaded())
|
| 5348 | {
|
| 5349 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5350 |
|
| 5351 | return false;
|
| 5352 | }
|
| 5353 |
|
| 5354 | if (!isset(self::$_attachmentsContainer[$this->GetTicketID()]))
|
| 5355 | {
|
| 5356 | return false;
|
| 5357 | }
|
| 5358 |
|
| 5359 | return self::$_attachmentsContainer[$this->GetTicketID()];
|
| 5360 | }
|
| 5361 |
|
| 5362 | /**
|
| 5363 | * Add to Active Attachments (for notifications)
|
| 5364 | *
|
| 5365 | * @author Varun Shoor
|
| 5366 | * @param string $_fileName The File Name
|
| 5367 | * @param string $_fileType The File Type
|
| 5368 | * @param string $_fileContents The File Contents
|
| 5369 | * @return bool "true" on Success, "false" otherwise
|
| 5370 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5371 | */
|
| 5372 | public function AddToNotificationAttachments($_fileName, $_fileType, $_fileContents)
|
| 5373 | {
|
| 5374 | if (!$this->GetIsClassLoaded())
|
| 5375 | {
|
| 5376 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5377 |
|
| 5378 | return false;
|
| 5379 | }
|
| 5380 |
|
| 5381 | if (!isset(self::$_notificationAttachmentsContainer[$this->GetTicketID()]))
|
| 5382 | {
|
| 5383 | self::$_notificationAttachmentsContainer[$this->GetTicketID()] = array();
|
| 5384 | }
|
| 5385 |
|
| 5386 | self::$_notificationAttachmentsContainer[$this->GetTicketID()][] = array('name' => $_fileName, 'type' => $_fileType, 'contents' => $_fileContents);
|
| 5387 |
|
| 5388 | return true;
|
| 5389 | }
|
| 5390 |
|
| 5391 | /**
|
| 5392 | * Retrieve the Attachments Container
|
| 5393 | *
|
| 5394 | * @author Varun Shoor
|
| 5395 | * @return array The Attachments Container
|
| 5396 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5397 | */
|
| 5398 | public function GetNotificationAttachments()
|
| 5399 | {
|
| 5400 | if (!$this->GetIsClassLoaded())
|
| 5401 | {
|
| 5402 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5403 |
|
| 5404 | return false;
|
| 5405 | }
|
| 5406 |
|
| 5407 | if (!isset(self::$_notificationAttachmentsContainer[$this->GetTicketID()]))
|
| 5408 | {
|
| 5409 | return false;
|
| 5410 | }
|
| 5411 |
|
| 5412 | return self::$_notificationAttachmentsContainer[$this->GetTicketID()];
|
| 5413 | }
|
| 5414 |
|
| 5415 | /**
|
| 5416 | * Move the tickets to trash
|
| 5417 | *
|
| 5418 | * @author Varun Shoor
|
| 5419 | * @param array $_departmentIDList The Department ID List
|
| 5420 | * @return bool "true" on Success, "false" otherwise
|
| 5421 | */
|
| 5422 | static public function MoveToTrashBulk($_departmentIDList) {
|
| 5423 | $_SWIFT = SWIFT::GetInstance();
|
| 5424 |
|
| 5425 | if (!_is_array($_departmentIDList)) {
|
| 5426 | return false;
|
| 5427 | }
|
| 5428 |
|
| 5429 | /**
|
| 5430 | * BUG FIX - Parminder Singh
|
| 5431 | *
|
| 5432 | * SWIFT-1894: 'Trash' count does not clear the ticket count in case a department is deleted
|
| 5433 | *
|
| 5434 | */
|
| 5435 |
|
| 5436 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('departmentid' => '0', 'trasholddepartmentid' => '0'), 'UPDATE', "departmentid IN (" . BuildIN($_departmentIDList) . ") OR trasholddepartmentid IN (" . BuildIN($_departmentIDList) . ")");
|
| 5437 |
|
| 5438 | return true;
|
| 5439 | }
|
| 5440 |
|
| 5441 | /**
|
| 5442 | * Move the tickets status to trash
|
| 5443 | *
|
| 5444 | * @author Varun Shoor
|
| 5445 | * @param array $_ticketStatusIDList The Ticket Status ID List
|
| 5446 | * @return bool "true" on Success, "false" otherwise
|
| 5447 | */
|
| 5448 | static public function ChangeStatusToTrash($_ticketStatusIDList) {
|
| 5449 | $_SWIFT = SWIFT::GetInstance();
|
| 5450 |
|
| 5451 | if (!_is_array($_ticketStatusIDList)) {
|
| 5452 | return false;
|
| 5453 | }
|
| 5454 |
|
| 5455 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('ticketstatusid' => '0'), 'UPDATE', "ticketstatusid IN (" . BuildIN($_ticketStatusIDList) . ")");
|
| 5456 |
|
| 5457 | return true;
|
| 5458 | }
|
| 5459 |
|
| 5460 | /**
|
| 5461 | * Update the User record
|
| 5462 | *
|
| 5463 | * @author Varun Shoor
|
| 5464 | * @param int $_userID The User ID
|
| 5465 | * @return bool "true" on Success, "false" otherwise
|
| 5466 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5467 | */
|
| 5468 | public function UpdateUser($_userID)
|
| 5469 | {
|
| 5470 | if (!$this->GetIsClassLoaded())
|
| 5471 | {
|
| 5472 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5473 |
|
| 5474 | return false;
|
| 5475 | }
|
| 5476 |
|
| 5477 | $this->UpdatePool('userid', $_userID);
|
| 5478 | $this->ProcessUpdatePool();
|
| 5479 |
|
| 5480 | return true;
|
| 5481 | }
|
| 5482 |
|
| 5483 | /**
|
| 5484 | * Retrieve the last post contents
|
| 5485 | *
|
| 5486 | * @author Varun Shoor
|
| 5487 | * @return string The last post contents
|
| 5488 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5489 | */
|
| 5490 | public function GetLastPostContents()
|
| 5491 | {
|
| 5492 | if (!$this->GetIsClassLoaded())
|
| 5493 | {
|
| 5494 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5495 |
|
| 5496 | return false;
|
| 5497 | }
|
| 5498 |
|
| 5499 | try {
|
| 5500 | $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($this->GetProperty('lastpostid')));
|
| 5501 |
|
| 5502 | if ($_SWIFT_TicketPostObject->GetProperty('ticketid') == $this->GetTicketID())
|
| 5503 | {
|
| 5504 | return $_SWIFT_TicketPostObject->GetDisplayContents();
|
| 5505 | }
|
| 5506 |
|
| 5507 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 5508 |
|
| 5509 |
|
| 5510 | return '';
|
| 5511 | }
|
| 5512 |
|
| 5513 |
|
| 5514 |
|
| 5515 | return '';
|
| 5516 | }
|
| 5517 |
|
| 5518 | /**
|
| 5519 | * Retrieve the Ticket Post IDs linked with this ticket
|
| 5520 | *
|
| 5521 | * @author Varun Shoor
|
| 5522 | * @param bool $_ignoreForwardedPosts (OPTIONAL) Whether to ignore forwarded posts
|
| 5523 | * @return array The Ticket Post ID List
|
| 5524 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5525 | */
|
| 5526 | public function GetTicketPostIDList($_ignoreForwardedPosts = false)
|
| 5527 | {
|
| 5528 | if (!$this->GetIsClassLoaded())
|
| 5529 | {
|
| 5530 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5531 |
|
| 5532 | return false;
|
| 5533 | }
|
| 5534 |
|
| 5535 | $_ticketPostIDList = array();
|
| 5536 |
|
| 5537 | /*
|
| 5538 | * BUG FIX - Parminder Singh
|
| 5539 | *
|
| 5540 | * SWIFT-2286 Staff creates a ticket with attachment. When forward, attachment does not go with the ticket.
|
| 5541 | *
|
| 5542 | */
|
| 5543 | $this->Database->Query("SELECT ticketpostid, creator, emailto, isthirdparty FROM " . TABLE_PREFIX . "ticketposts WHERE ticketid = '" . intval($this->GetTicketID()) . "'");
|
| 5544 | while ($this->Database->NextRecord()) {
|
| 5545 | if ($_ignoreForwardedPosts == true && $this->Database->Record['creator'] == SWIFT_TicketPost::CREATOR_STAFF && $this->Database->Record['emailto'] != '' && $this->Database->Record['isthirdparty'] == '1')
|
| 5546 | {
|
| 5547 | continue;
|
| 5548 | }
|
| 5549 |
|
| 5550 | $_ticketPostIDList[] = $this->Database->Record['ticketpostid'];
|
| 5551 | }
|
| 5552 |
|
| 5553 | return $_ticketPostIDList;
|
| 5554 | }
|
| 5555 |
|
| 5556 | /**
|
| 5557 | * Update the Average Response Time
|
| 5558 | *
|
| 5559 | * @author Varun Shoor
|
| 5560 | * @param int $_responseTime
|
| 5561 | * @return bool "true" on Success, "false" otherwise
|
| 5562 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5563 | */
|
| 5564 | public function UpdateAverageResponseTime($_responseTime) {
|
| 5565 | if (!$this->GetIsClassLoaded()) {
|
| 5566 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5567 |
|
| 5568 | return false;
|
| 5569 | }
|
| 5570 |
|
| 5571 | $_oldHitCount = intval($this->GetProperty('averageresponsetimehits'));
|
| 5572 | $_oldAverageResponseTime = intval($this->GetProperty('averageresponsetime'));
|
| 5573 |
|
| 5574 | $_newHitCount = $_oldHitCount + 1;
|
| 5575 |
|
| 5576 | $_newAverageResponseTime = (($_oldAverageResponseTime*$_oldHitCount)+$_responseTime)/$_newHitCount;
|
| 5577 |
|
| 5578 | $this->UpdatePool('averageresponsetime', intval($_newAverageResponseTime));
|
| 5579 | $this->UpdatePool('averageresponsetimehits', intval($_newHitCount));
|
| 5580 |
|
| 5581 | return true;
|
| 5582 | }
|
| 5583 |
|
| 5584 | /**
|
| 5585 | * Update the Email Queue
|
| 5586 | *
|
| 5587 | * @author Varun Shoor
|
| 5588 | * @param int $_emailQueueID The Email Queue ID
|
| 5589 | * @return bool "true" on Success, "false" otherwise
|
| 5590 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5591 | */
|
| 5592 | public function UpdateQueue($_emailQueueIDIncoming) {
|
| 5593 | $_SWIFT = SWIFT::GetInstance();
|
| 5594 |
|
| 5595 | if (!$this->GetIsClassLoaded()) {
|
| 5596 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5597 |
|
| 5598 | return false;
|
| 5599 | } else if ($this->GetProperty('emailqueueid') == $_emailQueueIDIncoming) {
|
| 5600 | return true;
|
| 5601 | }
|
| 5602 |
|
| 5603 | $_emailQueueCache = $this->Cache->Get('queuecache');
|
| 5604 | $_templateGroupCache = $this->Cache->Get('templategroupcache');
|
| 5605 | $_emailQueueID = 0;
|
| 5606 | if (isset($_emailQueueCache['list'][$_emailQueueIDIncoming]))
|
| 5607 | {
|
| 5608 | $_emailQueueID = $_emailQueueIDIncoming;
|
| 5609 | }
|
| 5610 |
|
| 5611 | $_emailQueueContainer = false;
|
| 5612 | if (isset($_emailQueueCache['list'][$_emailQueueID]))
|
| 5613 | {
|
| 5614 | $_emailQueueContainer = $_emailQueueCache['list'][$_emailQueueID];
|
| 5615 | }
|
| 5616 |
|
| 5617 | $_templateGroupID = SWIFT_TemplateGroup::GetDefaultGroupID();
|
| 5618 |
|
| 5619 | if (_is_array($_emailQueueContainer) && isset($_templateGroupCache[$_emailQueueContainer['tgroupid']]))
|
| 5620 | {
|
| 5621 | $_templateGroupID = $_emailQueueContainer['tgroupid'];
|
| 5622 | }
|
| 5623 |
|
| 5624 | $this->UpdatePool('emailqueueid', intval($_emailQueueID));
|
| 5625 | $this->UpdatePool('tgroupid', intval($_templateGroupID));
|
| 5626 |
|
| 5627 | return true;
|
| 5628 | }
|
| 5629 |
|
| 5630 | /**
|
| 5631 | * Load the Last Post Notification Message
|
| 5632 | *
|
| 5633 | * @author Varun Shoor
|
| 5634 | * @return bool "true" on Success, "false" otherwise
|
| 5635 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5636 | */
|
| 5637 | protected function LoadLastPostNotificationMessage() {
|
| 5638 | if (!$this->GetIsClassLoaded()) {
|
| 5639 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5640 |
|
| 5641 | return false;
|
| 5642 | }
|
| 5643 |
|
| 5644 | try {
|
| 5645 | $_SWIFT_TicketPostObject = new SWIFT_TicketPost(new SWIFT_DataID($this->GetProperty('lastpostid')));
|
| 5646 | $this->_lastPostNotificationMessage = $_SWIFT_TicketPostObject->GetProperty('contents');
|
| 5647 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 5648 |
|
| 5649 | return false;
|
| 5650 | }
|
| 5651 |
|
| 5652 | return true;
|
| 5653 | }
|
| 5654 |
|
| 5655 | /**
|
| 5656 | * Retrieve the Ticket ID Object on the provided Ticket ID
|
| 5657 | *
|
| 5658 | * @author Varun Shoor
|
| 5659 | * @param mixed $_ticketID The Numeric or Mask Ticket ID
|
| 5660 | * @return SWIFT_Ticket
|
| 5661 | */
|
| 5662 | static public function GetObjectOnID($_ticketID)
|
| 5663 | {
|
| 5664 | $_SWIFT = SWIFT::GetInstance();
|
| 5665 |
|
| 5666 | $_SWIFT_TicketObject = false;
|
| 5667 |
|
| 5668 | if (is_numeric($_ticketID)) {
|
| 5669 | try {
|
| 5670 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
|
| 5671 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 5672 | }
|
| 5673 | } else {
|
| 5674 | $_ticketID = SWIFT_Ticket::GetTicketIDFromMask($_ticketID);
|
| 5675 | if (empty($_ticketID)) {
|
| 5676 | return false;
|
| 5677 | }
|
| 5678 |
|
| 5679 | try {
|
| 5680 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataID($_ticketID));
|
| 5681 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 5682 | }
|
| 5683 | }
|
| 5684 |
|
| 5685 | if ($_SWIFT_TicketObject instanceof SWIFT_Ticket && $_SWIFT_TicketObject->GetIsClassLoaded()) {
|
| 5686 | return $_SWIFT_TicketObject;
|
| 5687 | }
|
| 5688 |
|
| 5689 | // By now we couldnt get the ticket object, we have to lookup the merge logs
|
| 5690 | $_mergeTicketID = false;
|
| 5691 | if (is_numeric($_ticketID)) {
|
| 5692 | $_mergeTicketID = SWIFT_TicketMergeLog::GetTicketIDFromMergedTicketID($_ticketID);
|
| 5693 | } else {
|
| 5694 | $_mergeTicketID = SWIFT_TicketMergeLog::GetTicketIDFromMergedTicketMaskID($_ticketID);
|
| 5695 | }
|
| 5696 |
|
| 5697 | if (!empty($_mergeTicketID)) {
|
| 5698 | try
|
| 5699 | {
|
| 5700 | $_SWIFT_TicketObject = new SWIFT_Ticket(new SWIFT_DataID($_mergeTicketID));
|
| 5701 | } catch (SWIFT_Exception $_SWIFT_ExceptionObject) {
|
| 5702 | }
|
| 5703 |
|
| 5704 | if ($_SWIFT_TicketObject instanceof SWIFT_Ticket && $_SWIFT_TicketObject->GetIsClassLoaded())
|
| 5705 | {
|
| 5706 | return $_SWIFT_TicketObject;
|
| 5707 | }
|
| 5708 | }
|
| 5709 |
|
| 5710 | return false;
|
| 5711 | }
|
| 5712 |
|
| 5713 | /**
|
| 5714 | * Mark the Tickets as Pending Auto Closure
|
| 5715 | *
|
| 5716 | * @author Varun Shoor
|
| 5717 | * @param array $_ticketIDList
|
| 5718 | * @param SWIFT_AutoCloseRule $_SWIFT_AutoCloseRuleObject
|
| 5719 | * @return bool "true" on Success, "false" otherwise
|
| 5720 | * @throws SWIFT_Exception If Invalid Data is Provided
|
| 5721 | */
|
| 5722 | static public function MarkAsAutoClosePending($_ticketIDList, SWIFT_AutoCloseRule $_SWIFT_AutoCloseRuleObject)
|
| 5723 | {
|
| 5724 | $_SWIFT = SWIFT::GetInstance();
|
| 5725 |
|
| 5726 | if (!$_SWIFT_AutoCloseRuleObject instanceof SWIFT_AutoCloseRule || !$_SWIFT_AutoCloseRuleObject->GetIsClassLoaded()) {
|
| 5727 | throw new SWIFT_Exception(SWIFT_INVALIDDATA);
|
| 5728 | }
|
| 5729 |
|
| 5730 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('isautoclosed' => '0', 'autocloseruleid' => intval($_SWIFT_AutoCloseRuleObject->GetAutoCloseRuleID()),
|
| 5731 | 'autoclosestatus' => self::AUTOCLOSESTATUS_PENDING, 'autoclosetimeline' => DATENOW), 'UPDATE', "ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 5732 |
|
| 5733 | // Do we need to send the pending notification?
|
| 5734 | if ($_SWIFT_AutoCloseRuleObject->GetProperty('sendpendingnotification') == '0') {
|
| 5735 | return true;
|
| 5736 | }
|
| 5737 |
|
| 5738 | $_ticketsContainer = array();
|
| 5739 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets
|
| 5740 | WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 5741 | while ($_SWIFT->Database->NextRecord()) {
|
| 5742 | $_ticketsContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 5743 | }
|
| 5744 |
|
| 5745 | foreach ($_ticketsContainer as $_SWIFT_TicketObject) {
|
| 5746 | if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
|
| 5747 | continue;
|
| 5748 | }
|
| 5749 |
|
| 5750 | $_SWIFT_TicketEmailDispatch = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
|
| 5751 | $_SWIFT_TicketEmailDispatch->DispatchPendingAutoClose($_SWIFT_AutoCloseRuleObject);
|
| 5752 | }
|
| 5753 |
|
| 5754 | return true;
|
| 5755 | }
|
| 5756 |
|
| 5757 | /**
|
| 5758 | * Mark the Tickets as Closed via Auto Closed
|
| 5759 | *
|
| 5760 | * @author Varun Shoor
|
| 5761 | * @param array $_ticketIDList
|
| 5762 | * @param SWIFT_AutoCloseRule $_SWIFT_AutoCloseRuleObject
|
| 5763 | * @return bool "true" on Success, "false" otherwise
|
| 5764 | * @throws SWIFT_Exception If Invalid Data is Provided
|
| 5765 | */
|
| 5766 | static public function MarkAsAutoClosed($_ticketIDList, SWIFT_AutoCloseRule $_SWIFT_AutoCloseRuleObject)
|
| 5767 | {
|
| 5768 | $_SWIFT = SWIFT::GetInstance();
|
| 5769 |
|
| 5770 | if (!$_SWIFT_AutoCloseRuleObject instanceof SWIFT_AutoCloseRule || !$_SWIFT_AutoCloseRuleObject->GetIsClassLoaded()) {
|
| 5771 | throw new SWIFT_Exception(SWIFT_INVALIDDATA);
|
| 5772 | }
|
| 5773 |
|
| 5774 | $_ticketsContainer = array();
|
| 5775 | $_SWIFT->Database->Query("SELECT * FROM " . TABLE_PREFIX . "tickets
|
| 5776 | WHERE ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 5777 | while ($_SWIFT->Database->NextRecord()) {
|
| 5778 | $_ticketsContainer[$_SWIFT->Database->Record['ticketid']] = new SWIFT_Ticket(new SWIFT_DataStore($_SWIFT->Database->Record));
|
| 5779 | }
|
| 5780 |
|
| 5781 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array('isautoclosed' => '1', 'autocloseruleid' => intval($_SWIFT_AutoCloseRuleObject->GetAutoCloseRuleID()),
|
| 5782 | 'autoclosestatus' => self::AUTOCLOSESTATUS_CLOSED, 'autoclosetimeline' => DATENOW), 'UPDATE', "ticketid IN (" . BuildIN($_ticketIDList) . ")");
|
| 5783 |
|
| 5784 | foreach ($_ticketsContainer as $_SWIFT_TicketObject) {
|
| 5785 | if (!$_SWIFT_TicketObject instanceof SWIFT_Ticket || !$_SWIFT_TicketObject->GetIsClassLoaded()) {
|
| 5786 | continue;
|
| 5787 | }
|
| 5788 |
|
| 5789 | $_SWIFT_TicketObject->SetStatus($_SWIFT_AutoCloseRuleObject->GetProperty('targetticketstatusid'), true, $_SWIFT_AutoCloseRuleObject->GetProperty('suppresssurveyemail'));
|
| 5790 |
|
| 5791 | // Do we need to send the final notification?
|
| 5792 | if ($_SWIFT_AutoCloseRuleObject->GetProperty('sendfinalnotification') == '1') {
|
| 5793 | $_SWIFT_TicketEmailDispatch = new SWIFT_TicketEmailDispatch($_SWIFT_TicketObject);
|
| 5794 | $_SWIFT_TicketEmailDispatch->DispatchFinalAutoClose($_SWIFT_AutoCloseRuleObject);
|
| 5795 | }
|
| 5796 |
|
| 5797 | $_SWIFT_TicketObject->RebuildProperties();
|
| 5798 | }
|
| 5799 |
|
| 5800 | return true;
|
| 5801 | }
|
| 5802 |
|
| 5803 | /**
|
| 5804 | * Retrieve the from email with proper suffix
|
| 5805 | *
|
| 5806 | * @author Varun Shoor
|
| 5807 | * @param string $_fromEmailAddress
|
| 5808 | * @param constant $_mailType
|
| 5809 | * @return bool "true" on Success, "false" otherwise
|
| 5810 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5811 | */
|
| 5812 | public function RetrieveFromEmailWithSuffix($_fromEmailAddress, $_mailType)
|
| 5813 | {
|
| 5814 | if (!$this->GetIsClassLoaded()) {
|
| 5815 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5816 |
|
| 5817 | return false;
|
| 5818 | }
|
| 5819 |
|
| 5820 | // Have we enabled clean subjects?
|
| 5821 | if ($this->Settings->Get('t_cleanmailsubjects') != '1') {
|
| 5822 | return $_fromEmailAddress;
|
| 5823 | }
|
| 5824 |
|
| 5825 | $_finalReturnEmailAddress = '';
|
| 5826 |
|
| 5827 | $_matches = array();
|
| 5828 | if (preg_match('/^(.*?)@(.*?)$/i', $_fromEmailAddress, $_matches)) {
|
| 5829 | $_dispatchType = 'r';
|
| 5830 | if ($_mailType == self::MAIL_NOTIFICATION) {
|
| 5831 | $_dispatchType = 'a';
|
| 5832 | } else if ($_mailType == self::MAIL_THIRDPARTY) {
|
| 5833 | $_dispatchType = 't';
|
| 5834 | }
|
| 5835 |
|
| 5836 | $_hashChunk = substr($this->GetProperty('tickethash'), 0, 5);
|
| 5837 |
|
| 5838 | $_finalReturnEmailAddress = $_matches[1] . '+' . $_dispatchType . '.' . $_hashChunk . '.' . $this->GetTicketID() . '@' . $_matches[2];
|
| 5839 |
|
| 5840 | } else {
|
| 5841 | return $_fromEmailAddress;
|
| 5842 | }
|
| 5843 |
|
| 5844 |
|
| 5845 | return $_finalReturnEmailAddress;
|
| 5846 | }
|
| 5847 |
|
| 5848 | /**
|
| 5849 | * Reset SLA Calculations
|
| 5850 | *
|
| 5851 | * @author Mahesh Salaria
|
| 5852 | * @return bool "true" on Success, "false" otherwise
|
| 5853 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5854 | */
|
| 5855 | public function ResetSLA()
|
| 5856 | {
|
| 5857 | if (!$this->GetIsClassLoaded()) {
|
| 5858 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5859 |
|
| 5860 | return false;
|
| 5861 | }
|
| 5862 |
|
| 5863 | $this->_noSLACalculation = false;
|
| 5864 |
|
| 5865 | return true;
|
| 5866 | }
|
| 5867 |
|
| 5868 | /**
|
| 5869 | * Return the total ticket count
|
| 5870 | *
|
| 5871 | * @author Varun Shoor
|
| 5872 | * @return int The Total Ticket Count
|
| 5873 | */
|
| 5874 | static public function GetTicketCount()
|
| 5875 | {
|
| 5876 | $_SWIFT = SWIFT::GetInstance();
|
| 5877 |
|
| 5878 | $_ticketCountContainer = $_SWIFT->Database->QueryFetch("SELECT COUNT(*) AS totalitems FROM " . TABLE_PREFIX . "tickets");
|
| 5879 | if (isset($_ticketCountContainer['totalitems']) && !empty($_ticketCountContainer['totalitems'])) {
|
| 5880 | return intval($_ticketCountContainer['totalitems']);
|
| 5881 | }
|
| 5882 |
|
| 5883 | return 0;
|
| 5884 | }
|
| 5885 |
|
| 5886 | /**
|
| 5887 | * Update the global property on all tickets, used to update stuff like departmentname etc.
|
| 5888 | *
|
| 5889 | * @author Varun Shoor
|
| 5890 | * @param string $_updateFieldName
|
| 5891 | * @param string $_updateFieldValue
|
| 5892 | * @param string $_whereFieldName
|
| 5893 | * @param string $_whereFieldValue
|
| 5894 | * @return bool "true" on Success, "false" otherwise
|
| 5895 | */
|
| 5896 | static public function UpdateGlobalProperty($_updateFieldName, $_updateFieldValue, $_whereFieldName, $_whereFieldValue)
|
| 5897 | {
|
| 5898 | $_SWIFT = SWIFT::GetInstance();
|
| 5899 |
|
| 5900 | $_updateFieldName = $_SWIFT->Database->Escape($_updateFieldName);
|
| 5901 | $_whereFieldName = $_SWIFT->Database->Escape($_whereFieldName);
|
| 5902 | $_whereFieldValue = intval($_whereFieldValue); // Expected to be always int
|
| 5903 |
|
| 5904 | $_SWIFT->Database->AutoExecute(TABLE_PREFIX . 'tickets', array($_updateFieldName => $_updateFieldValue), 'UPDATE', $_whereFieldName . " = '" . $_whereFieldValue . "'");
|
| 5905 |
|
| 5906 | return true;
|
| 5907 | }
|
| 5908 |
|
| 5909 | /**
|
| 5910 | * Set alert rules for ticket
|
| 5911 | *
|
| 5912 | * @author Ruchi Kothari
|
| 5913 | * @param bool $_noAlerts Alert rules
|
| 5914 | * @return bool "true" on Success, "false" otherwise
|
| 5915 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5916 | */
|
| 5917 | public function SetNoAlerts($_noAlerts)
|
| 5918 | {
|
| 5919 | if (!$this->GetIsClassLoaded()) {
|
| 5920 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5921 |
|
| 5922 | return false;
|
| 5923 | }
|
| 5924 |
|
| 5925 | $this->_noAlerts = $_noAlerts;
|
| 5926 | }
|
| 5927 |
|
| 5928 | /**
|
| 5929 | * Get alert rules for ticket
|
| 5930 | *
|
| 5931 | * @author Ruchi Kothari
|
| 5932 | * @return bool Alert rules status
|
| 5933 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5934 | */
|
| 5935 | public function GetNoAlerts()
|
| 5936 | {
|
| 5937 | if (!$this->GetIsClassLoaded()) {
|
| 5938 | throw new SWIFT_Exception(SWIFT_CLASSNOTLOADED);
|
| 5939 |
|
| 5940 | return false;
|
| 5941 | }
|
| 5942 |
|
| 5943 | return $this->_noAlerts;
|
| 5944 | }
|
| 5945 |
|
| 5946 | /**
|
| 5947 | * Set Old Ticket properties. This array is used to Keep previous ticket properties after execution.
|
| 5948 | *
|
| 5949 | * @author Mahesh Salaria
|
| 5950 | * @return bool "true" on Success, "false" otherwise
|
| 5951 | * @throws SWIFT_Ticket_Exception If the Class is not Loaded
|
| 5952 | */
|
| 5953 | public function SetOldTicketProperties()
|
| 5954 | {
|
| 5955 | if (!$this->GetIsClassLoaded()) {
|
| 5956 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 5957 |
|
| 5958 | return false;
|
| 5959 | }
|
| 5960 |
|
| 5961 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETSTATUS] = $this->GetProperty('ticketstatusid');
|
| 5962 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETPRIORITY] = $this->GetProperty('priorityid');
|
| 5963 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETDEPARTMENT] = $this->GetProperty('departmentid');
|
| 5964 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETOWNER] = intval($this->GetProperty('ownerstaffid'));
|
| 5965 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETEMAILQUEUE] = $this->GetProperty('emailqueueid');
|
| 5966 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETFLAGTYPE] = $this->GetProperty('flagtype');
|
| 5967 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETCREATOR] = $this->GetProperty('creator');
|
| 5968 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETUSERGROUP] = $this->GetUserGroupID();
|
| 5969 |
|
| 5970 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETFULLNAME] = $this->GetProperty('fullname');
|
| 5971 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETEMAIL] = $this->GetProperty('email');
|
| 5972 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETLASTREPLIER] = $this->GetProperty('lastreplier');
|
| 5973 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETSUBJECT] = $this->GetProperty('subject');
|
| 5974 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETCHARSET] = $this->GetProperty('charset');
|
| 5975 |
|
| 5976 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETTEMPLATEGROUP] = $this->GetProperty('tgroupid');
|
| 5977 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETISRESOLVED] = $this->GetProperty('isresolved');
|
| 5978 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETTYPE] = intval($this->GetProperty('tickettypeid'));
|
| 5979 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETWASREOPENED] = $this->GetProperty('wasreopened');
|
| 5980 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETTOTALREPLIES] = $this->GetProperty('totalreplies');
|
| 5981 | $this->_oldTicketProperties[SWIFT_SLA::SLA_TICKETBAYESCATEGORY] = $this->GetProperty('bayescategoryid');
|
| 5982 |
|
| 5983 | return true;
|
| 5984 | }
|
| 5985 |
|
| 5986 | /**
|
| 5987 | * Get Old ticket properties
|
| 5988 | *
|
| 5989 | * @author Mahesh Salaria
|
| 5990 | * @return array of old ticket properties
|
| 5991 | * @throws SWIFT_Exception If the Class is not Loaded
|
| 5992 | */
|
| 5993 | public function GetOldTicketProperties()
|
| 5994 | {
|
| 5995 | if (!$this->GetIsClassLoaded()) {
|
| 5996 | throw new SWIFT_Ticket_Exception(SWIFT_CLASSNOTLOADED);
|
| 5997 |
|
| 5998 | return false;
|
| 5999 | }
|
| 6000 |
|
| 6001 | return $this->_oldTicketProperties;
|
| 6002 | }
|
| 6003 | } |