1<?php 2/********************************************************************* 3 class.config.php 4 5 osTicket config info manager. 6 7 Peter Rotich <peter@osticket.com> 8 Copyright (c) 2006-2013 osTicket 9 http://www.osticket.com 10 11 Released under the GNU General Public License WITHOUT ANY WARRANTY. 12 See LICENSE.TXT for details. 13 14 vim: expandtab sw=4 ts=4 sts=4: 15**********************************************************************/ 16require_once INCLUDE_DIR . 'class.orm.php'; 17 18class Config { 19 var $config = array(); 20 21 var $section = null; # Default namespace ('core') 22 var $table = CONFIG_TABLE; # Table name (with prefix) 23 var $section_column = 'namespace'; # namespace column name 24 25 var $session = null; # Session-backed configuration 26 27 # Defaults for this configuration. If settings don't exist in the 28 # database yet, the ->getInfo() method will not include the (default) 29 # values in the returned array. $defaults allows developers to define 30 # new settings and the corresponding default values. 31 var $defaults = array(); # List of default values 32 33 function __construct($section=null, $defaults=array()) { 34 if ($section) 35 $this->section = $section; 36 37 if ($this->section === null) 38 return false; 39 40 if ($defaults) 41 $this->defaults = $defaults; 42 43 if (isset($_SESSION['cfg:'.$this->section])) 44 $this->session = &$_SESSION['cfg:'.$this->section]; 45 46 $this->load(); 47 } 48 49 function load() { 50 foreach ($this->items() as $I) 51 $this->config[$I->key] = $I; 52 } 53 54 function getNamespace() { 55 return $this->section; 56 } 57 58 function getInfo() { 59 $info = $this->defaults; 60 foreach ($this->config as $key=>$item) 61 $info[$key] = $item->value; 62 return $info; 63 } 64 65 function get($key, $default=null) { 66 if (isset($this->session) && isset($this->session[$key])) 67 return $this->session[$key]; 68 elseif (isset($this->config[$key])) 69 return $this->config[$key]->value; 70 elseif (isset($this->defaults[$key])) 71 return $this->defaults[$key]; 72 73 return $default; 74 } 75 76 function exists($key) { 77 return $this->get($key, null) ? true : false; 78 } 79 80 function set($key, $value) { 81 return ($this->update($key, $value)) ? $value : null; 82 } 83 84 function persist($key, $value) { 85 if (!isset($this->session)) { 86 $this->session = &$_SESSION['cfg:'.$this->section]; 87 $this->session = array(); 88 } 89 $this->session[$key] = $value; 90 return true; 91 } 92 93 function lastModified($key) { 94 if (isset($this->config[$key])) 95 return $this->config[$key]->updated; 96 97 return false; 98 } 99 100 function create($key, $value) { 101 $item = new ConfigItem([ 102 $this->section_column => $this->section, 103 'key' => $key, 104 'value' => $value, 105 ]); 106 if (!$item->save()) 107 return false; 108 109 return true; 110 } 111 112 function update($key, $value) { 113 if (!$key) 114 return false; 115 elseif (!isset($this->config[$key])) 116 return $this->create($key, $value); 117 118 $item = $this->config[$key]; 119 $before = $item->value; 120 $item->value = $value; 121 122 if ($before != $item->value) { 123 $type = array('type' => 'edited', 'key' => $item->ht['key']); 124 Signal::send('object.edited', $item, $type); 125 } 126 127 return $item->save(); 128 } 129 130 function updateAll($updates) { 131 foreach ($updates as $key=>$value) 132 if (!$this->update($key, $value)) 133 return false; 134 return true; 135 } 136 137 function destroy() { 138 unset($this->session); 139 return $this->items()->delete() > 0; 140 } 141 142 function items() { 143 return ConfigItem::items($this->section, $this->section_column); 144 } 145} 146 147class ConfigItem 148extends VerySimpleModel { 149 static $meta = array( 150 'table' => CONFIG_TABLE, 151 'pk' => array('id'), 152 ); 153 154 static function items($namespace, $column='namespace') { 155 156 $items = static::objects() 157 ->filter([$column => $namespace]); 158 159 try { 160 count($items); 161 } 162 catch (InconsistentModelException $ex) { 163 // Pending upgrade ?? 164 $items = array(); 165 } 166 167 return $items; 168 } 169 170 function save($refetch=false) { 171 if ($this->dirty) 172 $this->updated = SqlFunction::NOW(); 173 return parent::save($this->dirty || $refetch); 174 } 175 176 // Clean password reset tokens that have expired 177 static function cleanPwResets() { 178 global $cfg; 179 180 if (!$cfg || !($period = $cfg->getPwResetWindow())) // In seconds 181 return false; 182 183 return ConfigItem::objects() 184 ->filter(array( 185 'namespace' => 'pwreset', 186 'updated__lt' => SqlFunction::NOW()->minus(SqlInterval::SECOND($period)), 187 ))->delete(); 188 } 189 190 function getConfigsByNamespace($namespace=false, $key, $value=false) { 191 $filter = array(); 192 193 $filter['key'] = $key; 194 195 if ($namespace) 196 $filter['namespace'] = $namespace; 197 198 if ($value) 199 $filter['value'] = $value; 200 201 $token = ConfigItem::objects() 202 ->filter($filter); 203 204 return $namespace ? $token[0] : $token; 205 } 206} 207 208class OsticketConfig extends Config { 209 var $table = CONFIG_TABLE; 210 var $section = 'core'; 211 212 var $defaultDept; //Default Department 213 var $defaultSLA; //Default SLA 214 var $defaultSchedule; // Default Schedule 215 var $defaultEmail; //Default Email 216 var $alertEmail; //Alert Email 217 var $defaultSMTPEmail; //Default SMTP Email 218 219 var $defaults = array( 220 'allow_pw_reset' => true, 221 'pw_reset_window' => 30, 222 'enable_richtext' => true, 223 'enable_avatars' => true, 224 'allow_attachments' => true, 225 'agent_name_format' => 'full', # First Last 226 'client_name_format' => 'original', # As entered 227 'auto_claim_tickets'=> true, 228 'auto_refer_closed' => true, 229 'collaborator_ticket_visibility' => true, 230 'disable_agent_collabs' => false, 231 'require_topic_to_close' => false, 232 'system_language' => 'en_US', 233 'default_storage_bk' => 'D', 234 'message_autoresponder_collabs' => true, 235 'add_email_collabs' => true, 236 'clients_only' => false, 237 'client_registration' => 'closed', 238 'accept_unregistered_email' => true, 239 'default_help_topic' => 0, 240 'help_topic_sort_mode' => 'a', 241 'client_verify_email' => 1, 242 'allow_auth_tokens' => 1, 243 'verify_email_addrs' => 1, 244 'client_avatar' => 'gravatar.mm', 245 'agent_avatar' => 'gravatar.mm', 246 'ticket_lock' => 2, // Lock on activity 247 'max_open_tickets' => 0, 248 'files_req_auth' => 1, 249 'force_https' => '', 250 'allow_external_images' => 0, 251 ); 252 253 function __construct($section=null) { 254 parent::__construct($section); 255 256 if (count($this->config) == 0) { 257 // Fallback for osticket < 1.7@852ca89e 258 $sql='SELECT * FROM '.$this->table.' WHERE id = 1'; 259 $meta = ConfigItem::getMeta(); 260 if (($res=db_query($sql)) && db_num_rows($res)) 261 foreach (db_fetch_array($res) as $key=>$value) 262 $this->config[$key] = $meta->newInstance(array('value'=>$value)); 263 } 264 265 return true; 266 } 267 268 function lastModified($key=false) { 269 return max(array_map(array('parent', 'lastModified'), 270 array_keys($this->config))); 271 } 272 273 function isHelpDeskOffline() { 274 return !$this->isOnline(); 275 } 276 277 function isHelpDeskOnline() { 278 return $this->isOnline(); 279 } 280 281 function isOnline() { 282 return ($this->get('isonline')); 283 } 284 285 function isKnowledgebaseEnabled() { 286 global $thisclient; 287 288 if ($this->get('restrict_kb', false) 289 && (!$thisclient || $thisclient->isGuest()) 290 ) { 291 return false; 292 } 293 require_once(INCLUDE_DIR.'class.faq.php'); 294 return ($this->get('enable_kb') && FAQ::countPublishedFAQs()); 295 } 296 297 function isCannedResponseEnabled() { 298 return $this->get('enable_premade'); 299 } 300 301 function getVersion() { 302 return THIS_VERSION; 303 } 304 305 function getSchemaSignature($section=null) { 306 307 if ((!$section || $section == $this->section) 308 && ($v=$this->get('schema_signature'))) 309 return $v; 310 311 // 1.7 after namespaced configuration, other namespace 312 if ($section) { 313 $sql='SELECT value FROM '.$this->table 314 .' WHERE `key` = "schema_signature" and namespace='.db_input($section); 315 if (($res=db_query($sql, false)) && db_num_rows($res)) 316 return db_result($res); 317 } 318 319 // 1.7 before namespaced configuration 320 $sql='SELECT `schema_signature` FROM '.$this->table 321 .' WHERE id=1'; 322 if (($res=db_query($sql, false)) && db_num_rows($res)) 323 return db_result($res); 324 325 // old version 1.6 326 return md5(self::getDBVersion()); 327 } 328 329 function getDbTimezone() { 330 if (!$this->exists('db_timezone')) { 331 require_once INCLUDE_DIR . 'class.timezone.php'; 332 $this->persist('db_timezone', DbTimezone::determine()); 333 } 334 return $this->get('db_timezone'); 335 } 336 337 function getDefaultTimezone() { 338 return $this->get('default_timezone'); 339 } 340 341 function getTimezone($user=false) { 342 global $thisstaff, $thisclient; 343 344 $user = $user ?: $thisstaff; 345 346 if (!$user && $thisclient && is_callable(array($thisclient, 'getTimezone'))) 347 $user = $thisclient; 348 349 if ($user) 350 $zone = $user->getTimezone(); 351 352 if (!$zone) 353 $zone = $this->get('default_timezone'); 354 355 if (!$zone) 356 $zone = ini_get('date.timezone'); 357 358 return $zone; 359 } 360 361 function getDefaultLocale() { 362 return $this->get('default_locale'); 363 } 364 365 /* Date & Time Formats */ 366 function getTimeFormat($propogate=false) { 367 global $cfg; 368 369 if ($this->get('date_formats') == 'custom') 370 return $this->get('time_format'); 371 372 if ($propogate) { 373 $format = 'h:i a'; // Default 374 if (class_exists('IntlDateFormatter')) { 375 $formatter = new IntlDateFormatter( 376 Internationalization::getCurrentLocale(), 377 IntlDateFormatter::NONE, 378 IntlDateFormatter::SHORT, 379 $this->getTimezone(), 380 IntlDateFormatter::GREGORIAN 381 ); 382 $format = $formatter->getPattern(); 383 } 384 // Check if we're forcing 24 hrs format 385 if ($cfg && $cfg->isForce24HourTime() && $format) 386 $format = trim(str_replace(array('a', 'h'), array('', 'H'), 387 $format)); 388 return $format; 389 } 390 391 return ''; 392 } 393 394 function isForce24HourTime() { 395 return $this->get('date_formats') == '24'; 396 } 397 398 /** 399 * getDateFormat 400 * 401 * Retrieve the current date format for the system, as a string, and in 402 * the intl (icu) format. 403 * 404 * Parameters: 405 * $propogate - (boolean:default=false), if set and the configuration 406 * indicates default date and time formats (ie. not custom), then 407 * the intl date formatter will be queried to find the pattern used 408 * internally for the current locale settings. 409 */ 410 function getDateFormat($propogate=false) { 411 if ($this->get('date_formats') == 'custom') 412 return $this->get('date_format'); 413 if ($propogate) { 414 if (class_exists('IntlDateFormatter')) { 415 $formatter = new IntlDateFormatter( 416 Internationalization::getCurrentLocale(), 417 IntlDateFormatter::SHORT, 418 IntlDateFormatter::NONE, 419 $this->getTimezone(), 420 IntlDateFormatter::GREGORIAN 421 ); 422 return $formatter->getPattern(); 423 } 424 // Use a standard 425 return 'y-M-d'; 426 } 427 return ''; 428 } 429 430 function getDateTimeFormat() { 431 if ($this->get('date_formats') == 'custom') 432 return $this->get('datetime_format'); 433 434 if (class_exists('IntlDateFormatter')) 435 return sprintf('%s %s', $this->getDateFormat(true), 436 $this->getTimeFormat(true)); 437 438 return ''; 439 } 440 441 function getDayDateTimeFormat() { 442 if ($this->get('date_formats') == 'custom') 443 return $this->get('daydatetime_format'); 444 return ''; 445 } 446 447 function getConfigInfo() { 448 return $this->getInfo(); 449 } 450 451 function getTitle() { 452 return $this->get('helpdesk_title'); 453 } 454 455 function getUrl() { 456 return $this->get('helpdesk_url'); 457 } 458 459 function getBaseUrl() { //Same as above with no trailing slash. 460 return rtrim($this->getUrl(),'/'); 461 } 462 463 function getPageSize() { 464 return $this->get('max_page_size'); 465 } 466 467 function getGracePeriod() { 468 return $this->get('overdue_grace_period'); 469 } 470 471 // This is here for legacy reasons - default osTicket Password Policy 472 // uses it, if previously set. 473 function getPasswdResetPeriod() { 474 return $this->get('passwd_reset_period'); 475 } 476 477 478 function getStaffPasswordPolicy() { 479 return $this->get('agent_passwd_policy'); 480 } 481 482 function getClientPasswordPolicy() { 483 return $this->get('client_passwd_policy'); 484 } 485 486 function require2FAForAgents() { 487 return $this->get('require_agent_2fa'); 488 } 489 490 function isRichTextEnabled() { 491 return $this->get('enable_richtext'); 492 } 493 494 function getAllowIframes() { 495 return str_replace(array(', ', ','), array(' ', ' '), $this->get('allow_iframes')) ?: "'self'"; 496 } 497 498 function getIframeWhitelist() { 499 $whitelist = array_filter(explode(',', str_replace(' ', '', $this->get('embedded_domain_whitelist')))); 500 501 return !empty($whitelist) ? $whitelist : null; 502 } 503 504 function getACL() { 505 if (!($acl = $this->get('acl'))) 506 return null; 507 508 return explode(',', str_replace(' ', '', $acl)); 509 } 510 511 function getACLBackendOpts() { 512 return array( 513 0 => __('Disabled'), 514 1 => __('All'), 515 2 => __('Client Portal'), 516 3 => __('Staff Panel') 517 ); 518 } 519 520 function getACLBackend() { 521 return $this->get('acl_backend') ?: 0; 522 } 523 524 function isAvatarsEnabled() { 525 return $this->get('enable_avatars'); 526 } 527 528 function isTicketLockEnabled() { 529 return (($this->getTicketLockMode() != Lock::MODE_DISABLED) 530 && $this->getLockTime()); 531 } 532 533 function getClientTimeout() { 534 return $this->getClientSessionTimeout(); 535 } 536 537 function getClientSessionTimeout() { 538 return $this->get('client_session_timeout')*60; 539 } 540 541 function getClientLoginTimeout() { 542 return $this->get('client_login_timeout')*60; 543 } 544 545 function getClientMaxLogins() { 546 return $this->get('client_max_logins'); 547 } 548 549 function getStaffTimeout() { 550 return $this->getStaffSessionTimeout(); 551 } 552 553 function getStaffSessionTimeout() { 554 return $this->get('staff_session_timeout')*60; 555 } 556 557 function getStaffLoginTimeout() { 558 return $this->get('staff_login_timeout')*60; 559 } 560 561 function getStaffMaxLogins() { 562 return $this->get('staff_max_logins'); 563 } 564 565 function getStaffAvatarSource() { 566 require_once INCLUDE_DIR . 'class.avatar.php'; 567 list($source, $mode) = explode('.', $this->get('agent_avatar'), 2); 568 return AvatarSource::lookup($source, $mode); 569 } 570 571 function getClientAvatarSource() { 572 require_once INCLUDE_DIR . 'class.avatar.php'; 573 list($source, $mode) = explode('.', $this->get('client_avatar'), 2); 574 return AvatarSource::lookup($source, $mode); 575 } 576 577 function getLockTime() { 578 return $this->get('autolock_minutes'); 579 } 580 581 function getTicketLockMode() { 582 return $this->get('ticket_lock'); 583 } 584 585 function getAgentNameFormat() { 586 return $this->get('agent_name_format'); 587 } 588 589 function getClientNameFormat() { 590 return $this->get('client_name_format'); 591 } 592 593 function getDefaultDeptId() { 594 return $this->get('default_dept_id'); 595 } 596 597 function getDefaultDept() { 598 599 if(!$this->defaultDept && $this->getDefaultDeptId()) 600 $this->defaultDept=Dept::lookup($this->getDefaultDeptId()); 601 602 return $this->defaultDept; 603 } 604 605 function getDefaultEmailId() { 606 return $this->get('default_email_id'); 607 } 608 609 function getDefaultEmail() { 610 611 if(!$this->defaultEmail && $this->getDefaultEmailId()) 612 $this->defaultEmail = Email::lookup($this->getDefaultEmailId()); 613 614 return $this->defaultEmail; 615 } 616 617 function getDefaultEmailAddress() { 618 return ($email=$this->getDefaultEmail()) ? $email->getAddress() : null; 619 } 620 621 function getDefaultTicketStatusId() { 622 return $this->get('default_ticket_status_id', 1); 623 } 624 625 function getDefaultSLAId() { 626 return $this->get('default_sla_id'); 627 } 628 629 function getDefaultSLA() { 630 631 if(!$this->defaultSLA && $this->getDefaultSLAId()) 632 $this->defaultSLA = SLA::lookup($this->getDefaultSLAId()); 633 634 return $this->defaultSLA; 635 } 636 637 function getDefaultScheduleId() { 638 return $this->get('schedule_id'); 639 } 640 641 function getDefaultSchedule() { 642 if (!isset($this->defaultSchedule) && $this->getDefaultScheduleId()) 643 $this->defaultSchedule = BusinessHoursSchedule::lookup( 644 $this->getDefaultScheduleId()); 645 646 return $this->defaultSchedule; 647 } 648 649 function getAlertEmailId() { 650 return $this->get('alert_email_id'); 651 } 652 653 function getAlertEmail() { 654 655 if(!$this->alertEmail) 656 if(!($this->alertEmail = Email::lookup($this->getAlertEmailId()))) 657 $this->alertEmail = $this->getDefaultEmail(); 658 659 return $this->alertEmail; 660 } 661 662 function getDefaultSMTPEmail() { 663 664 if(!$this->defaultSMTPEmail && $this->get('default_smtp_id')) 665 $this->defaultSMTPEmail = Email::lookup($this->get('default_smtp_id')); 666 667 return $this->defaultSMTPEmail; 668 } 669 670 function getDefaultPriorityId() { 671 return $this->get('default_priority_id'); 672 } 673 674 function getDefaultPriority() { 675 if (!isset($this->defaultPriority)) 676 $this->defaultPriority = Priority::lookup($this->getDefaultPriorityId()); 677 678 return $this->defaultPriority; 679 } 680 681 function getDefaultTopicId() { 682 return $this->get('default_help_topic'); 683 } 684 685 function getDefaultTopic() { 686 return Topic::lookup($this->getDefaultTopicId()); 687 } 688 689 function getTopicSortMode() { 690 return $this->get('help_topic_sort_mode'); 691 } 692 693 function forceHttps() { 694 return $this->get('force_https') == 'on'; 695 } 696 697 function setTopicSortMode($mode) { 698 $modes = static::allTopicSortModes(); 699 if (!isset($modes[$mode])) 700 throw new InvalidArgumentException(sprintf( 701 '%s: Unsupported help topic sort mode', $mode)); 702 703 $this->update('help_topic_sort_mode', $mode); 704 } 705 706 static function allTopicSortModes() { 707 return array( 708 Topic::SORT_ALPHA => __('Alphabetically'), 709 Topic::SORT_MANUAL => __('Manually'), 710 ); 711 } 712 713 function getDefaultTemplateId() { 714 return $this->get('default_template_id'); 715 } 716 717 function getDefaultTemplate() { 718 719 if(!$this->defaultTemplate && $this->getDefaultTemplateId()) 720 $this->defaultTemplate = EmailTemplateGroup::lookup($this->getDefaultTemplateId()); 721 722 return $this->defaultTemplate; 723 } 724 725 function getLandingPageId() { 726 return $this->get('landing_page_id'); 727 } 728 729 function getLandingPage() { 730 731 if(!$this->landing_page && $this->getLandingPageId()) 732 $this->landing_page = Page::lookup($this->getLandingPageId()); 733 734 return $this->landing_page; 735 } 736 737 function getOfflinePageId() { 738 return $this->get('offline_page_id'); 739 } 740 741 function getOfflinePage() { 742 743 if(!$this->offline_page && $this->getOfflinePageId()) 744 $this->offline_page = Page::lookup($this->getOfflinePageId()); 745 746 return $this->offline_page; 747 } 748 749 function getThankYouPageId() { 750 return $this->get('thank-you_page_id'); 751 } 752 753 function getThankYouPage() { 754 755 if(!$this->thankyou_page && $this->getThankYouPageId()) 756 $this->thankyou_page = Page::lookup($this->getThankYouPageId()); 757 758 return $this->thankyou_page; 759 } 760 761 function getDefaultPages() { 762 /* Array of ids...as opposed to objects */ 763 return array( 764 $this->getLandingPageId(), 765 $this->getOfflinePageId(), 766 $this->getThankYouPageId(), 767 ); 768 } 769 770 function getMaxOpenTickets() { 771 return $this->get('max_open_tickets'); 772 } 773 774 function getMaxFileSize() { 775 return $this->get('max_file_size'); 776 } 777 778 function getLogLevel() { 779 return $this->get('log_level'); 780 } 781 782 function getLogGracePeriod() { 783 return $this->get('log_graceperiod'); 784 } 785 786 function enableStaffIPBinding() { 787 return ($this->get('staff_ip_binding')); 788 } 789 790 /** 791 * Configuration: allow_pw_reset 792 * 793 * TRUE if the <a>Forgot my password</a> link and system should be 794 * enabled, and FALSE otherwise. 795 */ 796 function allowPasswordReset() { 797 return $this->get('allow_pw_reset'); 798 } 799 800 /** 801 * Configuration: pw_reset_window 802 * 803 * Number of minutes for which the password reset token is valid. 804 * 805 * Returns: Number of seconds the password reset token is valid. The 806 * number of minutes from the database is automatically converted 807 * to seconds here. 808 */ 809 function getPwResetWindow() { 810 // pw_reset_window is stored in minutes. Return value in seconds 811 return $this->get('pw_reset_window') * 60; 812 } 813 814 function isClientLoginRequired() { 815 return $this->get('clients_only'); 816 } 817 818 function isClientRegistrationEnabled() { 819 return in_array($this->getClientRegistrationMode(), 820 array('public', 'auto')); 821 } 822 823 function getClientRegistrationMode() { 824 return $this->get('client_registration'); 825 } 826 827 function isClientRegistrationMode($modes) { 828 if (!is_array($modes)) 829 $modes = array($modes); 830 831 return in_array($this->getClientRegistrationMode(), $modes); 832 } 833 834 function isClientEmailVerificationRequired() { 835 return $this->get('client_verify_email'); 836 } 837 838 function isAuthTokenEnabled() { 839 return $this->get('allow_auth_tokens'); 840 } 841 842 function isCaptchaEnabled() { 843 return (extension_loaded('gd') && function_exists('gd_info') && $this->get('enable_captcha')); 844 } 845 846 function isAutoCronEnabled() { 847 return ($this->get('enable_auto_cron')); 848 } 849 850 function isEmailPollingEnabled() { 851 return ($this->get('enable_mail_polling')); 852 } 853 854 function useEmailPriority() { 855 return ($this->get('use_email_priority')); 856 } 857 858 function acceptUnregisteredEmail() { 859 return $this->get('accept_unregistered_email'); 860 } 861 862 function addCollabsViaEmail() { 863 return ($this->get('add_email_collabs')); 864 } 865 866 function getAdminEmail() { 867 return $this->get('admin_email'); 868 } 869 870 function verifyEmailAddrs() { 871 return (bool) $this->get('verify_email_addrs'); 872 } 873 874 function getReplySeparator() { 875 return $this->get('reply_separator'); 876 } 877 878 function stripQuotedReply() { 879 return ($this->get('strip_quoted_reply')); 880 } 881 882 function saveEmailHeaders() { 883 return true; //No longer an option...hint: big plans for headers coming!! 884 } 885 886 function getDefaultTicketSequence() { 887 if ($this->get('ticket_sequence_id')) 888 $sequence = Sequence::lookup($this->get('ticket_sequence_id')); 889 if (!$sequence) 890 $sequence = new RandomSequence(); 891 return $sequence; 892 } 893 894 function showTopLevelTicketCounts() { 895 return ($this->get('queue_bucket_counts')); 896 } 897 898 function getDefaultTicketNumberFormat() { 899 return $this->get('ticket_number_format'); 900 } 901 902 function getNewTicketNumber() { 903 $s = $this->getDefaultTicketSequence(); 904 return $s->next($this->getDefaultTicketNumberFormat(), 905 array('Ticket', 'isTicketNumberUnique')); 906 } 907 908 // Task sequence 909 function getDefaultTaskSequence() { 910 if ($this->get('task_sequence_id')) 911 $sequence = Sequence::lookup($this->get('task_sequence_id')); 912 if (!$sequence) 913 $sequence = new RandomSequence(); 914 915 return $sequence; 916 } 917 918 function getDefaultTaskNumberFormat() { 919 return $this->get('task_number_format'); 920 } 921 922 function getNewTaskNumber() { 923 $s = $this->getDefaultTaskSequence(); 924 return $s->next($this->getDefaultTaskNumberFormat(), 925 array('Task', 'isNumberUnique')); 926 } 927 928 /* autoresponders & Alerts */ 929 function autoRespONNewTicket() { 930 return ($this->get('ticket_autoresponder')); 931 } 932 933 function autoRespONNewMessage() { 934 return ($this->get('message_autoresponder')); 935 } 936 937 function notifyCollabsONNewMessage() { 938 return ($this->get('message_autoresponder_collabs')); 939 } 940 941 function notifyONNewStaffTicket() { 942 return ($this->get('ticket_notice_active')); 943 } 944 945 function alertONNewMessage() { 946 return ($this->get('message_alert_active')); 947 } 948 949 function alertLastRespondentONNewMessage() { 950 return ($this->get('message_alert_laststaff')); 951 } 952 953 function alertAssignedONNewMessage() { 954 return ($this->get('message_alert_assigned')); 955 } 956 957 function alertDeptManagerONNewMessage() { 958 return ($this->get('message_alert_dept_manager')); 959 } 960 961 function alertAcctManagerONNewMessage() { 962 return ($this->get('message_alert_acct_manager')); 963 } 964 965 //TODO: change note_alert to activity_alert 966 function alertONNewActivity() { 967 return ($this->get('note_alert_active')); 968 } 969 970 function alertLastRespondentONNewActivity() { 971 return ($this->get('note_alert_laststaff')); 972 } 973 974 function alertAssignedONNewActivity() { 975 return ($this->get('note_alert_assigned')); 976 } 977 978 function alertDeptManagerONNewActivity() { 979 return ($this->get('note_alert_dept_manager')); 980 } 981 982 function alertONNewTicket() { 983 return ($this->get('ticket_alert_active')); 984 } 985 986 function alertAdminONNewTicket() { 987 return ($this->get('ticket_alert_admin')); 988 } 989 990 function alertDeptManagerONNewTicket() { 991 return ($this->get('ticket_alert_dept_manager')); 992 } 993 994 function alertDeptMembersONNewTicket() { 995 return ($this->get('ticket_alert_dept_members')); 996 } 997 998 function alertAcctManagerONNewTicket() { 999 return ($this->get('ticket_alert_acct_manager')); 1000 } 1001 1002 function alertONTransfer() { 1003 return ($this->get('transfer_alert_active')); 1004 } 1005 1006 function alertAssignedONTransfer() { 1007 return ($this->get('transfer_alert_assigned')); 1008 } 1009 1010 function alertDeptManagerONTransfer() { 1011 return ($this->get('transfer_alert_dept_manager')); 1012 } 1013 1014 function alertDeptMembersONTransfer() { 1015 return ($this->get('transfer_alert_dept_members')); 1016 } 1017 1018 function alertONAssignment() { 1019 return ($this->get('assigned_alert_active')); 1020 } 1021 1022 function alertStaffONAssignment() { 1023 return ($this->get('assigned_alert_staff')); 1024 } 1025 1026 function alertTeamLeadONAssignment() { 1027 return ($this->get('assigned_alert_team_lead')); 1028 } 1029 1030 function alertTeamMembersONAssignment() { 1031 return ($this->get('assigned_alert_team_members')); 1032 } 1033 1034 1035 function alertONOverdueTicket() { 1036 return ($this->get('overdue_alert_active')); 1037 } 1038 1039 function alertAssignedONOverdueTicket() { 1040 return ($this->get('overdue_alert_assigned')); 1041 } 1042 1043 function alertDeptManagerONOverdueTicket() { 1044 return ($this->get('overdue_alert_dept_manager')); 1045 } 1046 1047 function alertDeptMembersONOverdueTicket() { 1048 return ($this->get('overdue_alert_dept_members')); 1049 } 1050 1051 function autoClaimTickets() { 1052 return $this->get('auto_claim_tickets'); 1053 } 1054 1055 function autoReferTicketsOnClose() { 1056 return $this->get('auto_refer_closed'); 1057 } 1058 1059 function collaboratorTicketsVisibility() { 1060 return $this->get('collaborator_ticket_visibility'); 1061 } 1062 1063 function disableAgentCollaborators() { 1064 return $this->get('disable_agent_collabs'); 1065 } 1066 1067 function requireTopicToClose() { 1068 return $this->get('require_topic_to_close'); 1069 } 1070 1071 function allowExternalImages() { 1072 return ($this->get('allow_external_images')); 1073 } 1074 1075 function getDefaultTicketQueueId() { 1076 return $this->get('default_ticket_queue', 1); 1077 } 1078 1079 function hideStaffName() { 1080 return ($this->get('hide_staff_name')); 1081 } 1082 1083 function sendOverLimitNotice() { 1084 return ($this->get('overlimit_notice_active')); 1085 } 1086 1087 /* Tasks */ 1088 1089 function alertONNewTask() { 1090 return ($this->get('task_alert_active')); 1091 } 1092 1093 function alertAdminONNewTask() { 1094 return ($this->get('task_alert_admin')); 1095 } 1096 1097 function alertDeptManagerONNewTask() { 1098 return ($this->get('task_alert_dept_manager')); 1099 } 1100 1101 function alertDeptMembersONNewTask() { 1102 return ($this->get('task_alert_dept_members')); 1103 } 1104 1105 function alertONTaskActivity() { 1106 return ($this->get('task_activity_alert_active')); 1107 } 1108 1109 function alertLastRespondentONTaskActivity() { 1110 return ($this->get('task_activity_alert_laststaff')); 1111 } 1112 1113 function alertAssignedONTaskActivity() { 1114 return ($this->get('task_activity_alert_assigned')); 1115 } 1116 1117 function alertDeptManagerONTaskActivity() { 1118 return ($this->get('task_activity_alert_dept_manager')); 1119 } 1120 1121 function alertONTaskTransfer() { 1122 return ($this->get('task_transfer_alert_active')); 1123 } 1124 1125 function alertAssignedONTaskTransfer() { 1126 return ($this->get('task_transfer_alert_assigned')); 1127 } 1128 1129 function alertDeptManagerONTaskTransfer() { 1130 return ($this->get('task_transfer_alert_dept_manager')); 1131 } 1132 1133 function alertDeptMembersONTaskTransfer() { 1134 return ($this->get('task_transfer_alert_dept_members')); 1135 } 1136 1137 function alertONTaskAssignment() { 1138 return ($this->get('task_assignment_alert_active')); 1139 } 1140 1141 function alertStaffONTaskAssignment() { 1142 return ($this->get('task_assignment_alert_staff')); 1143 } 1144 1145 function alertTeamLeadONTaskAssignment() { 1146 return ($this->get('task_assignment_alert_team_lead')); 1147 } 1148 1149 function alertTeamMembersONTaskAssignment() { 1150 return ($this->get('task_assignment_alert_team_members')); 1151 } 1152 1153 function alertONOverdueTask() { 1154 return ($this->get('task_overdue_alert_active')); 1155 } 1156 1157 function alertAssignedONOverdueTask() { 1158 return ($this->get('task_overdue_alert_assigned')); 1159 } 1160 1161 function alertDeptManagerONOverdueTask() { 1162 return ($this->get('task_overdue_alert_dept_manager')); 1163 } 1164 1165 function alertDeptMembersONOverdueTask() { 1166 return ($this->get('task_overdue_alert_dept_members')); 1167 } 1168 1169 /* Error alerts sent to admin email when enabled */ 1170 function alertONSQLError() { 1171 return ($this->get('send_sql_errors')); 1172 } 1173 function alertONLoginError() { 1174 return ($this->get('send_login_errors')); 1175 } 1176 1177 1178 1179 /* Attachments */ 1180 function getAllowedFileTypes() { 1181 return trim($this->get('allowed_filetypes')); 1182 } 1183 1184 function emailAttachments() { 1185 return ($this->get('email_attachments')); 1186 } 1187 1188 function allowAttachments() { 1189 return ($this->get('allow_attachments')); 1190 } 1191 1192 function getPrimaryLanguage() { 1193 return $this->get('system_language'); 1194 } 1195 1196 function getSecondaryLanguages() { 1197 $langs = $this->get('secondary_langs'); 1198 $langs = (is_string($langs)) ? explode(',', $langs) : array(); 1199 return array_filter($langs); 1200 } 1201 1202 /* Needed by upgrader on 1.6 and older releases upgrade - not not remove */ 1203 function getUploadDir() { 1204 return $this->get('upload_dir'); 1205 } 1206 1207 function getDefaultStorageBackendChar() { 1208 return $this->get('default_storage_bk'); 1209 } 1210 1211 function getVar($name) { 1212 return $this->get($name); 1213 } 1214 1215 function updateSettings($vars, &$errors) { 1216 1217 if(!$vars || $errors) 1218 return false; 1219 1220 switch(strtolower($vars['t'])) { 1221 case 'system': 1222 return $this->updateSystemSettings($vars, $errors); 1223 break; 1224 case 'tickets': 1225 return $this->updateTicketsSettings($vars, $errors); 1226 break; 1227 case 'tasks': 1228 return $this->updateTasksSettings($vars, $errors); 1229 break; 1230 case 'emails': 1231 return $this->updateEmailsSettings($vars, $errors); 1232 break; 1233 case 'pages': 1234 return $this->updatePagesSettings($vars, $errors); 1235 break; 1236 case 'agents': 1237 return $this->updateAgentsSettings($vars, $errors); 1238 break; 1239 case 'users': 1240 return $this->updateUsersSettings($vars, $errors); 1241 break; 1242 case 'kb': 1243 return $this->updateKBSettings($vars, $errors); 1244 break; 1245 default: 1246 $errors['err']=sprintf('%s - %s', __('Unknown setting option'), __('Get technical help!')); 1247 } 1248 1249 return false; 1250 } 1251 1252 function updateSystemSettings($vars, &$errors) { 1253 1254 $f=array(); 1255 $f['helpdesk_url']=array('type'=>'string', 'required'=>1, 'error'=>__('Helpdesk URL is required')); 1256 $f['helpdesk_title']=array('type'=>'string', 'required'=>1, 'error'=>__('Helpdesk title is required')); 1257 $f['default_dept_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Default Department is required')); 1258 $f['autolock_minutes']=array('type'=>'int', 'required'=>1, 'error'=>__('Enter lock time in minutes')); 1259 $f['allow_iframes']=array('type'=>'cs-url', 'required'=>0, 'error'=>__('Enter comma separated list of urls')); 1260 $f['embedded_domain_whitelist']=array('type'=>'cs-domain', 'required'=>0, 'error'=>__('Enter comma separated list of domains')); 1261 $f['acl']=array('type'=>'ipaddr', 'required'=>0, 'error'=>__('Enter comma separated list of IP addresses')); 1262 //Date & Time Options 1263 $f['time_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Time format is required')); 1264 $f['date_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Date format is required')); 1265 $f['datetime_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Datetime format is required')); 1266 $f['daydatetime_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Day, Datetime format is required')); 1267 $f['default_timezone']=array('type'=>'string', 'required'=>1, 'error'=>__('Default Timezone is required')); 1268 $f['system_language']=array('type'=>'string', 'required'=>1, 'error'=>__('A primary system language is required')); 1269 1270 $vars = Format::htmlchars($vars, true); 1271 1272 // ACL Checks 1273 if ($vars['acl']) { 1274 // Check if Admin's IP is in the list, if not, return error 1275 // to avoid locking self out 1276 if (!in_array($vars['acl_backend'], array(0,2))) { 1277 $acl = explode(',', str_replace(' ', '', $vars['acl'])); 1278 if (!in_array(osTicket::get_client_ip(), $acl)) 1279 $errors['acl'] = __('Cowardly refusing to lock out active administrator'); 1280 } 1281 } elseif ((int) $vars['acl_backend'] !== 0) 1282 $errors['acl'] = __('IP address required when selecting panel'); 1283 1284 // Make sure the selected backend is valid 1285 $storagebk = null; 1286 if (isset($vars['default_storage_bk'])) { 1287 try { 1288 $storagebk = FileStorageBackend::lookup($vars['default_storage_bk']); 1289 1290 } catch (Exception $ex) { 1291 $errors['default_storage_bk'] = $ex->getMessage(); 1292 } 1293 } 1294 1295 if(!Validator::process($f, $vars, $errors) || $errors) 1296 return false; 1297 1298 // Manage secondard languages 1299 $vars['secondary_langs'][] = $vars['add_secondary_language']; 1300 foreach ($vars['secondary_langs'] as $i=>$lang) { 1301 if (!$lang || !Internationalization::isLanguageInstalled($lang)) 1302 unset($vars['secondary_langs'][$i]); 1303 } 1304 $secondary_langs = implode(',', $vars['secondary_langs']); 1305 1306 if ($storagebk) 1307 $this->update('default_storage_bk', $storagebk->getBkChar()); 1308 1309 1310 return $this->updateAll(array( 1311 'isonline'=>$vars['isonline'], 1312 'helpdesk_title'=>$vars['helpdesk_title'], 1313 'helpdesk_url'=>$vars['helpdesk_url'], 1314 'default_dept_id'=>$vars['default_dept_id'], 1315 'force_https'=>$vars['force_https'] ? 'on' : '', 1316 'max_page_size'=>$vars['max_page_size'], 1317 'log_level'=>$vars['log_level'], 1318 'log_graceperiod'=>$vars['log_graceperiod'], 1319 'time_format'=>$vars['time_format'], 1320 'date_format'=>$vars['date_format'], 1321 'datetime_format'=>$vars['datetime_format'], 1322 'daydatetime_format'=>$vars['daydatetime_format'], 1323 'date_formats'=>$vars['date_formats'], 1324 'default_timezone'=>$vars['default_timezone'], 1325 'schedule_id' => $vars['schedule_id'], 1326 'default_locale'=>$vars['default_locale'], 1327 'system_language'=>$vars['system_language'], 1328 'secondary_langs'=>$secondary_langs, 1329 'max_file_size' => $vars['max_file_size'], 1330 'autolock_minutes' => $vars['autolock_minutes'], 1331 'enable_avatars' => isset($vars['enable_avatars']) ? 1 : 0, 1332 'enable_richtext' => isset($vars['enable_richtext']) ? 1 : 0, 1333 'files_req_auth' => isset($vars['files_req_auth']) ? 1 : 0, 1334 'allow_iframes' => Format::sanitize($vars['allow_iframes']), 1335 'embedded_domain_whitelist' => Format::sanitize($vars['embedded_domain_whitelist']), 1336 'acl' => Format::sanitize($vars['acl']), 1337 'acl_backend' => Format::sanitize((int) $vars['acl_backend']) ?: 0, 1338 )); 1339 } 1340 1341 function updateAgentsSettings($vars, &$errors) { 1342 $f=array(); 1343 $f['staff_session_timeout']=array('type'=>'int', 'required'=>1, 'error'=>'Enter idle time in minutes'); 1344 $f['pw_reset_window']=array('type'=>'int', 'required'=>1, 'min'=>1, 1345 'error'=>__('Valid password reset window required')); 1346 1347 require_once INCLUDE_DIR.'class.avatar.php'; 1348 list($avatar_source) = explode('.', $vars['agent_avatar']); 1349 if (!AvatarSource::lookup($avatar_source)) 1350 $errors['agent_avatar'] = __('Select a value from the list'); 1351 1352 if(!Validator::process($f, $vars, $errors) || $errors) 1353 return false; 1354 1355 return $this->updateAll(array( 1356 'agent_passwd_policy'=>$vars['agent_passwd_policy'], 1357 'staff_max_logins'=>$vars['staff_max_logins'], 1358 'staff_login_timeout'=>$vars['staff_login_timeout'], 1359 'staff_session_timeout'=>$vars['staff_session_timeout'], 1360 'staff_ip_binding'=>isset($vars['staff_ip_binding'])?1:0, 1361 'allow_pw_reset'=>isset($vars['allow_pw_reset'])?1:0, 1362 'pw_reset_window'=>$vars['pw_reset_window'], 1363 'require_agent_2fa'=> isset($vars['require_agent_2fa']) ? 1 : 0, 1364 'agent_name_format'=>$vars['agent_name_format'], 1365 'hide_staff_name'=>isset($vars['hide_staff_name']) ? 1 : 0, 1366 'agent_avatar'=>$vars['agent_avatar'], 1367 'disable_agent_collabs'=>isset($vars['disable_agent_collabs'])?1:0, 1368 )); 1369 } 1370 1371 function updateUsersSettings($vars, &$errors) { 1372 $f=array(); 1373 $f['client_session_timeout']=array('type'=>'int', 'required'=>1, 'error'=>'Enter idle time in minutes'); 1374 1375 require_once INCLUDE_DIR.'class.avatar.php'; 1376 list($avatar_source) = explode('.', $vars['client_avatar']); 1377 if (!AvatarSource::lookup($avatar_source)) 1378 $errors['client_avatar'] = __('Select a value from the list'); 1379 1380 if(!Validator::process($f, $vars, $errors) || $errors) 1381 return false; 1382 1383 return $this->updateAll(array( 1384 'client_passwd_policy'=>$vars['client_passwd_policy'], 1385 'client_max_logins'=>$vars['client_max_logins'], 1386 'client_login_timeout'=>$vars['client_login_timeout'], 1387 'client_session_timeout'=>$vars['client_session_timeout'], 1388 'clients_only'=>isset($vars['clients_only'])?1:0, 1389 'client_registration'=>$vars['client_registration'], 1390 'client_verify_email'=>isset($vars['client_verify_email'])?1:0, 1391 'allow_auth_tokens' => isset($vars['allow_auth_tokens']) ? 1 : 0, 1392 'client_name_format'=>$vars['client_name_format'], 1393 'client_avatar'=>$vars['client_avatar'], 1394 )); 1395 } 1396 1397 function updateTicketsSettings($vars, &$errors) { 1398 $f=array(); 1399 $f['default_sla_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Selection required')); 1400 $f['default_ticket_status_id'] = array('type'=>'int', 'required'=>1, 'error'=>__('Selection required')); 1401 $f['default_priority_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Selection required')); 1402 $f['max_open_tickets']=array('type'=>'int', 'required'=>1, 'error'=>__('Enter valid numeric value')); 1403 1404 1405 if($vars['enable_captcha']) { 1406 if (!extension_loaded('gd')) 1407 $errors['enable_captcha']=__('The GD extension is required'); 1408 elseif(!function_exists('imagepng')) 1409 $errors['enable_captcha']=__('PNG support is required for Image Captcha'); 1410 } 1411 1412 if ($vars['default_help_topic'] 1413 && ($T = Topic::lookup($vars['default_help_topic'])) 1414 && !$T->isActive()) { 1415 $errors['default_help_topic'] = __('Default help topic must be set to active'); 1416 } 1417 1418 if (!preg_match('`(?!<\\\)#`', $vars['ticket_number_format'])) 1419 $errors['ticket_number_format'] = 'Ticket number format requires at least one hash character (#)'; 1420 1421 if (!isset($vars['default_ticket_queue'])) 1422 $errors['default_ticket_queue'] = __("Select a default ticket queue"); 1423 elseif (!CustomQueue::lookup($vars['default_ticket_queue'])) 1424 $errors['default_ticket_queue'] = __("Select a default ticket queue"); 1425 1426 $this->updateAutoresponderSettings($vars, $errors); 1427 $this->updateAlertsSettings($vars, $errors); 1428 1429 if(!Validator::process($f, $vars, $errors) || $errors) 1430 return false; 1431 1432 // Sort ticket queues 1433 $queues = CustomQueue::queues()->getIterator(); 1434 foreach ($vars['qsort'] as $queue_id => $sort) { 1435 if ($q = $queues->findFirst(array('id' => $queue_id))) { 1436 $q->sort = $sort; 1437 $q->save(); 1438 } 1439 } 1440 1441 return $this->updateAll(array( 1442 'ticket_number_format'=>$vars['ticket_number_format'] ?: '######', 1443 'ticket_sequence_id'=>$vars['ticket_sequence_id'] ?: 0, 1444 'queue_bucket_counts'=>isset($vars['queue_bucket_counts'])?1:0, 1445 'default_priority_id'=>$vars['default_priority_id'], 1446 'default_help_topic'=>$vars['default_help_topic'], 1447 'default_ticket_status_id'=>$vars['default_ticket_status_id'], 1448 'default_sla_id'=>$vars['default_sla_id'], 1449 'max_open_tickets'=>$vars['max_open_tickets'], 1450 'enable_captcha'=>isset($vars['enable_captcha'])?1:0, 1451 'auto_claim_tickets'=>isset($vars['auto_claim_tickets'])?1:0, 1452 'auto_refer_closed' => isset($vars['auto_refer_closed']) ? 1 : 0, 1453 'collaborator_ticket_visibility'=>isset($vars['collaborator_ticket_visibility'])?1:0, 1454 'require_topic_to_close'=>isset($vars['require_topic_to_close'])?1:0, 1455 'show_related_tickets'=>isset($vars['show_related_tickets'])?1:0, 1456 'allow_client_updates'=>isset($vars['allow_client_updates'])?1:0, 1457 'ticket_lock' => $vars['ticket_lock'], 1458 'default_ticket_queue'=>$vars['default_ticket_queue'], 1459 'allow_external_images'=>isset($vars['allow_external_images'])?1:0, 1460 )); 1461 } 1462 1463 function updateTasksSettings($vars, &$errors) { 1464 $f=array(); 1465 $f['default_task_priority_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Selection required')); 1466 1467 if (!preg_match('`(?!<\\\)#`', $vars['task_number_format'])) 1468 $errors['task_number_format'] = 'Task number format requires at least one hash character (#)'; 1469 1470 Validator::process($f, $vars, $errors); 1471 1472 if ($vars['task_alert_active'] 1473 && (!isset($vars['task_alert_admin']) 1474 && !isset($vars['task_alert_dept_manager']) 1475 && !isset($vars['task_alert_dept_members']) 1476 && !isset($vars['task_alert_acct_manager']))) { 1477 $errors['task_alert_active'] = __('Select recipient(s)'); 1478 } 1479 1480 if ($vars['task_activity_alert_active'] 1481 && (!isset($vars['task_activity_alert_laststaff']) 1482 && !isset($vars['task_activity_alert_assigned']) 1483 && !isset($vars['task_activity_alert_dept_manager']))) { 1484 $errors['task_activity_alert_active'] = __('Select recipient(s)'); 1485 } 1486 1487 if ($vars['task_transfer_alert_active'] 1488 && (!isset($vars['task_transfer_alert_assigned']) 1489 && !isset($vars['task_transfer_alert_dept_manager']) 1490 && !isset($vars['task_transfer_alert_dept_members']))) { 1491 $errors['task_transfer_alert_active'] = __('Select recipient(s)'); 1492 } 1493 1494 if ($vars['task_overdue_alert_active'] 1495 && (!isset($vars['task_overdue_alert_assigned']) 1496 && !isset($vars['task_overdue_alert_dept_manager']) 1497 && !isset($vars['task_overdue_alert_dept_members']))) { 1498 $errors['task_overdue_alert_active'] = __('Select recipient(s)'); 1499 } 1500 1501 if ($vars['task_assignment_alert_active'] 1502 && (!isset($vars['task_assignment_alert_staff']) 1503 && !isset($vars['task_assignment_alert_team_lead']) 1504 && !isset($vars['task_assignment_alert_team_members']))) { 1505 $errors['task_assignment_alert_active'] = __('Select recipient(s)'); 1506 } 1507 1508 if ($errors) 1509 return false; 1510 1511 return $this->updateAll(array( 1512 'task_number_format'=>$vars['task_number_format'] ?: '######', 1513 'task_sequence_id'=>$vars['task_sequence_id'] ?: 0, 1514 'default_task_priority_id'=>$vars['default_task_priority_id'], 1515 'default_task_sla_id'=>$vars['default_task_sla_id'], 1516 'task_alert_active'=>$vars['task_alert_active'], 1517 'task_alert_admin'=>isset($vars['task_alert_admin']) ? 1 : 0, 1518 'task_alert_dept_manager'=>isset($vars['task_alert_dept_manager']) ? 1 : 0, 1519 'task_alert_dept_members'=>isset($vars['task_alert_dept_members']) ? 1 : 0, 1520 'task_activity_alert_active'=>$vars['task_activity_alert_active'], 1521 'task_activity_alert_laststaff'=>isset($vars['task_activity_alert_laststaff']) ? 1 : 0, 1522 'task_activity_alert_assigned'=>isset($vars['task_activity_alert_assigned']) ? 1 : 0, 1523 'task_activity_alert_dept_manager'=>isset($vars['task_activity_alert_dept_manager']) ? 1 : 0, 1524 'task_assignment_alert_active'=>$vars['task_assignment_alert_active'], 1525 'task_assignment_alert_staff'=>isset($vars['task_assignment_alert_staff']) ? 1 : 0, 1526 'task_assignment_alert_team_lead'=>isset($vars['task_assignment_alert_team_lead']) ? 1 : 0, 1527 'task_assignment_alert_team_members'=>isset($vars['task_assignment_alert_team_members']) ? 1 : 0, 1528 'task_transfer_alert_active'=>$vars['task_transfer_alert_active'], 1529 'task_transfer_alert_assigned'=>isset($vars['task_transfer_alert_assigned']) ? 1 : 0, 1530 'task_transfer_alert_dept_manager'=>isset($vars['task_transfer_alert_dept_manager']) ? 1 : 0, 1531 'task_transfer_alert_dept_members'=>isset($vars['task_transfer_alert_dept_members']) ? 1 : 0, 1532 'task_overdue_alert_active'=>$vars['task_overdue_alert_active'], 1533 'task_overdue_alert_assigned'=>isset($vars['task_overdue_alert_assigned']) ? 1 : 0, 1534 'task_overdue_alert_dept_manager'=>isset($vars['task_overdue_alert_dept_manager']) ? 1 : 0, 1535 'task_overdue_alert_dept_members'=>isset($vars['task_overdue_alert_dept_members']) ? 1 : 0, 1536 )); 1537 } 1538 1539 function updateEmailsSettings($vars, &$errors) { 1540 $f=array(); 1541 $f['default_template_id']=array('type'=>'int', 'required'=>1, 'error'=>__('You must select template')); 1542 $f['default_email_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Default email is required')); 1543 $f['alert_email_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Selection required')); 1544 $f['admin_email']=array('type'=>'email', 'required'=>1, 'error'=>__('System admin email is required')); 1545 1546 if($vars['strip_quoted_reply'] && !trim($vars['reply_separator'])) 1547 $errors['reply_separator']=__('Reply separator is required to strip quoted reply.'); 1548 1549 if($vars['admin_email'] && Email::getIdByEmail($vars['admin_email'])) //Make sure admin email is not also a system email. 1550 $errors['admin_email']=__('Email already setup as system email'); 1551 1552 if(!Validator::process($f,$vars,$errors) || $errors) 1553 return false; 1554 1555 return $this->updateAll(array( 1556 'default_template_id'=>$vars['default_template_id'], 1557 'default_email_id'=>$vars['default_email_id'], 1558 'alert_email_id'=>$vars['alert_email_id'], 1559 'default_smtp_id'=>$vars['default_smtp_id'], 1560 'admin_email'=>$vars['admin_email'], 1561 'verify_email_addrs'=>isset($vars['verify_email_addrs']) ? 1 : 0, 1562 'enable_auto_cron'=>isset($vars['enable_auto_cron'])?1:0, 1563 'enable_mail_polling'=>isset($vars['enable_mail_polling'])?1:0, 1564 'strip_quoted_reply'=>isset($vars['strip_quoted_reply'])?1:0, 1565 'use_email_priority'=>isset($vars['use_email_priority'])?1:0, 1566 'accept_unregistered_email'=>isset($vars['accept_unregistered_email'])?1:0, 1567 'add_email_collabs'=>isset($vars['add_email_collabs'])?1:0, 1568 'reply_separator'=>$vars['reply_separator'], 1569 'email_attachments'=>isset($vars['email_attachments'])?1:0, 1570 )); 1571 } 1572 1573 function getLogo($site) { 1574 $id = $this->get("{$site}_logo_id", false); 1575 return ($id) ? AttachmentFile::lookup((int) $id) : null; 1576 } 1577 function getClientLogo() { 1578 return $this->getLogo('client'); 1579 } 1580 function getLogoId($site) { 1581 return $this->get("{$site}_logo_id", false); 1582 } 1583 function getClientLogoId() { 1584 return $this->getLogoId('client'); 1585 } 1586 1587 function getStaffLogoId() { 1588 return $this->getLogoId('staff'); 1589 } 1590 function getStaffLogo() { 1591 return $this->getLogo('staff'); 1592 } 1593 1594 function getStaffLoginBackdropId() { 1595 return $this->get("staff_backdrop_id", false); 1596 } 1597 function getStaffLoginBackdrop() { 1598 $id = $this->getStaffLoginBackdropId(); 1599 return ($id) ? AttachmentFile::lookup((int) $id) : null; 1600 } 1601 1602 function isAuthRequiredForFiles() { 1603 return $this->get('files_req_auth'); 1604 } 1605 1606 function updatePagesSettings($vars, &$errors) { 1607 global $ost; 1608 1609 $f=array(); 1610 $f['landing_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); 1611 $f['offline_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); 1612 $f['thank-you_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); 1613 1614 if ($_FILES['logo']) { 1615 $error = false; 1616 list($logo) = AttachmentFile::format($_FILES['logo']); 1617 if (!$logo) 1618 ; // Pass 1619 elseif ($logo['error']) 1620 $errors['logo'] = $logo['error']; 1621 elseif (!AttachmentFile::uploadLogo($logo, $error)) 1622 $errors['logo'] = sprintf(__('Unable to upload logo image: %s'), $error); 1623 } 1624 1625 if ($_FILES['backdrop']) { 1626 $error = false; 1627 list($backdrop) = AttachmentFile::format($_FILES['backdrop']); 1628 if (!$backdrop) 1629 ; // Pass 1630 elseif ($backdrop['error']) 1631 $errors['backdrop'] = $backdrop['error']; 1632 elseif (!AttachmentFile::uploadBackdrop($backdrop, $error)) 1633 $errors['backdrop'] = sprintf(__('Unable to upload backdrop image: %s'), $error); 1634 } 1635 1636 $company = $ost->company; 1637 $company_form = $company->getForm(); 1638 $company_form->setSource($_POST); 1639 if (!$company_form->isValid()) 1640 $errors += $company_form->errors(); 1641 1642 if(!Validator::process($f, $vars, $errors) || $errors) 1643 return false; 1644 1645 $company_form->save(); 1646 1647 if (isset($vars['delete-logo'])) 1648 foreach ($vars['delete-logo'] as $id) 1649 if (($vars['selected-logo'] != $id) 1650 && ($f = AttachmentFile::lookup((int) $id))) 1651 $f->delete(); 1652 1653 if (isset($vars['delete-backdrop'])) 1654 foreach ($vars['delete-backdrop'] as $id) 1655 if (($vars['selected-backdrop'] != $id) 1656 && ($f = AttachmentFile::lookup((int) $id))) 1657 $f->delete(); 1658 1659 return $this->updateAll(array( 1660 'landing_page_id' => $vars['landing_page_id'], 1661 'offline_page_id' => $vars['offline_page_id'], 1662 'thank-you_page_id' => $vars['thank-you_page_id'], 1663 'client_logo_id' => ( 1664 (is_numeric($vars['selected-logo']) && $vars['selected-logo']) 1665 ? $vars['selected-logo'] : false), 1666 'staff_logo_id' => ( 1667 (is_numeric($vars['selected-logo-scp']) && $vars['selected-logo-scp']) 1668 ? $vars['selected-logo-scp'] : false), 1669 'staff_backdrop_id' => ( 1670 (is_numeric($vars['selected-backdrop']) && $vars['selected-backdrop']) 1671 ? $vars['selected-backdrop'] : false), 1672 )); 1673 } 1674 1675 function updateAutoresponderSettings($vars, &$errors) { 1676 1677 if($errors) return false; 1678 1679 return $this->updateAll(array( 1680 'ticket_autoresponder'=>isset($vars['ticket_autoresponder']) ? 1 : 0, 1681 'message_autoresponder'=>isset($vars['message_autoresponder']) ? 1 : 0, 1682 'message_autoresponder_collabs'=>isset($vars['message_autoresponder_collabs']) ? 1 : 0, 1683 'ticket_notice_active'=>isset($vars['ticket_notice_active']) ? 1 : 0, 1684 'overlimit_notice_active'=>isset($vars['overlimit_notice_active']) ? 1 : 0, 1685 )); 1686 } 1687 1688 1689 function updateKBSettings($vars, &$errors) { 1690 if ($errors) return false; 1691 1692 return $this->updateAll(array( 1693 'enable_kb'=>isset($vars['enable_kb'])?1:0, 1694 'restrict_kb'=>isset($vars['restrict_kb'])?1:0, 1695 'enable_premade'=>isset($vars['enable_premade'])?1:0, 1696 )); 1697 } 1698 1699 1700 function updateAlertsSettings($vars, &$errors) { 1701 1702 if($vars['ticket_alert_active'] 1703 && (!isset($vars['ticket_alert_admin']) 1704 && !isset($vars['ticket_alert_dept_manager']) 1705 && !isset($vars['ticket_alert_dept_members']) 1706 && !isset($vars['ticket_alert_acct_manager']))) { 1707 $errors['ticket_alert_active']=__('Select recipient(s)'); 1708 } 1709 if($vars['message_alert_active'] 1710 && (!isset($vars['message_alert_laststaff']) 1711 && !isset($vars['message_alert_assigned']) 1712 && !isset($vars['message_alert_dept_manager']) 1713 && !isset($vars['message_alert_acct_manager']))) { 1714 $errors['message_alert_active']=__('Select recipient(s)'); 1715 } 1716 1717 if($vars['note_alert_active'] 1718 && (!isset($vars['note_alert_laststaff']) 1719 && !isset($vars['note_alert_assigned']) 1720 && !isset($vars['note_alert_dept_manager']))) { 1721 $errors['note_alert_active']=__('Select recipient(s)'); 1722 } 1723 1724 if($vars['transfer_alert_active'] 1725 && (!isset($vars['transfer_alert_assigned']) 1726 && !isset($vars['transfer_alert_dept_manager']) 1727 && !isset($vars['transfer_alert_dept_members']))) { 1728 $errors['transfer_alert_active']=__('Select recipient(s)'); 1729 } 1730 1731 if($vars['overdue_alert_active'] 1732 && (!isset($vars['overdue_alert_assigned']) 1733 && !isset($vars['overdue_alert_dept_manager']) 1734 && !isset($vars['overdue_alert_dept_members']))) { 1735 $errors['overdue_alert_active']=__('Select recipient(s)'); 1736 } 1737 1738 if($vars['assigned_alert_active'] 1739 && (!isset($vars['assigned_alert_staff']) 1740 && !isset($vars['assigned_alert_team_lead']) 1741 && !isset($vars['assigned_alert_team_members']))) { 1742 $errors['assigned_alert_active']=__('Select recipient(s)'); 1743 } 1744 1745 if($errors) return false; 1746 1747 return $this->updateAll(array( 1748 'ticket_alert_active'=>$vars['ticket_alert_active'], 1749 'ticket_alert_admin'=>isset($vars['ticket_alert_admin'])?1:0, 1750 'ticket_alert_dept_manager'=>isset($vars['ticket_alert_dept_manager'])?1:0, 1751 'ticket_alert_dept_members'=>isset($vars['ticket_alert_dept_members'])?1:0, 1752 'ticket_alert_acct_manager'=>isset($vars['ticket_alert_acct_manager'])?1:0, 1753 'message_alert_active'=>$vars['message_alert_active'], 1754 'message_alert_laststaff'=>isset($vars['message_alert_laststaff'])?1:0, 1755 'message_alert_assigned'=>isset($vars['message_alert_assigned'])?1:0, 1756 'message_alert_dept_manager'=>isset($vars['message_alert_dept_manager'])?1:0, 1757 'message_alert_acct_manager'=>isset($vars['message_alert_acct_manager'])?1:0, 1758 'note_alert_active'=>$vars['note_alert_active'], 1759 'note_alert_laststaff'=>isset($vars['note_alert_laststaff'])?1:0, 1760 'note_alert_assigned'=>isset($vars['note_alert_assigned'])?1:0, 1761 'note_alert_dept_manager'=>isset($vars['note_alert_dept_manager'])?1:0, 1762 'assigned_alert_active'=>$vars['assigned_alert_active'], 1763 'assigned_alert_staff'=>isset($vars['assigned_alert_staff'])?1:0, 1764 'assigned_alert_team_lead'=>isset($vars['assigned_alert_team_lead'])?1:0, 1765 'assigned_alert_team_members'=>isset($vars['assigned_alert_team_members'])?1:0, 1766 'transfer_alert_active'=>$vars['transfer_alert_active'], 1767 'transfer_alert_assigned'=>isset($vars['transfer_alert_assigned'])?1:0, 1768 'transfer_alert_dept_manager'=>isset($vars['transfer_alert_dept_manager'])?1:0, 1769 'transfer_alert_dept_members'=>isset($vars['transfer_alert_dept_members'])?1:0, 1770 'overdue_alert_active'=>$vars['overdue_alert_active'], 1771 'overdue_alert_assigned'=>isset($vars['overdue_alert_assigned'])?1:0, 1772 'overdue_alert_dept_manager'=>isset($vars['overdue_alert_dept_manager'])?1:0, 1773 'overdue_alert_dept_members'=>isset($vars['overdue_alert_dept_members'])?1:0, 1774 'send_sys_errors'=>isset($vars['send_sys_errors'])?1:0, 1775 'send_sql_errors'=>isset($vars['send_sql_errors'])?1:0, 1776 'send_login_errors'=>isset($vars['send_login_errors'])?1:0, 1777 )); 1778 } 1779 1780 //Used to detect version prior to 1.7 (useful during upgrade) 1781 /* static */ function getDBVersion() { 1782 $sql='SELECT `ostversion` FROM '.TABLE_PREFIX.'config ' 1783 .'WHERE id=1'; 1784 return db_result(db_query($sql)); 1785 } 1786} 1787?> 1788