function save($id, $vars, &$errors)
 {
     if ($id && $id != $vars['client_id']) {
         $errors['err'] = _('Internal Error');
     }
     // Check email.
     if (!$vars['client_email'] || !Validator::is_email($vars['client_email'])) {
         $errors['email'] = _('Valid email required');
     } elseif (Email::getIdByEmail($vars['client_email'])) {
         $errors['email'] = _('Already in-use system email');
     } else {
         //check if the email is already in-use.
         $sql = 'SELECT client_id FROM ' . CLIENT_TABLE . ' WHERE client_email=' . db_input($vars['client_email']);
         if ($id) {
             $sql .= ' AND client_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['email'] = _('Already in-use email');
         }
     }
     if ($vars['client_phone'] && !Validator::is_phone($vars['client_phone'])) {
         $errors['phone'] = _('Valid number required');
     }
     if ($vars['client_mobile'] && !Validator::is_phone($vars['client_mobile'])) {
         $errors['mobile'] = _('Valid number required');
     }
     // Check passwords
     if ($vars['npassword'] || $vars['vpassword'] || !$id) {
         if (!$vars['npassword'] && !$id) {
             $errors['npassword'] = _('Password required');
         } elseif ($vars['npassword'] && strcmp($vars['npassword'], $vars['vpassword'])) {
             $errors['vpassword'] = _('Password(s) do not match');
         } elseif ($vars['npassword'] && strlen($vars['npassword']) < 6) {
             $errors['npassword'] = _('Must be at least 6 characters');
         } elseif ($vars['npassword'] && strlen($vars['npassword']) > 128) {
             $errors['npassword'] = _('Password too long');
         }
     }
     if (!$errors) {
         $sql = ' SET client_isactive=' . db_input($vars['client_isactive']) . ',client_email=' . db_input(Format::striptags($vars['client_email'])) . ',client_firstname=' . db_input(Format::striptags($vars['client_firstname'])) . ',client_lastname=' . db_input(Format::striptags($vars['client_lastname'])) . ',client_organization=' . db_input(Format::striptags($vars['client_organization'])) . ',client_phone="' . db_input($vars['client_phone'], false) . '"' . ',client_mobile="' . db_input($vars['client_mobile'], false) . '"';
         if ($vars['npassword']) {
             $hash = PhpassHashedPass::hash($vars['npassword']);
             $sql .= ',client_password='******'UPDATE ' . CLIENT_TABLE . ' ' . $sql . ' WHERE client_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = _('Unable to update the user. Internal error occured');
             }
             if ($vars['old_client_email'] != $vars['client_email']) {
                 // Email changed? Update the tickets!
                 $sql = 'UPDATE ' . TICKET_TABLE . ' SET email=' . db_input(Format::striptags($vars['client_email'])) . ' WHERE email=' . db_input($vars['old_client_email']);
                 if (!db_query($sql)) {
                     $errors['err'] = _('Unable to update the user. Internal error occured');
                 }
                 //TODO: reverse the previous db operation!
             }
         } else {
             $sql = 'INSERT INTO ' . CLIENT_TABLE . ' ' . $sql . ',client_created=NOW()';
             if (db_query($sql) && ($uID = db_insert_id())) {
                 return $uID;
             }
             $errors['err'] = _('Unable to create user. Internal error');
         }
     }
     return $errors ? false : true;
 }
 function updatePref($var, &$errors)
 {
     if (!$var || $errors) {
         return false;
     }
     $f = array();
     $f['helpdesk_url'] = array('type' => 'string', 'required' => 1, 'error' => 'Assistência técnica URlnecessário');
     //TODO: Add url validation
     $f['helpdesk_title'] = array('type' => 'string', 'required' => 1, 'error' => 'Título da Assistência Técnica exigido');
     $f['default_dept_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Departamento Padrão necessário');
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'E-mail padrão exigido');
     $f['default_template_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Você deve selecionar modelo.');
     $f['staff_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Digite tempo inativo em minutos');
     $f['client_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Digite tempo inativo em minutos');
     $f['time_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de tempo necessário');
     //TODO: Add date format validation
     $f['date_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato da data requerida');
     $f['datetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de data e hora necessária');
     $f['daydatetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato dia, data e hora necessária');
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => 'E-mail válido necessário');
     $f['autolock_minutes'] = array('type' => 'int', 'required' => 1, 'error' => 'Digite o tempo de bloqueio em minutos');
     //TODO: check option fields for validity.
     //do the validation.
     $val = new Validator();
     $val->setFields($f);
     if (!$val->validate($var)) {
         $errors = array_merge($errors, $val->errors());
     }
     if ($var['ticket_alert_active'] && (!isset($var['ticket_alert_admin']) && !isset($var['ticket_alert_dept_manager']) && !isset($var['ticket_alert_dept_members']))) {
         $errors['ticket_alert_active'] = 'Sem destinatário(s) selecionado';
     }
     if ($var['message_alert_active'] && (!isset($var['message_alert_laststaff']) && !isset($var['message_alert_assigned']) && !isset($var['message_alert_dept_manager']))) {
         $errors['message_alert_active'] = 'Sem destinatário(s) selecionado';
     }
     if ($var['note_alert_active'] && (!isset($var['note_alert_laststaff']) && !isset($var['note_alert_assigned']) && !isset($var['note_alert_dept_manager']))) {
         $errors['note_alert_active'] = 'Sem destinatário(s) selecionado';
     }
     if ($var['strip_quoted_reply'] && !$var['reply_separator']) {
         $errors['reply_separator'] = 'Separador de resposta necessário (?)';
     }
     if ($var['enable_captcha']) {
         if (!extension_loaded('gd')) {
             $errors['enable_captcha'] = 'Extensão GD necessária';
         } elseif (!function_exists('imagepng')) {
             $errors['enable_captcha'] = 'Suporte PNG necessário para a imagem captcha';
         }
     }
     if (!$errors['admin_email'] && Email::getIdByEmail($var['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = 'E-mail já está configurado como e-mail do sistema';
     }
     if ($errors) {
         return false;
     }
     //No go!
     //We are good to go...blanket update!
     $sql = 'UPDATE ' . CONFIG_TABLE . ' SET isonline=' . db_input($var['isonline']) . ',timezone_offset=' . db_input($var['timezone_offset']) . ',enable_daylight_saving=' . db_input(isset($var['enable_daylight_saving']) ? 1 : 0) . ',staff_ip_binding=' . db_input(isset($var['staff_ip_binding']) ? 1 : 0) . ',staff_max_logins=' . db_input($var['staff_max_logins']) . ',staff_login_timeout=' . db_input($var['staff_login_timeout']) . ',staff_session_timeout=' . db_input($var['staff_session_timeout']) . ',client_max_logins=' . db_input($var['client_max_logins']) . ',client_login_timeout=' . db_input($var['client_login_timeout']) . ',client_session_timeout=' . db_input($var['client_session_timeout']) . ',max_page_size=' . db_input($var['max_page_size']) . ',log_level=' . db_input($var['log_level']) . ',log_graceperiod=' . db_input($var['log_graceperiod']) . ',max_open_tickets=' . db_input($var['max_open_tickets']) . ',autolock_minutes=' . db_input($var['autolock_minutes']) . ',overdue_grace_period=' . db_input($var['overdue_grace_period']) . ',alert_email_id=' . db_input($var['alert_email_id']) . ',default_email_id=' . db_input($var['default_email_id']) . ',default_dept_id=' . db_input($var['default_dept_id']) . ',default_priority_id=' . db_input($var['default_priority_id']) . ',default_template_id=' . db_input($var['default_template_id']) . ',default_smtp_id=' . db_input($var['default_smtp_id']) . ',spoof_default_smtp=' . db_input($var['default_smtp'] && isset($var['spoof_default_smtp']) ? 1 : 0) . ',clickable_urls=' . db_input(isset($var['clickable_urls']) ? 1 : 0) . ',allow_priority_change=' . db_input(isset($var['allow_priority_change']) ? 1 : 0) . ',use_email_priority=' . db_input(isset($var['use_email_priority']) ? 1 : 0) . ',enable_captcha=' . db_input(isset($var['enable_captcha']) ? 1 : 0) . ',enable_auto_cron=' . db_input(isset($var['enable_auto_cron']) ? 1 : 0) . ',enable_mail_fetch=' . db_input(isset($var['enable_mail_fetch']) ? 1 : 0) . ',enable_email_piping=' . db_input(isset($var['enable_email_piping']) ? 1 : 0) . ',send_sql_errors=' . db_input(isset($var['send_sql_errors']) ? 1 : 0) . ',send_login_errors=' . db_input(isset($var['send_login_errors']) ? 1 : 0) . ',save_email_headers=' . db_input(isset($var['save_email_headers']) ? 1 : 0) . ',strip_quoted_reply=' . db_input(isset($var['strip_quoted_reply']) ? 1 : 0) . ',log_ticket_activity=' . db_input(isset($var['log_ticket_activity']) ? 1 : 0) . ',ticket_autoresponder=' . db_input($var['ticket_autoresponder']) . ',message_autoresponder=' . db_input($var['message_autoresponder']) . ',ticket_notice_active=' . db_input($var['ticket_notice_active']) . ',ticket_alert_active=' . db_input($var['ticket_alert_active']) . ',ticket_alert_admin=' . db_input(isset($var['ticket_alert_admin']) ? 1 : 0) . ',ticket_alert_dept_manager=' . db_input(isset($var['ticket_alert_dept_manager']) ? 1 : 0) . ',ticket_alert_dept_members=' . db_input(isset($var['ticket_alert_dept_members']) ? 1 : 0) . ',message_alert_active=' . db_input($var['message_alert_active']) . ',message_alert_laststaff=' . db_input(isset($var['message_alert_laststaff']) ? 1 : 0) . ',message_alert_assigned=' . db_input(isset($var['message_alert_assigned']) ? 1 : 0) . ',message_alert_dept_manager=' . db_input(isset($var['message_alert_dept_manager']) ? 1 : 0) . ',note_alert_active=' . db_input($var['note_alert_active']) . ',note_alert_laststaff=' . db_input(isset($var['note_alert_laststaff']) ? 1 : 0) . ',note_alert_assigned=' . db_input(isset($var['note_alert_assigned']) ? 1 : 0) . ',note_alert_dept_manager=' . db_input(isset($var['note_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_active=' . db_input($var['overdue_alert_active']) . ',overdue_alert_assigned=' . db_input(isset($var['overdue_alert_assigned']) ? 1 : 0) . ',overdue_alert_dept_manager=' . db_input(isset($var['overdue_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_dept_members=' . db_input(isset($var['overdue_alert_dept_members']) ? 1 : 0) . ',auto_assign_reopened_tickets=' . db_input(isset($var['auto_assign_reopened_tickets']) ? 1 : 0) . ',show_assigned_tickets=' . db_input(isset($var['show_assigned_tickets']) ? 1 : 0) . ',show_answered_tickets=' . db_input(isset($var['show_answered_tickets']) ? 1 : 0) . ',hide_staff_name=' . db_input(isset($var['hide_staff_name']) ? 1 : 0) . ',overlimit_notice_active=' . db_input($var['overlimit_notice_active']) . ',random_ticket_ids=' . db_input($var['random_ticket_ids']) . ',time_format=' . db_input($var['time_format']) . ',date_format=' . db_input($var['date_format']) . ',datetime_format=' . db_input($var['datetime_format']) . ',daydatetime_format=' . db_input($var['daydatetime_format']) . ',reply_separator=' . db_input(trim($var['reply_separator'])) . ',admin_email=' . db_input($var['admin_email']) . ',helpdesk_title=' . db_input($var['helpdesk_title']) . ',helpdesk_url=' . db_input($var['helpdesk_url']) . ' WHERE id=' . $this->getId();
     //echo $sql;
     if (db_query($sql)) {
         if (db_affected_rows()) {
             //Something actually changed!!!!
             $this->reload();
             //Reload the new info.
             require_once INCLUDE_DIR . 'class.cron.php';
             Sys::purgeLogs();
             //Cleanup the logs --- too bad if it was a mistaken config.
             Cron::TicketMonitor();
             //Age & cleanup
         }
         return true;
     }
     return false;
 }
 function updateEmailsSettings($vars, &$errors)
 {
     $f = array();
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Default email required');
     $f['alert_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Selection required');
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => 'System admin email required');
     if ($vars['strip_quoted_reply'] && !trim($vars['reply_separator'])) {
         $errors['reply_separator'] = 'Reply separator required to strip quoted reply.';
     }
     if ($vars['admin_email'] && Email::getIdByEmail($vars['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = 'Email already setup as system email';
     }
     if (!Validator::process($f, $vars, $errors) || $errors) {
         return false;
     }
     return $this->updateAll(array('default_email_id' => $vars['default_email_id'], 'alert_email_id' => $vars['alert_email_id'], 'default_smtp_id' => $vars['default_smtp_id'], 'admin_email' => $vars['admin_email'], 'enable_auto_cron' => isset($vars['enable_auto_cron']) ? 1 : 0, 'enable_mail_polling' => isset($vars['enable_mail_polling']) ? 1 : 0, 'strip_quoted_reply' => isset($vars['strip_quoted_reply']) ? 1 : 0, 'reply_separator' => $vars['reply_separator']));
 }
 function save($id, $vars, &$errors)
 {
     global $cfg;
     //very basic checks
     if ($id && $id != $vars['email_id']) {
         $errors['err'] = 'Internal error.';
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Valid email required';
     } elseif (($eid = Email::getIdByEmail($vars['email'])) && $eid != $id) {
         $errors['email'] = 'Email already exits';
     } elseif (!strcasecmp($cfg->getAdminEmail(), $vars['email'])) {
         $errors['email'] = 'Email already used as admin email!';
     } else {
         //make sure the email doesn't belong to any of the staff
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE email=' . db_input($vars['email']);
         if (($res = db_query($sql)) && db_num_rows($res)) {
             $errors['email'] = 'Email in-use by a staff member';
         }
     }
     if (!$vars['dept_id'] || !is_numeric($vars['dept_id'])) {
         $errors['dept_id'] = 'You must select a Dept.';
     }
     if (!$vars['priority_id']) {
         $errors['priority_id'] = 'You must select a priority';
     }
     if ($vars['mail_active'] || $vars['smtp_active'] && $vars['smtp_auth']) {
         if (!$vars['userid']) {
             $errors['userid'] = 'Username missing';
         }
         if (!$vars['userpass']) {
             $errors['userpass'] = '******';
         }
     }
     if ($vars['mail_active']) {
         //Check pop/imapinfo only when enabled.
         if (!function_exists('imap_open')) {
             $errors['mail_active'] = 'IMAP doesn\'t exist. PHP must be compiled with IMAP enabled.';
         }
         if (!$vars['mail_host']) {
             $errors['mail_host'] = 'Host name required';
         }
         if (!$vars['mail_port']) {
             $errors['mail_port'] = 'Port required';
         }
         if (!$vars['mail_protocol']) {
             $errors['mail_protocol'] = 'Select protocol';
         }
         if (!$vars['mail_fetchfreq'] || !is_numeric($vars['mail_fetchfreq'])) {
             $errors['mail_fetchfreq'] = 'Fetch interval required';
         }
         if (!$vars['mail_fetchmax'] || !is_numeric($vars['mail_fetchmax'])) {
             $errors['mail_fetchmax'] = 'Maximum emails required';
         }
     }
     if ($vars['smtp_active']) {
         if (!$vars['smtp_host']) {
             $errors['smtp_host'] = 'Host name required';
         }
         if (!$vars['smtp_port']) {
             $errors['smtp_port'] = 'Port required';
         }
     }
     if (!$errors && ($vars['mail_host'] && $vars['userid'])) {
         $sql = 'SELECT email_id FROM ' . EMAIL_TABLE . ' WHERE mail_host=' . db_input($vars['mail_host']) . ' AND userid=' . db_input($vars['userid']);
         if ($id) {
             $sql .= ' AND email_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['userid'] = $errors['host'] = 'Another department using host/username combination.';
         }
     }
     if (!$errors && $vars['mail_active']) {
         //note: password is unencrypted at this point...MailFetcher expect plain text.
         $fetcher = new MailFetcher($vars['userid'], $vars['userpass'], $vars['mail_host'], $vars['mail_port'], $vars['mail_protocol'], $vars['mail_encryption']);
         if (!$fetcher->connect()) {
             $errors['userpass'] = '******' . $vars['mail_protocol'] . ' settings';
             $errors['mail'] = '<br>' . $fetcher->getLastError();
         }
     }
     if (!$errors && $vars['smtp_active']) {
         //Check SMTP login only.
         require_once 'Mail.php';
         // PEAR Mail package
         $smtp = mail::factory('smtp', array('host' => $vars['smtp_host'], 'port' => $vars['smtp_port'], 'auth' => $vars['smtp_auth'] ? true : false, 'username' => $vars['userid'], 'password' => $vars['userpass'], 'timeout' => 20, 'debug' => false));
         $mail = $smtp->connect();
         if (PEAR::isError($mail)) {
             $errors['userpass'] = '******';
             $errors['smtp'] = '<br>' . $mail->getMessage();
         } else {
             $smtp->disconnect();
             //Thank you, sir!
         }
     }
     if (!$errors) {
         $sql = 'updated=NOW(),mail_errors=0, mail_lastfetch=NULL' . ',email=' . db_input($vars['email']) . ',name=' . db_input(Format::striptags($vars['name'])) . ',dept_id=' . db_input($vars['dept_id']) . ',priority_id=' . db_input($vars['priority_id']) . ',noautoresp=' . db_input(isset($vars['noautoresp']) ? 1 : 0) . ',userid=' . db_input($vars['userid']) . ',userpass='******'userpass'], SECRET_SALT)) . ',mail_active=' . db_input($vars['mail_active']) . ',mail_host=' . db_input($vars['mail_host']) . ',mail_protocol=' . db_input($vars['mail_protocol'] ? $vars['mail_protocol'] : 'POP') . ',mail_encryption=' . db_input($vars['mail_encryption']) . ',mail_port=' . db_input($vars['mail_port'] ? $vars['mail_port'] : 0) . ',mail_fetchfreq=' . db_input($vars['mail_fetchfreq'] ? $vars['mail_fetchfreq'] : 0) . ',mail_fetchmax=' . db_input($vars['mail_fetchmax'] ? $vars['mail_fetchmax'] : 0) . ',mail_delete=' . db_input(isset($vars['mail_delete']) ? $vars['mail_delete'] : 0) . ',smtp_active=' . db_input($vars['smtp_active']) . ',smtp_host=' . db_input($vars['smtp_host']) . ',smtp_port=' . db_input($vars['smtp_port'] ? $vars['smtp_port'] : 0) . ',smtp_auth=' . db_input($vars['smtp_auth']);
         if ($id) {
             //update
             $sql = 'UPDATE ' . EMAIL_TABLE . ' SET ' . $sql . ' WHERE email_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = 'Unable to update email. Internal error occured';
             }
         } else {
             $sql = 'INSERT INTO ' . EMAIL_TABLE . ' SET ' . $sql . ',created=NOW()';
             if (!db_query($sql) or !($emailID = db_insert_id())) {
                 $errors['err'] = 'Unable to add email. Internal error';
             } else {
                 return $emailID;
             }
             //newly created email.
         }
     } else {
         $errors['err'] = 'Error(s) Occured. Try again';
     }
     return $errors ? FALSE : TRUE;
 }
 function getHeaderInfo($mid)
 {
     if (!($headerinfo = imap_headerinfo($this->mbox, $mid)) || !$headerinfo->from) {
         return null;
     }
     $raw_header = $this->getHeader($mid);
     $info = array('raw_header' => &$raw_header, 'headers' => $headerinfo, 'decoder' => $this, 'type' => $this->getMimeType($headerinfo));
     Signal::send('mail.decoded', $this, $info);
     $sender = $headerinfo->from[0];
     //Just what we need...
     $header = array('name' => $this->mime_decode(@$sender->personal), 'email' => trim(strtolower($sender->mailbox) . '@' . $sender->host), 'subject' => $this->mime_decode(@$headerinfo->subject), 'mid' => trim(@$headerinfo->message_id), 'header' => $raw_header, 'in-reply-to' => $headerinfo->in_reply_to, 'references' => $headerinfo->references);
     if ($replyto = $headerinfo->reply_to) {
         $header['reply-to'] = $replyto[0]->mailbox . '@' . $replyto[0]->host;
         $header['reply-to-name'] = $replyto[0]->personal;
     }
     // Put together a list of recipients
     $tolist = array();
     if ($headerinfo->to) {
         $tolist['to'] = $headerinfo->to;
     }
     if ($headerinfo->cc) {
         $tolist['cc'] = $headerinfo->cc;
     }
     //Add delivered-to address to list.
     if (stripos($header['header'], 'delivered-to:') !== false && ($dt = Mail_Parse::findHeaderEntry($header['header'], 'delivered-to', true))) {
         if ($delivered_to = Mail_Parse::parseAddressList($dt)) {
             $tolist['delivered-to'] = $delivered_to;
         }
     }
     $header['recipients'] = array();
     foreach ($tolist as $source => $list) {
         foreach ($list as $addr) {
             if (!($emailId = Email::getIdByEmail(strtolower($addr->mailbox) . '@' . $addr->host))) {
                 //Skip virtual Delivered-To addresses
                 if ($source == 'delivered-to') {
                     continue;
                 }
                 $header['recipients'][] = array('source' => sprintf(_S("Email (%s)"), $source), 'name' => $this->mime_decode(@$addr->personal), 'email' => strtolower($addr->mailbox) . '@' . $addr->host);
             } elseif (!$header['emailId']) {
                 $header['emailId'] = $emailId;
             }
         }
     }
     //See if any of the recipients is a delivered to address
     if ($tolist['delivered-to']) {
         foreach ($tolist['delivered-to'] as $addr) {
             foreach ($header['recipients'] as $i => $r) {
                 if (strcasecmp($r['email'], $addr->mailbox . '@' . $addr->host) === 0) {
                     $header['recipients'][$i]['source'] = 'delivered-to';
                 }
             }
         }
     }
     //BCCed?
     if (!$header['emailId']) {
         if ($headerinfo->bcc) {
             foreach ($headerinfo->bcc as $addr) {
                 if ($header['emailId'] = Email::getIdByEmail(strtolower($addr->mailbox) . '@' . $addr->host)) {
                     break;
                 }
             }
         }
     }
     // Ensure we have a message-id. If unable to read it out of the
     // email, use the hash of the entire email headers
     if (!$header['mid'] && $header['header']) {
         $header['mid'] = Mail_Parse::findHeaderEntry($header['header'], 'message-id');
         if (is_array($header['mid'])) {
             $header['mid'] = array_pop(array_filter($header['mid']));
         }
         if (!$header['mid']) {
             $header['mid'] = '<' . md5($header['header']) . '@local>';
         }
     }
     return $header;
 }
 function updatePref($var, &$errors)
 {
     if (!$var || $errors) {
         return false;
     }
     $f = array();
     $f['helpdesk_url'] = array('type' => 'string', 'required' => 1, 'error' => 'Helpdesk URl required');
     //TODO: Add url validation
     $f['helpdesk_title'] = array('type' => 'string', 'required' => 1, 'error' => 'Helpdesk title required');
     $f['default_dept_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Default Dept. required');
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Default email required');
     $f['default_template_id'] = array('type' => 'int', 'required' => 1, 'error' => 'You must select template.');
     $f['staff_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Enter idle time in minutes');
     $f['client_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Enter idle time in minutes');
     $f['time_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Time format required');
     //TODO: Add date format validation
     $f['date_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Date format required');
     $f['datetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Datetime format required');
     $f['daydatetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Day, Datetime format required');
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => 'Valid email required');
     $f['autolock_minutes'] = array('type' => 'int', 'required' => 1, 'error' => 'Enter lock time in minutes');
     //TODO: check option fields for validity.
     //do the validation.
     $val = new Validator();
     $val->setFields($f);
     if (!$val->validate($var)) {
         $errors = array_merge($errors, $val->errors());
     }
     if ($var['ticket_alert_active'] && (!isset($var['ticket_alert_admin']) && !isset($var['ticket_alert_dept_manager']) && !isset($var['ticket_alert_dept_members']))) {
         $errors['ticket_alert_active'] = 'No target recipient(s) selected';
     }
     if ($var['message_alert_active'] && (!isset($var['message_alert_laststaff']) && !isset($var['message_alert_assigned']) && !isset($var['message_alert_dept_manager']))) {
         $errors['message_alert_active'] = 'No target recipient(s) selected';
     }
     if ($var['note_alert_active'] && (!isset($var['note_alert_laststaff']) && !isset($var['note_alert_assigned']) && !isset($var['note_alert_dept_manager']))) {
         $errors['note_alert_active'] = 'No target recipient(s) selected';
     }
     if ($var['strip_quoted_reply'] && !$var['reply_separator']) {
         $errors['reply_separator'] = 'Reply separator required (?)';
     }
     if ($var['enable_captcha']) {
         if (!extension_loaded('gd')) {
             $errors['enable_captcha'] = 'The GD extension required';
         } elseif (!function_exists('imagepng')) {
             $errors['enable_captcha'] = 'PNG support required for Image Captcha';
         }
     }
     if (!$errors['admin_email'] && Email::getIdByEmail($var['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = 'Email already setup as system email';
     }
     if ($errors) {
         return false;
     }
     //No go!
     //We are good to go...blanket update!
     $sql = 'UPDATE ' . CONFIG_TABLE . ' SET isonline=' . db_input($var['isonline']) . ',timezone_offset=' . db_input($var['timezone_offset']) . ',enable_daylight_saving=' . db_input(isset($var['enable_daylight_saving']) ? 1 : 0) . ',staff_ip_binding=' . db_input(isset($var['staff_ip_binding']) ? 1 : 0) . ',staff_max_logins=' . db_input($var['staff_max_logins']) . ',staff_login_timeout=' . db_input($var['staff_login_timeout']) . ',staff_session_timeout=' . db_input($var['staff_session_timeout']) . ',client_max_logins=' . db_input($var['client_max_logins']) . ',client_login_timeout=' . db_input($var['client_login_timeout']) . ',client_session_timeout=' . db_input($var['client_session_timeout']) . ',max_page_size=' . db_input($var['max_page_size']) . ',log_level=' . db_input($var['log_level']) . ',log_graceperiod=' . db_input($var['log_graceperiod']) . ',max_open_tickets=' . db_input($var['max_open_tickets']) . ',autolock_minutes=' . db_input($var['autolock_minutes']) . ',overdue_grace_period=' . db_input($var['overdue_grace_period']) . ',alert_email_id=' . db_input($var['alert_email_id']) . ',default_email_id=' . db_input($var['default_email_id']) . ',default_dept_id=' . db_input($var['default_dept_id']) . ',default_priority_id=' . db_input($var['default_priority_id']) . ',default_template_id=' . db_input($var['default_template_id']) . ',default_smtp_id=' . db_input($var['default_smtp_id']) . ',spoof_default_smtp=' . db_input($var['default_smtp'] && isset($var['spoof_default_smtp']) ? 1 : 0) . ',clickable_urls=' . db_input(isset($var['clickable_urls']) ? 1 : 0) . ',allow_priority_change=' . db_input(isset($var['allow_priority_change']) ? 1 : 0) . ',use_email_priority=' . db_input(isset($var['use_email_priority']) ? 1 : 0) . ',enable_captcha=' . db_input(isset($var['enable_captcha']) ? 1 : 0) . ',enable_auto_cron=' . db_input(isset($var['enable_auto_cron']) ? 1 : 0) . ',enable_mail_fetch=' . db_input(isset($var['enable_mail_fetch']) ? 1 : 0) . ',enable_email_piping=' . db_input(isset($var['enable_email_piping']) ? 1 : 0) . ',send_sql_errors=' . db_input(isset($var['send_sql_errors']) ? 1 : 0) . ',send_login_errors=' . db_input(isset($var['send_login_errors']) ? 1 : 0) . ',save_email_headers=' . db_input(isset($var['save_email_headers']) ? 1 : 0) . ',strip_quoted_reply=' . db_input(isset($var['strip_quoted_reply']) ? 1 : 0) . ',log_ticket_activity=' . db_input(isset($var['log_ticket_activity']) ? 1 : 0) . ',ticket_autoresponder=' . db_input($var['ticket_autoresponder']) . ',message_autoresponder=' . db_input($var['message_autoresponder']) . ',ticket_notice_active=' . db_input($var['ticket_notice_active']) . ',ticket_alert_active=' . db_input($var['ticket_alert_active']) . ',ticket_alert_admin=' . db_input(isset($var['ticket_alert_admin']) ? 1 : 0) . ',ticket_alert_dept_manager=' . db_input(isset($var['ticket_alert_dept_manager']) ? 1 : 0) . ',ticket_alert_dept_members=' . db_input(isset($var['ticket_alert_dept_members']) ? 1 : 0) . ',message_alert_active=' . db_input($var['message_alert_active']) . ',message_alert_laststaff=' . db_input(isset($var['message_alert_laststaff']) ? 1 : 0) . ',message_alert_assigned=' . db_input(isset($var['message_alert_assigned']) ? 1 : 0) . ',message_alert_dept_manager=' . db_input(isset($var['message_alert_dept_manager']) ? 1 : 0) . ',note_alert_active=' . db_input($var['note_alert_active']) . ',note_alert_laststaff=' . db_input(isset($var['note_alert_laststaff']) ? 1 : 0) . ',note_alert_assigned=' . db_input(isset($var['note_alert_assigned']) ? 1 : 0) . ',note_alert_dept_manager=' . db_input(isset($var['note_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_active=' . db_input($var['overdue_alert_active']) . ',overdue_alert_assigned=' . db_input(isset($var['overdue_alert_assigned']) ? 1 : 0) . ',overdue_alert_dept_manager=' . db_input(isset($var['overdue_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_dept_members=' . db_input(isset($var['overdue_alert_dept_members']) ? 1 : 0) . ',auto_assign_reopened_tickets=' . db_input(isset($var['auto_assign_reopened_tickets']) ? 1 : 0) . ',show_assigned_tickets=' . db_input(isset($var['show_assigned_tickets']) ? 1 : 0) . ',show_answered_tickets=' . db_input(isset($var['show_answered_tickets']) ? 1 : 0) . ',hide_staff_name=' . db_input(isset($var['hide_staff_name']) ? 1 : 0) . ',overlimit_notice_active=' . db_input($var['overlimit_notice_active']) . ',random_ticket_ids=' . db_input($var['random_ticket_ids']) . ',time_format=' . db_input($var['time_format']) . ',date_format=' . db_input($var['date_format']) . ',datetime_format=' . db_input($var['datetime_format']) . ',daydatetime_format=' . db_input($var['daydatetime_format']) . ',reply_separator=' . db_input(trim($var['reply_separator'])) . ',admin_email=' . db_input($var['admin_email']) . ',helpdesk_title=' . db_input($var['helpdesk_title']) . ',helpdesk_url=' . db_input($var['helpdesk_url']) . ' WHERE id=' . $this->getId();
     //echo $sql;
     if (db_query($sql)) {
         if (db_affected_rows()) {
             //Something actually changed!!!!
             $this->reload();
             //Reload the new info.
             require_once INCLUDE_DIR . 'class.cron.php';
             Sys::purgeLogs();
             //Cleanup the logs --- too bad if it was a mistaken config.
             Cron::TicketMonitor();
             //Age & cleanup
         }
         return true;
     }
     return false;
 }
Beispiel #7
0
 function updateEmailsSettings($vars, &$errors)
 {
     $f = array();
     $f['default_template_id'] = array('type' => 'int', 'required' => 1, 'error' => __('You must select template'));
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => __('Default email is required'));
     $f['alert_email_id'] = array('type' => 'int', 'required' => 1, 'error' => __('Selection required'));
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => __('System admin email is required'));
     if ($vars['strip_quoted_reply'] && !trim($vars['reply_separator'])) {
         $errors['reply_separator'] = __('Reply separator is required to strip quoted reply.');
     }
     if ($vars['admin_email'] && Email::getIdByEmail($vars['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = __('Email already setup as system email');
     }
     if (!Validator::process($f, $vars, $errors) || $errors) {
         return false;
     }
     return $this->updateAll(array('default_template_id' => $vars['default_template_id'], 'default_email_id' => $vars['default_email_id'], 'alert_email_id' => $vars['alert_email_id'], 'default_smtp_id' => $vars['default_smtp_id'], 'admin_email' => $vars['admin_email'], 'verify_email_addrs' => isset($vars['verify_email_addrs']) ? 1 : 0, 'enable_auto_cron' => isset($vars['enable_auto_cron']) ? 1 : 0, 'enable_mail_polling' => isset($vars['enable_mail_polling']) ? 1 : 0, 'strip_quoted_reply' => isset($vars['strip_quoted_reply']) ? 1 : 0, 'use_email_priority' => isset($vars['use_email_priority']) ? 1 : 0, 'accept_unregistered_email' => isset($vars['accept_unregistered_email']) ? 1 : 0, 'add_email_collabs' => isset($vars['add_email_collabs']) ? 1 : 0, 'reply_separator' => $vars['reply_separator'], 'email_attachments' => isset($vars['email_attachments']) ? 1 : 0));
 }
Beispiel #8
0
 static function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $ost, $cfg, $thisclient, $_FILES;
     // Don't enforce form validation for email
     $field_filter = function ($type) use($origin) {
         return function ($f) use($origin, $type) {
             // Ultimately, only offer validation errors for web for
             // non-internal fields. For email, no validation can be
             // performed. For other origins, validate as usual
             switch (strtolower($origin)) {
                 case 'email':
                     return false;
                 case 'staff':
                     // Required 'Contact Information' fields aren't required
                     // when staff open tickets
                     return $type != 'user' || in_array($f->get('name'), array('name', 'email'));
                 case 'web':
                     return !$f->get('private');
                 default:
                     return true;
             }
         };
     };
     $reject_ticket = function ($message) use(&$errors) {
         global $ost;
         $errors = array('errno' => 403, 'err' => __('This help desk is for use by authorized users only'));
         $ost->logWarning(_S('Ticket Denied'), $message, false);
         return 0;
     };
     Signal::send('ticket.create.before', null, $vars);
     // Create and verify the dynamic form entry for the new ticket
     $form = TicketForm::getNewInstance();
     $form->setSource($vars);
     // If submitting via email or api, ensure we have a subject and such
     if (!in_array(strtolower($origin), array('web', 'staff'))) {
         foreach ($form->getFields() as $field) {
             $fname = $field->get('name');
             if ($fname && isset($vars[$fname]) && !$field->value) {
                 $field->value = $field->parse($vars[$fname]);
             }
         }
     }
     if (!$form->isValid($field_filter('ticket'))) {
         $errors += $form->errors();
     }
     /*INICIO
       Creado por Anthony Parisi
       2016-02-01
       Con las siguientes lineas de código, se crea el ticket mediante la API.*/
     if (!in_array(strtolower($origin), array('web', 'staff'))) {
         $errors = array();
     }
     /* FIN */
     if ($vars['uid']) {
         $user = User::lookup($vars['uid']);
     }
     $id = 0;
     $fields = array();
     $fields['message'] = array('type' => '*', 'required' => 1, 'error' => __('Message content is required'));
     switch (strtolower($origin)) {
         case 'web':
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Select a help topic'));
             break;
         case 'staff':
             $fields['deptId'] = array('type' => 'int', 'required' => 0, 'error' => __('Department selection is required'));
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Help topic selection is required'));
             $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => __('Invalid date format - must be MM/DD/YY'));
         case 'api':
             $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => __('Indicate ticket source'));
             break;
         case 'email':
             $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => __('Unknown system email'));
             break;
         default:
             # TODO: Return error message
             $errors['err'] = $errors['origin'] = __('Invalid ticket origin given');
     }
     if (!Validator::process($fields, $vars, $errors) && !$errors['err']) {
         $errors['err'] = __('Missing or invalid data - check the errors and try again');
     }
     //Make sure the due date is valid
     if ($vars['duedate']) {
         if (!$vars['time'] || strpos($vars['time'], ':') === false) {
             $errors['time'] = __('Select a time from the list');
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) {
             $errors['duedate'] = __('Invalid due date');
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) {
             $errors['duedate'] = __('Due date must be in the future');
         }
     }
     if (!$errors) {
         # Perform ticket filter actions on the new ticket arguments
         $__form = null;
         if ($vars['topicId']) {
             if (($__topic = Topic::lookup($vars['topicId'])) && ($__form = $__topic->getForm())) {
                 $__form = $__form->instanciate();
                 $__form->setSource($vars);
             }
         }
         try {
             $vars = self::filterTicketData($origin, $vars, array($form, $__form), $user);
         } catch (RejectedException $ex) {
             return $reject_ticket(sprintf(_S('Ticket rejected (%s) by filter "%s"'), $ex->vars['email'], $ex->getRejectingFilter()->getName()));
         }
         //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL)
         if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($_user = TicketUser::lookupByEmail($vars['email'])) && ($openTickets = $_user->getNumOpenTickets()) && $openTickets >= $cfg->getMaxOpenTickets()) {
             $errors = array('err' => __("You've reached the maximum open tickets allowed."));
             $ost->logWarning(sprintf(_S('Ticket denied - %s'), $vars['email']), sprintf(_S('Max open tickets (%1$d) reached for %2$s'), $cfg->getMaxOpenTickets(), $vars['email']), false);
             return 0;
         }
         // Allow vars to be changed in ticket filter and applied to the user
         // account created or detected
         if (!$user && $vars['email']) {
             $user = User::lookupByEmail($vars['email']);
         }
         if (!$user) {
             // Reject emails if not from registered clients (if
             // configured)
             if (strcasecmp($origin, 'email') === 0 && !$cfg->acceptUnregisteredEmail()) {
                 list($mailbox, $domain) = explode('@', $vars['email'], 2);
                 // Users not yet created but linked to an organization
                 // are still acceptable
                 if (!Organization::forDomain($domain)) {
                     return $reject_ticket(sprintf(_S('Ticket rejected (%s) (unregistered client)'), $vars['email']));
                 }
             }
             $user_form = UserForm::getUserForm()->getForm($vars);
             if (!$user_form->isValid($field_filter('user')) || !($user = User::fromVars($user_form->getClean()))) {
                 $errors['user'] = __('Incomplete client information');
             }
         }
     }
     if ($vars['topicId']) {
         if ($topic = Topic::lookup($vars['topicId'])) {
             if ($topic_form = $topic->getForm()) {
                 $TF = $topic_form->getForm($vars);
                 $topic_form = $topic_form->instanciate();
                 $topic_form->setSource($vars);
                 if (!$TF->isValid($field_filter('topic'))) {
                     $errors = array_merge($errors, $TF->errors());
                 }
             }
         } else {
             $errors['topicId'] = 'Invalid help topic selected';
         }
     }
     // Any error above is fatal.
     if ($errors) {
         return 0;
     }
     Signal::send('ticket.create.validated', null, $vars);
     # Some things will need to be unpacked back into the scope of this
     # function
     if (isset($vars['autorespond'])) {
         $autorespond = $vars['autorespond'];
     }
     # Apply filter-specific priority
     if ($vars['priorityId']) {
         $form->setAnswer('priority', null, $vars['priorityId']);
     }
     // If the filter specifies a help topic which has a form associated,
     // and there was previously either no help topic set or the help
     // topic did not have a form, there's no need to add it now as (1)
     // validation is closed, (2) there may be a form already associated
     // and filled out from the original  help topic, and (3) staff
     // members can always add more forms now
     // OK...just do it.
     $statusId = $vars['statusId'];
     $deptId = $vars['deptId'];
     //pre-selected Dept if any.
     $source = ucfirst($vars['source']);
     // Apply email settings for emailed tickets. Email settings should
     // trump help topic settins if the email has an associated help
     // topic
     if ($vars['emailId'] && ($email = Email::lookup($vars['emailId']))) {
         $deptId = $deptId ?: $email->getDeptId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $email->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $email->autoRespond();
         }
         if (!isset($topic) && ($T = $email->getTopic()) && $T->isActive()) {
             $topic = $T;
         }
         $email = null;
         $source = 'Email';
     }
     if (!isset($topic)) {
         // This may return NULL, no big deal
         $topic = $cfg->getDefaultTopic();
     }
     // Intenal mapping magic...see if we need to override anything
     if (isset($topic)) {
         $deptId = $deptId ?: $topic->getDeptId();
         $statusId = $statusId ?: $topic->getStatusId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $topic->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $topic->autoRespond();
         }
         //Auto assignment.
         if (!isset($vars['staffId']) && $topic->getStaffId()) {
             $vars['staffId'] = $topic->getStaffId();
         } elseif (!isset($vars['teamId']) && $topic->getTeamId()) {
             $vars['teamId'] = $topic->getTeamId();
         }
         //set default sla.
         if (isset($vars['slaId'])) {
             $vars['slaId'] = $vars['slaId'] ?: $cfg->getDefaultSLAId();
         } elseif ($topic && $topic->getSLAId()) {
             $vars['slaId'] = $topic->getSLAId();
         }
     }
     // Auto assignment to organization account manager
     if (($org = $user->getOrganization()) && $org->autoAssignAccountManager() && ($code = $org->getAccountManagerId())) {
         if (!isset($vars['staffId']) && $code[0] == 's') {
             $vars['staffId'] = substr($code, 1);
         } elseif (!isset($vars['teamId']) && $code[0] == 't') {
             $vars['teamId'] = substr($code, 1);
         }
     }
     // Last minute checks
     $priority = $form->getAnswer('priority');
     if (!$priority || !$priority->getIdValue()) {
         $form->setAnswer('priority', null, $cfg->getDefaultPriorityId());
     }
     $deptId = $deptId ?: $cfg->getDefaultDeptId();
     $statusId = $statusId ?: $cfg->getDefaultTicketStatusId();
     $topicId = isset($topic) ? $topic->getId() : 0;
     $ipaddress = $vars['ip'] ?: $_SERVER['REMOTE_ADDR'];
     $source = $source ?: 'Web';
     //We are ready son...hold on to the rails.
     $number = $topic ? $topic->getNewTicketNumber() : $cfg->getNewTicketNumber();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,user_id=' . db_input($user->getId()) . ' ,`number`=' . db_input($number) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source);
     if (isset($vars['emailId']) && $vars['emailId']) {
         $sql .= ', email_id=' . db_input($vars['emailId']);
     }
     //Make sure the origin is staff - avoid firebug hack!
     if ($vars['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time'])));
     }
     if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) {
         return null;
     }
     /* -------------------- POST CREATE ------------------------ */
     // Save the (common) dynamic form
     $form->setTicketId($id);
     $form->save();
     // Save the form data from the help-topic form, if any
     if ($topic_form) {
         $topic_form->setTicketId($id);
         $topic_form->save();
     }
     $ticket->loadDynamicData();
     $dept = $ticket->getDept();
     // Add organizational collaborators
     if ($org && $org->autoAddCollabs()) {
         $pris = $org->autoAddPrimaryContactsAsCollabs();
         $members = $org->autoAddMembersAsCollabs();
         $settings = array('isactive' => true);
         $collabs = array();
         foreach ($org->allMembers() as $u) {
             if ($members || $pris && $u->isPrimaryContact()) {
                 if ($c = $ticket->addCollaborator($u, $settings, $errors)) {
                     $collabs[] = (string) $c;
                 }
             }
         }
         //TODO: Can collaborators add others?
         if ($collabs) {
             //TODO: Change EndUser to name of  user.
             $ticket->logNote(sprintf(_S('Collaborators for %s organization added'), $org->getName()), implode("<br>", $collabs), $org->getName(), false);
         }
     }
     //post the message.
     $vars['title'] = $vars['subject'];
     //Use the initial subject as title of the post.
     $vars['userId'] = $ticket->getUserId();
     $message = $ticket->postMessage($vars, $origin, false);
     // Configure service-level-agreement for this ticket
     $ticket->selectSLAId($vars['slaId']);
     // Assign ticket to staff or team (new ticket by staff)
     if ($vars['assignId']) {
         $ticket->assign($vars['assignId'], $vars['note']);
     } else {
         // Auto assign staff or team - auto assignment based on filter
         // rules. Both team and staff can be assigned
         if ($vars['staffId']) {
             $ticket->assignToStaff($vars['staffId'], _S('Auto Assignment'));
         }
         if ($vars['teamId']) {
             // No team alert if also assigned to an individual agent
             $ticket->assignToTeam($vars['teamId'], _S('Auto Assignment'), !$vars['staffId']);
         }
     }
     // Apply requested status — this should be done AFTER assignment,
     // because if it is requested to be closed, it should not cause the
     // ticket to be reopened for assignment.
     if ($statusId) {
         $ticket->setStatus($statusId, false, false);
     }
     /**********   double check auto-response  ************/
     //Override auto responder if the FROM email is one of the internal emails...loop control.
     if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
         $autorespond = false;
     }
     # Messages that are clearly auto-responses from email systems should
     # not have a return 'ping' message
     if (isset($vars['flags']) && $vars['flags']['bounce']) {
         $autorespond = false;
     }
     if ($autorespond && $message->isAutoReply()) {
         $autorespond = false;
     }
     //post canned auto-response IF any (disables new ticket auto-response).
     if ($vars['cannedResponseId'] && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) {
         $ticket->markUnAnswered();
         //Leave the ticket as unanswred.
         $autorespond = false;
     }
     //Check department's auto response settings
     // XXX: Dept. setting doesn't affect canned responses.
     if ($autorespond && $dept && !$dept->autoRespONNewTicket()) {
         $autorespond = false;
     }
     //Don't send alerts to staff when the message is a bounce
     //  this is necessary to avoid possible loop (especially on new ticket)
     if ($alertstaff && $message->isBounce()) {
         $alertstaff = false;
     }
     /***** See if we need to send some alerts ****/
     $ticket->onNewTicket($message, $autorespond, $alertstaff);
     /************ check if the user JUST reached the max. open tickets limit **********/
     if ($cfg->getMaxOpenTickets() > 0 && ($user = $ticket->getOwner()) && $user->getNumOpenTickets() == $cfg->getMaxOpenTickets()) {
         $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff'));
     }
     /* Start tracking ticket lifecycle events */
     $ticket->logEvent('created');
     // Fire post-create signal (for extra email sending, searching)
     Signal::send('model.created', $ticket);
     /*INICIO
       Anthony Parisi
       2016-02-05
       Con las siguientes lineas de código, se actualizan los campos de 
       Detalle de su Solicitud en las tablas descritas en la Sentencia SQL*/
     if (!in_array(strtolower($origin), array('web', 'staff'))) {
         //echo "<pre>";
         //var_dump($vars);
         //die($vars['valores']);
         foreach ($ticket as $key => $value) {
             if ($key == "id") {
                 $ticket_idAPI = $value;
             }
             if ($key == "last_message") {
                 $last_message = $value;
                 $datos = explode("\n", $last_message);
                 $nombre = $vars['name'];
                 $correo = $vars['email'];
                 $telefono = $vars['phone'];
                 $valores = $vars['valores'];
                 $adicional = explode("%%", $valores);
                 //die($adicional[4]);
                 /*$nombre   = ucwords(strtolower(substr($datos[0], 20, strlen($datos[0])-21)));
                   $correo   = strtolower(substr($datos[1], 20, strlen($datos[1])-21));
                   $telefono = substr($datos[2], 22, strlen($datos[2])-23);
                   $i        = 5;
                   $mensaje  = "";
                   while(strpos($datos[$i], "------------------------------------------------------") === false){
                       $mensaje .= $datos[$i];
                       $i++;
                   }
                   for($i=5;$i < (count($datos)-6);$i++){
                       if(strpos($datos[$i], "TIPO DE PASAJE: ") > -1)
                           $pasaje = substr($datos[$i], 28, strlen($datos[$i])-29);
                       elseif(strpos($datos[$i], "CIUDAD DE ORIGEN: ") > -1)
                           $origen = substr($datos[$i], 18, strlen($datos[$i])-19);
                       elseif(strpos($datos[$i], "CIUDAD DE DESTINO: ") > -1)
                           $destino = substr($datos[$i], 21, strlen($datos[$i])-22);
                       elseif(strpos($datos[$i], "FECHA DE SALIDA: ") > -1)
                           $salida = substr($datos[$i], 17, strlen($datos[$i])-18);
                       elseif(strpos($datos[$i], "FECHA DE REGRESO: ") > -1)
                           $regreso = substr($datos[$i], 20, strlen($datos[$i])-21);
                       elseif(strpos($datos[$i], "CLASE: ") > -1)
                           $clase = substr($datos[$i], 19, strlen($datos[$i])-20);
                       elseif(strpos($datos[$i], "AEROL") > -1)
                           $aerolinea = substr($datos[$i], 14, strlen($datos[$i])-15);
                   }
                   $adultos = substr($datos[count($datos)-5], 9, strlen($datos[count($datos)-5])-10);
                   $mayores = substr($datos[count($datos)-4], 11, strlen($datos[count($datos)-4])-12);
                   $ninos = substr($datos[count($datos)-3], 9, strlen($datos[count($datos)-3])-10);
                   $bebes = substr($datos[count($datos)-2], 8, strlen($datos[count($datos)-2])-9);*/
             }
         }
         $detail = '{"88":"Cotizacion PopPup"}';
         $mysqli = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);
         $mysqli->query("UPDATE `ost_form_entry_values` SET `value` = '{$detail}' WHERE field_id = '20' AND `entry_id` = (SELECT id FROM ost_form_entry WHERE object_id = '{$ticket_idAPI}' AND object_type = 'T');");
         $mysqli->query("INSERT INTO `ost_ticket__cdata` SET `subject`='88', `ticket_id`= '{$ticket_idAPI}' ON DUPLICATE KEY UPDATE `subject`='88';");
         $sqlUser = $mysqli->query("SELECT id FROM ost_user WHERE id = '" . $user->getId() . "' AND `org_id` = 30 LIMIT 1;");
         $rowUser = mysqli_num_rows($sqlUser);
         if ($rowUser <= 0) {
             $mysqli->query("UPDATE ost_user SET `org_id` = 30, `updated` = NOW() WHERE id = " . $user->getId() . " LIMIT 1;");
         }
         $mysqli->query("INSERT INTO \n                                `ost_cotizaciones` (\n                                    `ticket_id`, \n                                    `nombre`, \n                                    `correo`, \n                                    `telefono`, \n                                    `mensaje`, \n                                    `tipo_vuelo`, \n                                    `origen`, \n                                    `destino`, \n                                    `salida`, \n                                    `regreso`, \n                                    `clase`, \n                                    `aerolinea`, \n                                    `adultos`, \n                                    `mayores`, \n                                    `ninos`, \n                                    `bebe`) \n                                VALUES (\n                                    '{$ticket_idAPI}', \n                                    '{$nombre}', \n                                    '{$correo}', \n                                    '{$telefono}', \n                                    '{$adicional['0']}', \n                                    '{$adicional['1']}', \n                                    '{$adicional['2']}', \n                                    '{$adicional['3']}', \n                                    '{$adicional['4']}', \n                                    '{$adicional['5']}', \n                                    '{$adicional['6']}', \n                                    '{$adicional['7']}', \n                                    '{$adicional['8']}', \n                                    '{$adicional['9']}', \n                                    '{$adicional['10']}', \n                                    '{$adicional['11']}');");
     }
     /* FIN */
     /* Phew! ... time for tea (KETEPA) */
     return $ticket;
 }
 function save($id, $vars, &$errors)
 {
     global $cfg;
     //very basic checks
     if ($id && $id != $vars['email_id']) {
         $errors['err'] = 'Erro interno.';
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Email válido obrigatório';
     } elseif (($eid = Email::getIdByEmail($vars['email'])) && $eid != $id) {
         $errors['email'] = 'Email já existe.';
     } elseif (!strcasecmp($cfg->getAdminEmail(), $vars['email'])) {
         $errors['email'] = 'Email já usado como email do administrador!';
     } else {
         //make sure the email doesn't belong to any of the staff
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE email=' . db_input($vars['email']);
         if (($res = db_query($sql)) && db_num_rows($res)) {
             $errors['email'] = 'Email em uso por um membro do suporte.';
         }
     }
     if (!$vars['dept_id'] || !is_numeric($vars['dept_id'])) {
         $errors['dept_id'] = 'Você deve selecionar um departamento.';
     }
     if (!$vars['priority_id']) {
         $errors['priority_id'] = 'Você deve selecionar uma prioridade';
     }
     if ($vars['mail_active'] || $vars['smtp_active'] && $vars['smtp_auth']) {
         if (!$vars['userid']) {
             $errors['userid'] = 'Nome de usuário ausente';
         }
         if (!$vars['userpass']) {
             $errors['userpass'] = '******';
         }
     }
     if ($vars['mail_active']) {
         //Check pop/imapinfo only when enabled.
         if (!function_exists('imap_open')) {
             $errors['mail_active'] = 'IMAP não existe. PHP deve ser compilado com IMAP habilitado.';
         }
         if (!$vars['mail_host']) {
             $errors['mail_host'] = 'Nome do host obrigatório';
         }
         if (!$vars['mail_port']) {
             $errors['mail_port'] = 'Porta obrigatória';
         }
         if (!$vars['mail_protocol']) {
             $errors['mail_protocol'] = 'Selecione protocolo';
         }
         if (!$vars['mail_fetchfreq'] || !is_numeric($vars['mail_fetchfreq'])) {
             $errors['mail_fetchfreq'] = 'Buscar intervalo obrigatório';
         }
         if (!$vars['mail_fetchmax'] || !is_numeric($vars['mail_fetchmax'])) {
             $errors['mail_fetchmax'] = 'Máximo de emails exigidos';
         }
     }
     if ($vars['smtp_active']) {
         if (!$vars['smtp_host']) {
             $errors['smtp_host'] = 'Nome do host obrigatório';
         }
         if (!$vars['smtp_port']) {
             $errors['smtp_port'] = 'Porta obrigatória';
         }
     }
     if (!$errors && ($vars['mail_host'] && $vars['userid'])) {
         $sql = 'SELECT email_id FROM ' . EMAIL_TABLE . ' WHERE mail_host=' . db_input($vars['mail_host']) . ' AND userid=' . db_input($vars['userid']);
         if ($id) {
             $sql .= ' AND email_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['userid'] = $errors['host'] = 'Outro departamento está usando combinação de nome/host.';
         }
     }
     if (!$errors && $vars['mail_active']) {
         //note: password is unencrypted at this point...MailFetcher expect plain text.
         $fetcher = new MailFetcher($vars['userid'], $vars['userpass'], $vars['mail_host'], $vars['mail_port'], $vars['mail_protocol'], $vars['mail_encryption']);
         if (!$fetcher->connect()) {
             $errors['userpass'] = '******' . $vars['mail_protocol'] . ' configurações';
             $errors['mail'] = '<br>' . $fetcher->getLastError();
         }
     }
     if (!$errors && $vars['smtp_active']) {
         //Check SMTP login only.
         require_once 'Mail.php';
         // PEAR Mail package
         $smtp = mail::factory('smtp', array('host' => $vars['smtp_host'], 'port' => $vars['smtp_port'], 'auth' => $vars['smtp_auth'] ? true : false, 'username' => $vars['userid'], 'password' => $vars['userpass'], 'timeout' => 20, 'debug' => false));
         $mail = $smtp->connect();
         if (PEAR::isError($mail)) {
             $errors['userpass'] = '******';
             $errors['smtp'] = '<br>' . $mail->getMessage();
         } else {
             $smtp->disconnect();
             //Thank you, sir!
         }
     }
     if (!$errors) {
         $sql = 'updated=NOW(),mail_errors=0, mail_lastfetch=NULL' . ',email=' . db_input($vars['email']) . ',name=' . db_input(Format::striptags($vars['name'])) . ',dept_id=' . db_input($vars['dept_id']) . ',priority_id=' . db_input($vars['priority_id']) . ',noautoresp=' . db_input(isset($vars['noautoresp']) ? 1 : 0) . ',userid=' . db_input($vars['userid']) . ',userpass='******'userpass'], SECRET_SALT)) . ',mail_active=' . db_input($vars['mail_active']) . ',mail_host=' . db_input($vars['mail_host']) . ',mail_protocol=' . db_input($vars['mail_protocol'] ? $vars['mail_protocol'] : 'POP') . ',mail_encryption=' . db_input($vars['mail_encryption']) . ',mail_port=' . db_input($vars['mail_port'] ? $vars['mail_port'] : 0) . ',mail_fetchfreq=' . db_input($vars['mail_fetchfreq'] ? $vars['mail_fetchfreq'] : 0) . ',mail_fetchmax=' . db_input($vars['mail_fetchmax'] ? $vars['mail_fetchmax'] : 0) . ',mail_delete=' . db_input(isset($vars['mail_delete']) ? $vars['mail_delete'] : 0) . ',smtp_active=' . db_input($vars['smtp_active']) . ',smtp_host=' . db_input($vars['smtp_host']) . ',smtp_port=' . db_input($vars['smtp_port'] ? $vars['smtp_port'] : 0) . ',smtp_auth=' . db_input($vars['smtp_auth']);
         if ($id) {
             //update
             $sql = 'UPDATE ' . EMAIL_TABLE . ' SET ' . $sql . ' WHERE email_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = 'Não é possível atualizar e-mail. Erro interno';
             }
         } else {
             $sql = 'INSERT INTO ' . EMAIL_TABLE . ' SET ' . $sql . ',created=NOW()';
             if (!db_query($sql) or !($emailID = db_insert_id())) {
                 $errors['err'] = 'Não é possível adicionar e-mail. Erro interno';
             } else {
                 return $emailID;
             }
             //newly created email.
         }
     } else {
         $errors['err'] = 'Erro(s). Tente novamente';
     }
     return $errors ? FALSE : TRUE;
 }
Beispiel #10
0
 /**
  * postEmail
  *
  * After some security and sanity checks, attaches the body and subject
  * of the message in reply to this thread item
  *
  * Parameters:
  * mailinfo - (array) of information about the email, with at least the
  *          following keys
  *      - mid - (string) email message-id
  *      - name - (string) personal name of email originator
  *      - email - (string<email>) originating email address
  *      - subject - (string) email subject line (decoded)
  *      - body - (string) email message body (decoded)
  */
 function postEmail($mailinfo)
 {
     // +==================+===================+=============+
     // | Orig Thread-Type | Reply Thread-Type | Requires    |
     // +==================+===================+=============+
     // | *                | Message (M)       | From: Owner |
     // | *                | Note (N)          | From: Staff |
     // | Response (R)     | Message (M)       |             |
     // | Message (M)      | Response (R)      | From: Staff |
     // +------------------+-------------------+-------------+
     if (!($ticket = $this->getTicket())) {
         // Kind of hard to continue a discussion without a ticket ...
         return false;
     } elseif ($this->getEmailMessageId() == $mailinfo['mid']) {
         // Reporting success so the email can be moved or deleted.
         return true;
     }
     $vars = array('mid' => $mailinfo['mid'], 'header' => $mailinfo['header'], 'ticketId' => $ticket->getId(), 'poster' => $mailinfo['name'], 'origin' => 'Email', 'source' => 'Email', 'ip' => '', 'reply_to' => $this);
     if (isset($mailinfo['attachments'])) {
         $vars['attachments'] = $mailinfo['attachments'];
     }
     $body = $mailinfo['message'];
     // Disambiguate if the user happens also to be a staff member of the
     // system. The current ticket owner should _always_ post messages
     // instead of notes or responses
     if (strcasecmp($mailinfo['email'], $ticket->getEmail()) == 0) {
         $vars['message'] = $body;
         return $ticket->postMessage($vars, 'Email');
     } elseif ($staff_id = Staff::getIdByEmail($mailinfo['email'])) {
         $vars['staffId'] = $staff_id;
         $poster = Staff::lookup($staff_id);
         $errors = array();
         $vars['note'] = $body;
         return $ticket->postNote($vars, $errors, $poster);
     } elseif (Email::getIdByEmail($mailinfo['email'])) {
         // Don't process the email -- it came FROM this system
         return true;
     } else {
         $vars['message'] = sprintf("Received From: %s\n\n%s", $mailinfo['email'], $body);
         return $ticket->postMessage($vars, 'Email');
     }
     // Currently impossible, but indicate that this thread object could
     // not append the incoming email.
     return false;
 }
 /**
  * postEmail
  *
  * After some security and sanity checks, attaches the body and subject
  * of the message in reply to this thread item
  *
  * Parameters:
  * mailinfo - (array) of information about the email, with at least the
  *          following keys
  *      - mid - (string) email message-id
  *      - name - (string) personal name of email originator
  *      - email - (string<email>) originating email address
  *      - subject - (string) email subject line (decoded)
  *      - body - (string) email message body (decoded)
  */
 function postEmail($mailinfo)
 {
     global $ost;
     // +==================+===================+=============+
     // | Orig Thread-Type | Reply Thread-Type | Requires    |
     // +==================+===================+=============+
     // | *                | Message (M)       | From: Owner |
     // | *                | Note (N)          | From: Staff |
     // | Response (R)     | Message (M)       |             |
     // | Message (M)      | Response (R)      | From: Staff |
     // +------------------+-------------------+-------------+
     if (!($ticket = $this->getTicket())) {
         // Kind of hard to continue a discussion without a ticket ...
         return false;
     } elseif ($this->getEmailMessageId() == $mailinfo['mid']) {
         // Reporting success so the email can be moved or deleted.
         return true;
     }
     // Mail sent by this system will have a message-id format of
     // <*****@*****.**>
     // where code is a predictable string based on the SECRET_SALT of
     // this osTicket installation. If this incoming mail matches the
     // code, then it very likely originated from this system and looped
     @(list($code) = explode('-', $mailinfo['mid'], 2));
     if (0 === strcasecmp(ltrim($code, '<'), substr(md5('mail' . SECRET_SALT), -9))) {
         // This mail was sent by this system. It was received due to
         // some kind of mail delivery loop. It should not be considered
         // a response to an existing thread entry
         if ($ost) {
             $ost->log(LOG_ERR, _S('Email loop detected'), sprintf(_S('It appears as though &lt;%s&gt; is being used as a forwarded or fetched email account and is also being used as a user / system account. Please correct the loop or seek technical assistance.'), $mailinfo['email']), false, true);
         }
         return true;
     }
     $vars = array('mid' => $mailinfo['mid'], 'header' => $mailinfo['header'], 'ticketId' => $ticket->getId(), 'poster' => $mailinfo['name'], 'origin' => 'Email', 'source' => 'Email', 'ip' => '', 'reply_to' => $this, 'recipients' => $mailinfo['recipients'], 'to-email-id' => $mailinfo['to-email-id']);
     $errors = array();
     if (isset($mailinfo['attachments'])) {
         $vars['attachments'] = $mailinfo['attachments'];
     }
     $body = $mailinfo['message'];
     // Disambiguate if the user happens also to be a staff member of the
     // system. The current ticket owner should _always_ post messages
     // instead of notes or responses
     if ($mailinfo['userId'] || strcasecmp($mailinfo['email'], $ticket->getEmail()) == 0) {
         $vars['message'] = $body;
         $vars['userId'] = $mailinfo['userId'] ? $mailinfo['userId'] : $ticket->getUserId();
         return $ticket->postMessage($vars, 'Email');
     } elseif ($mailinfo['staffId'] || ($mailinfo['staffId'] = Staff::getIdByEmail($mailinfo['email']))) {
         $vars['staffId'] = $mailinfo['staffId'];
         $poster = Staff::lookup($mailinfo['staffId']);
         $vars['note'] = $body;
         return $ticket->postNote($vars, $errors, $poster);
     } elseif (Email::getIdByEmail($mailinfo['email'])) {
         // Don't process the email -- it came FROM this system
         return true;
     } elseif (isset($mailinfo['thread-type'])) {
         switch ($mailinfo['thread-type']) {
             case 'N':
                 $vars['note'] = $body;
                 $poster = $mailinfo['email'];
                 return $ticket->postNote($vars, $errors, $poster);
         }
     } else {
         //XXX: Are we potentially leaking the email address to
         // collaborators?
         $vars['message'] = sprintf("Received From: %s\n\n%s", $mailinfo['email'], $body);
         $vars['userId'] = 0;
         //Unknown user! //XXX: Assume ticket owner?
         return $ticket->postMessage($vars, 'Email');
     }
     // Currently impossible, but indicate that this thread object could
     // not append the incoming email.
     return false;
 }
 function getHeaderInfo($mid)
 {
     if (!($headerinfo = imap_headerinfo($this->mbox, $mid)) || !$headerinfo->from) {
         return null;
     }
     $sender = $headerinfo->from[0];
     //Just what we need...
     $header = array('name' => @$sender->personal, 'email' => trim(strtolower($sender->mailbox) . '@' . $sender->host), 'subject' => @$headerinfo->subject, 'mid' => trim(@$headerinfo->message_id), 'header' => $this->getHeader($mid), 'in-reply-to' => $headerinfo->in_reply_to, 'references' => $headerinfo->references);
     if ($replyto = $headerinfo->reply_to) {
         $header['reply-to'] = $replyto[0]->mailbox . '@' . $replyto[0]->host;
         $header['reply-to-name'] = $replyto[0]->personal;
     }
     //Try to determine target email - useful when fetched inbox has
     // aliases that are independent emails within osTicket.
     $emailId = 0;
     $tolist = array();
     if ($headerinfo->to) {
         $tolist = array_merge($tolist, $headerinfo->to);
     }
     if ($headerinfo->cc) {
         $tolist = array_merge($tolist, $headerinfo->cc);
     }
     if ($headerinfo->bcc) {
         $tolist = array_merge($tolist, $headerinfo->bcc);
     }
     foreach ($tolist as $addr) {
         if ($emailId = Email::getIdByEmail(strtolower($addr->mailbox) . '@' . $addr->host)) {
             break;
         }
     }
     $header['emailId'] = $emailId;
     // Ensure we have a message-id. If unable to read it out of the
     // email, use the hash of the entire email headers
     if (!$header['mid'] && $header['header']) {
         if (!($header['mid'] = Mail_Parse::findHeaderEntry($header['header'], 'message-id'))) {
             $header['mid'] = '<' . md5($header['header']) . '@local>';
         }
     }
     return $header;
 }
 function save($id, $vars, &$errors)
 {
     if ($id && $id != $vars['staff_id']) {
         $errors['err'] = _('Internal Error');
     }
     if (!$vars['firstname'] || !$vars['lastname']) {
         $errors['name'] = _('First and last name required');
     }
     if (!$vars['username'] || strlen($vars['username']) < 3) {
         $errors['username'] = _('Username required');
     } else {
         //check if the username is already in-use.
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE username='******'username']);
         if ($id) {
             $sql .= ' AND staff_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['username'] = _('Username already in-use');
         }
     }
     // Check email.
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = _('Valid email required');
     } elseif (Email::getIdByEmail($vars['email'])) {
         $errors['email'] = _('Already in-use system email');
     } else {
         //check if the email is already in-use.
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE email=' . db_input($vars['email']);
         if ($id) {
             $sql .= ' AND staff_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['email'] = _('Already in-use email');
         }
     }
     if ($vars['phone'] && !Validator::is_phone($vars['phone'])) {
         $errors['phone'] = _('Valid number required');
     }
     if ($vars['mobile'] && !Validator::is_phone($vars['mobile'])) {
         $errors['mobile'] = _('Valid number required');
     }
     // Chek password
     if ($vars['npassword'] || $vars['vpassword'] || !$id) {
         if (!$vars['npassword'] && !$id) {
             $errors['npassword'] = _('Temp password required');
         } elseif ($vars['npassword'] && strcmp($vars['npassword'], $vars['vpassword'])) {
             $errors['vpassword'] = _('Password(s) do not match');
         } elseif ($vars['npassword'] && strlen($vars['npassword']) < 6) {
             $errors['npassword'] = _('Must be at least 6 characters');
         } elseif ($vars['npassword'] && strlen($vars['npassword']) > 128) {
             $errors['npassword'] = _('Password too long');
         }
     }
     // Check department
     if (!$vars['dept_id']) {
         $errors['dept'] = _('Department required');
     } elseif ($id && $this->getDeptId() != $vars['dept_id']) {
         //check if the user is still dept. manager.
         $sql = 'SELECT dept_name FROM ' . DEPT_TABLE . ' WHERE dept_id=' . db_input($this->getDeptId()) . ' AND manager_id=' . db_input($id);
         if (db_num_rows(db_query($sql))) {
             $errors['dept'] = _('The user is currently manager of his/her department');
         }
     }
     // Check if the role is select and that it remains at least one administrator
     if (!$vars['role_id']) {
         $errors['role'] = _('Role required');
     } elseif ($vars['role_id'] == "1") {
         $isadmin = "1";
     } elseif ($id && db_count('SELECT COUNT(*) FROM ' . STAFF_TABLE . ' WHERE staff_id = ' . db_input($id) . ' AND isadmin = 1') == 1 && db_count('SELECT COUNT(*) FROM ' . STAFF_TABLE . ' WHERE isadmin = 1') == 1) {
         $errors['role'] = _('At least an administrator must remain');
     } else {
         $isadmin = "0";
     }
     if (!$errors) {
         $sql = ' SET updated=NOW() ' . ',isadmin=' . db_input($isadmin) . ',isactive=' . db_input($vars['isactive']) . ',isvisible=' . db_input(isset($vars['isvisible']) ? 1 : 0) . ',onvacation=' . db_input(isset($vars['onvacation']) ? 1 : 0) . ',dept_id=' . db_input($vars['dept_id']) . ',role_id=' . db_input($vars['role_id']) . ',username='******'username'])) . ',firstname=' . db_input(Format::striptags($vars['firstname'])) . ',lastname=' . db_input(Format::striptags($vars['lastname'])) . ',email=' . db_input($vars['email']) . ',phone="' . db_input($vars['phone'], false) . '"' . ',mobile="' . db_input($vars['mobile'], false) . '"' . ',signature=' . db_input(Format::striptags($vars['signature']));
         if ($vars['npassword']) {
             $hash = PhpassHashedPass::hash($vars['npassword']);
             $sql .= ',passwd=' . db_input($hash);
         }
         if (isset($vars['resetpasswd'])) {
             $sql .= ',change_passwd=1';
         }
         if ($id) {
             $sql = 'UPDATE ' . STAFF_TABLE . ' ' . $sql . ' WHERE staff_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = _('Unable to update the user. Internal error occured');
             }
         } else {
             $sql = 'INSERT INTO ' . STAFF_TABLE . ' ' . $sql . ',created=NOW()';
             if (db_query($sql) && ($uID = db_insert_id())) {
                 return $uID;
             }
             $errors['err'] = _('Unable to create user. Internal error');
         }
     }
     return $errors ? false : true;
 }
 function parse($stream)
 {
     global $cfg;
     $contents = '';
     if (is_resource($stream)) {
         while (!feof($stream)) {
             $contents .= fread($stream, 8192);
         }
     } else {
         $contents = $stream;
     }
     $parser = new Mail_Parse($contents);
     if (!$parser->decode()) {
         //Decode...returns false on decoding errors
         return $this->err('Email parse failed [' . $parser->getError() . ']');
     }
     $data = array();
     //FROM address: who sent the email.
     if (($fromlist = $parser->getFromAddressList()) && !PEAR::isError($fromlist)) {
         $from = $fromlist[0];
         //Default.
         foreach ($fromlist as $fromobj) {
             if (!Validator::is_email($fromobj->mailbox . '@' . $fromobj->host)) {
                 continue;
             }
             $from = $fromobj;
             break;
         }
         $data['email'] = $from->mailbox . '@' . $from->host;
         $data['name'] = trim($from->personal, '"');
         if ($from->comment && $from->comment[0]) {
             $data['name'] .= ' (' . $from->comment[0] . ')';
         }
         //Use email address as name  when FROM address doesn't  have a name.
         if (!$data['name'] && $data['email']) {
             $data['name'] = $data['email'];
         }
     }
     //TO Address:Try to figure out the email address... associated with the incoming email.
     $emailId = 0;
     if ($tolist = $parser->getToAddressList()) {
         foreach ($tolist as $toaddr) {
             if ($emailId = Email::getIdByEmail($toaddr->mailbox . '@' . $toaddr->host)) {
                 break;
             }
         }
     }
     //maybe we got CC'ed??
     if (!$emailId && ($cclist = $parser->getCcAddressList())) {
         foreach ($cclist as $ccaddr) {
             if ($emailId = Email::getIdByEmail($ccaddr->mailbox . '@' . $ccaddr->host)) {
                 break;
             }
         }
     }
     $data['subject'] = $parser->getSubject();
     $data['message'] = Format::stripEmptyLines($parser->getBody());
     $data['header'] = $parser->getHeader();
     $data['mid'] = $parser->getMessageId();
     $data['priorityId'] = $parser->getPriority();
     $data['emailId'] = $emailId;
     $data['in-reply-to'] = $parser->struct->headers['in-reply-to'];
     $data['references'] = $parser->struct->headers['references'];
     if (($replyto = $parser->getReplyTo()) && !PEAR::isError($replyto)) {
         $replyto = $replyto[0];
         $data['reply-to'] = $replyto->mailbox . '@' . $replyto->host;
         if ($replyto->personal) {
             $data['reply-to-name'] = trim($replyto->personal, " \t\n\r\v\"");
         }
     }
     if ($cfg && $cfg->allowEmailAttachments()) {
         $data['attachments'] = $parser->getAttachments();
     }
     return $data;
 }
 function updatePref($var, &$errors)
 {
     if (!$var || $errors) {
         return false;
     }
     $f = array();
     $f['helpdesk_url'] = array('type' => 'string', 'required' => 1, 'error' => 'Helpdesk URL erforderlich');
     //TODO: Add url validation
     $f['helpdesk_title'] = array('type' => 'string', 'required' => 1, 'error' => 'URL del centro de ayuda Requerida');
     $f['default_dept_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Titulo Requerido');
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Departamento por defecto Requerido');
     $f['default_template_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Email pr defecto Requerido');
     $f['staff_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Debes selecionar una Plantilla');
     $f['client_session_timeout'] = array('type' => 'int', 'required' => 1, 'error' => 'Introduzca el tiempo de inactividad en minutos');
     $f['time_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de hora Requerido');
     //TODO: Add date format validation
     $f['date_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de fecha Requerido');
     $f['datetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de fecha y hora Requerido');
     $f['daydatetime_format'] = array('type' => 'string', 'required' => 1, 'error' => 'Formato de fecha con dia y hora Requerido');
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => 'Email valido Requerido');
     $f['autolock_minutes'] = array('type' => 'int', 'required' => 1, 'error' => 'Introduzca tiempo de Bloqueo en minutos');
     //TODO: check option fields for validity.
     //do the validation.
     $val = new Validator();
     $val->setFields($f);
     if (!$val->validate($var)) {
         $errors = array_merge($errors, $val->errors());
     }
     if ($var['ticket_alert_active'] && (!isset($var['ticket_alert_admin']) && !isset($var['ticket_alert_dept_manager']) && !isset($var['ticket_alert_dept_members']))) {
         $errors['ticket_alert_active'] = 'No ha selecionado un destinario';
     }
     if ($var['message_alert_active'] && (!isset($var['message_alert_laststaff']) && !isset($var['message_alert_assigned']) && !isset($var['message_alert_dept_manager']))) {
         $errors['message_alert_active'] = 'No ha selecionado un destinario';
     }
     if ($var['note_alert_active'] && (!isset($var['note_alert_laststaff']) && !isset($var['note_alert_assigned']) && !isset($var['note_alert_dept_manager']))) {
         $errors['note_alert_active'] = 'No ha selecionado un destinario';
     }
     if ($var['strip_quoted_reply'] && !$var['reply_separator']) {
         $errors['reply_separator'] = 'Separador de respuesta Requerido (?)';
     }
     if ($var['enable_captcha']) {
         if (!extension_loaded('gd')) {
             $errors['enable_captcha'] = 'La extensi&oacute;n GD es Requerida';
         } elseif (!function_exists('imagepng')) {
             $errors['enable_captcha'] = 'PNG debe ser soportado para el Capcha';
         }
     }
     if (!$errors['admin_email'] && Email::getIdByEmail($var['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = 'Esta cuenta de correo ya esta siendo utilizada como cuenta del Sistema';
     }
     if ($errors) {
         return false;
     }
     //No go!
     //We are good to go...blanket update!
     $sql = 'UPDATE ' . CONFIG_TABLE . ' SET isonline=' . db_input($var['isonline']) . ',timezone_offset=' . db_input($var['timezone_offset']) . ',enable_daylight_saving=' . db_input(isset($var['enable_daylight_saving']) ? 1 : 0) . ',staff_ip_binding=' . db_input(isset($var['staff_ip_binding']) ? 1 : 0) . ',staff_max_logins=' . db_input($var['staff_max_logins']) . ',staff_login_timeout=' . db_input($var['staff_login_timeout']) . ',staff_session_timeout=' . db_input($var['staff_session_timeout']) . ',client_max_logins=' . db_input($var['client_max_logins']) . ',client_login_timeout=' . db_input($var['client_login_timeout']) . ',client_session_timeout=' . db_input($var['client_session_timeout']) . ',max_page_size=' . db_input($var['max_page_size']) . ',log_level=' . db_input($var['log_level']) . ',log_graceperiod=' . db_input($var['log_graceperiod']) . ',max_open_tickets=' . db_input($var['max_open_tickets']) . ',autolock_minutes=' . db_input($var['autolock_minutes']) . ',overdue_grace_period=' . db_input($var['overdue_grace_period']) . ',alert_email_id=' . db_input($var['alert_email_id']) . ',default_email_id=' . db_input($var['default_email_id']) . ',default_dept_id=' . db_input($var['default_dept_id']) . ',default_priority_id=' . db_input($var['default_priority_id']) . ',default_template_id=' . db_input($var['default_template_id']) . ',default_smtp_id=' . db_input($var['default_smtp_id']) . ',spoof_default_smtp=' . db_input($var['default_smtp'] && isset($var['spoof_default_smtp']) ? 1 : 0) . ',clickable_urls=' . db_input(isset($var['clickable_urls']) ? 1 : 0) . ',allow_priority_change=' . db_input(isset($var['allow_priority_change']) ? 1 : 0) . ',use_email_priority=' . db_input(isset($var['use_email_priority']) ? 1 : 0) . ',enable_captcha=' . db_input(isset($var['enable_captcha']) ? 1 : 0) . ',enable_auto_cron=' . db_input(isset($var['enable_auto_cron']) ? 1 : 0) . ',enable_mail_fetch=' . db_input(isset($var['enable_mail_fetch']) ? 1 : 0) . ',enable_email_piping=' . db_input(isset($var['enable_email_piping']) ? 1 : 0) . ',send_sql_errors=' . db_input(isset($var['send_sql_errors']) ? 1 : 0) . ',send_login_errors=' . db_input(isset($var['send_login_errors']) ? 1 : 0) . ',save_email_headers=' . db_input(isset($var['save_email_headers']) ? 1 : 0) . ',strip_quoted_reply=' . db_input(isset($var['strip_quoted_reply']) ? 1 : 0) . ',log_ticket_activity=' . db_input(isset($var['log_ticket_activity']) ? 1 : 0) . ',ticket_autoresponder=' . db_input($var['ticket_autoresponder']) . ',message_autoresponder=' . db_input($var['message_autoresponder']) . ',ticket_notice_active=' . db_input($var['ticket_notice_active']) . ',ticket_alert_active=' . db_input($var['ticket_alert_active']) . ',ticket_alert_admin=' . db_input(isset($var['ticket_alert_admin']) ? 1 : 0) . ',ticket_alert_dept_manager=' . db_input(isset($var['ticket_alert_dept_manager']) ? 1 : 0) . ',ticket_alert_dept_members=' . db_input(isset($var['ticket_alert_dept_members']) ? 1 : 0) . ',message_alert_active=' . db_input($var['message_alert_active']) . ',message_alert_laststaff=' . db_input(isset($var['message_alert_laststaff']) ? 1 : 0) . ',message_alert_assigned=' . db_input(isset($var['message_alert_assigned']) ? 1 : 0) . ',message_alert_dept_manager=' . db_input(isset($var['message_alert_dept_manager']) ? 1 : 0) . ',note_alert_active=' . db_input($var['note_alert_active']) . ',note_alert_laststaff=' . db_input(isset($var['note_alert_laststaff']) ? 1 : 0) . ',note_alert_assigned=' . db_input(isset($var['note_alert_assigned']) ? 1 : 0) . ',note_alert_dept_manager=' . db_input(isset($var['note_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_active=' . db_input($var['overdue_alert_active']) . ',overdue_alert_assigned=' . db_input(isset($var['overdue_alert_assigned']) ? 1 : 0) . ',overdue_alert_dept_manager=' . db_input(isset($var['overdue_alert_dept_manager']) ? 1 : 0) . ',overdue_alert_dept_members=' . db_input(isset($var['overdue_alert_dept_members']) ? 1 : 0) . ',auto_assign_reopened_tickets=' . db_input(isset($var['auto_assign_reopened_tickets']) ? 1 : 0) . ',show_assigned_tickets=' . db_input(isset($var['show_assigned_tickets']) ? 1 : 0) . ',show_answered_tickets=' . db_input(isset($var['show_answered_tickets']) ? 1 : 0) . ',hide_staff_name=' . db_input(isset($var['hide_staff_name']) ? 1 : 0) . ',overlimit_notice_active=' . db_input($var['overlimit_notice_active']) . ',random_ticket_ids=' . db_input($var['random_ticket_ids']) . ',time_format=' . db_input($var['time_format']) . ',date_format=' . db_input($var['date_format']) . ',datetime_format=' . db_input($var['datetime_format']) . ',daydatetime_format=' . db_input($var['daydatetime_format']) . ',reply_separator=' . db_input(trim($var['reply_separator'])) . ',admin_email=' . db_input($var['admin_email']) . ',helpdesk_title=' . db_input($var['helpdesk_title']) . ',helpdesk_url=' . db_input($var['helpdesk_url']) . ' WHERE id=' . $this->getId();
     //echo $sql;
     if (db_query($sql)) {
         if (db_affected_rows()) {
             //Something actually changed!!!!
             $this->reload();
             //Reload the new info.
             require_once INCLUDE_DIR . 'class.cron.php';
             Sys::purgeLogs();
             //Cleanup the logs --- too bad if it was a mistaken config.
             Cron::TicketMonitor();
             //Age & cleanup
         }
         return true;
     }
     return false;
 }
Beispiel #16
0
 function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $cfg, $thisclient, $_FILES;
     //Check for 403
     if ($vars['email'] && Validator::is_email($vars['email'])) {
         //Make sure the email address is not banned
         if (EmailFilter::isBanned($vars['email'])) {
             $errors['err'] = 'Ticket denied. Error #403';
             Sys::log(LOG_WARNING, 'Ticket denied', 'Banned email - ' . $vars['email']);
             return 0;
         }
         //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL)
         if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($client = Client::lookupByEmail($vars['email'])) && ($openTickets = $client->getNumOpenTickets()) && $opentickets >= $cfg->getMaxOpenTickets()) {
             $errors['err'] = "You've reached the maximum open tickets allowed.";
             Sys::log(LOG_WARNING, 'Ticket denied -' . $vars['email'], sprintf('Max open tickets (%d) reached for %s ', $cfg->getMaxOpenTickets(), $vars['email']));
             return 0;
         }
     }
     // Make sure email contents should not be rejected
     if (($email_filter = new EmailFilter($vars)) && ($filter = $email_filter->shouldReject())) {
         $errors['err'] = 'Ticket denied. Error #403';
         Sys::log(LOG_WARNING, 'Ticket denied', sprintf('Banned email - %s by filter "%s"', $vars['email'], $filter->getName()));
         return 0;
     }
     $id = 0;
     $fields = array();
     $fields['name'] = array('type' => 'string', 'required' => 1, 'error' => 'Name required');
     $fields['email'] = array('type' => 'email', 'required' => 1, 'error' => 'Valid email required');
     $fields['subject'] = array('type' => 'string', 'required' => 1, 'error' => 'Subject required');
     $fields['message'] = array('type' => 'text', 'required' => 1, 'error' => 'Message required');
     switch (strtolower($origin)) {
         case 'web':
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Select help topic');
             break;
         case 'staff':
             $fields['deptId'] = array('type' => 'int', 'required' => 1, 'error' => 'Dept. required');
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Topic required');
             $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => 'Invalid date - must be MM/DD/YY');
         case 'api':
             $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => 'Indicate source');
             break;
         case 'email':
             $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => 'Email unknown');
             break;
         default:
             # TODO: Return error message
             $errors['err'] = $errors['origin'] = 'Invalid origin given';
     }
     $fields['priorityId'] = array('type' => 'int', 'required' => 0, 'error' => 'Invalid Priority');
     $fields['phone'] = array('type' => 'phone', 'required' => 0, 'error' => 'Valid phone # required');
     if (!Validator::process($fields, $vars, $errors) && !$errors['err']) {
         $errors['err'] = 'Missing or invalid data - check the errors and try again';
     }
     //Make sure phone extension is valid
     if ($vars['phone_ext']) {
         if (!is_numeric($vars['phone_ext']) && !$errors['phone']) {
             $errors['phone'] = 'Invalid phone ext.';
         } elseif (!$vars['phone']) {
             //make sure they just didn't enter ext without phone # XXX: reconsider allowing!
             $errors['phone'] = 'Phone number required';
         }
     }
     //Make sure the due date is valid
     if ($vars['duedate']) {
         if (!$vars['time'] || strpos($vars['time'], ':') === false) {
             $errors['time'] = 'Select time';
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) {
             $errors['duedate'] = 'Invalid duedate';
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) {
             $errors['duedate'] = 'Due date must be in the future';
         }
     }
     # Perform email filter actions on the new ticket arguments XXX: Move filter to the top and check for reject...
     if (!$errors && $email_filter) {
         $email_filter->apply($vars);
     }
     # Some things will need to be unpacked back into the scope of this
     # function
     if (isset($vars['autorespond'])) {
         $autorespond = $vars['autorespond'];
     }
     //Any error above is fatal.
     if ($errors) {
         return 0;
     }
     // OK...just do it.
     $deptId = $vars['deptId'];
     //pre-selected Dept if any.
     $priorityId = $vars['priorityId'];
     $source = ucfirst($vars['source']);
     $topic = NULL;
     // Intenal mapping magic...see if we need to overwrite anything
     if (isset($vars['topicId']) && ($topic = Topic::lookup($vars['topicId']))) {
         //Ticket created via web by user/or staff
         $deptId = $deptId ? $deptId : $topic->getDeptId();
         $priorityId = $priorityId ? $priorityId : $topic->getPriorityId();
         if ($autorespond) {
             $autorespond = $topic->autoRespond();
         }
         $source = $vars['source'] ? $vars['source'] : 'Web';
     } elseif ($vars['emailId'] && !$vars['deptId'] && ($email = Email::lookup($vars['emailId']))) {
         //Emailed Tickets
         $deptId = $email->getDeptId();
         $priorityId = $priorityId ? $priorityId : $email->getPriorityId();
         if ($autorespond) {
             $autorespond = $email->autoRespond();
         }
         $email = null;
         $source = 'Email';
     } elseif ($vars['deptId']) {
         //Opened by staff.
         $deptId = $vars['deptId'];
         $source = ucfirst($vars['source']);
     }
     //Last minute checks
     $priorityId = $priorityId ? $priorityId : $cfg->getDefaultPriorityId();
     $deptId = $deptId ? $deptId : $cfg->getDefaultDeptId();
     $topicId = $vars['topicId'] ? $vars['topicId'] : 0;
     $ipaddress = $vars['ip'] ? $vars['ip'] : $_SERVER['REMOTE_ADDR'];
     //We are ready son...hold on to the rails.
     $extId = Ticket::genExtRandID();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,ticketID=' . db_input($extId) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,priority_id=' . db_input($priorityId) . ' ,email=' . db_input($vars['email']) . ' ,name=' . db_input(Format::striptags($vars['name'])) . ' ,subject=' . db_input(Format::striptags($vars['subject'])) . ' ,phone="' . db_input($vars['phone'], false) . '"' . ' ,phone_ext=' . db_input($vars['phone_ext'] ? $vars['phone_ext'] : '') . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source);
     //Make sure the origin is staff - avoid firebug hack!
     if ($vars['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time'])));
     }
     if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) {
         return null;
     }
     /* -------------------- POST CREATE ------------------------ */
     $dept = $ticket->getDept();
     if (!$cfg->useRandomIds()) {
         //Sequential ticketIDs support really..really suck arse.
         $extId = $id;
         //To make things really easy we are going to use autoincrement ticket_id.
         db_query('UPDATE ' . TICKET_TABLE . ' SET ticketID=' . db_input($extId) . ' WHERE ticket_id=' . $id . ' LIMIT 1');
         //TODO: RETHING what happens if this fails?? [At the moment on failure random ID is used...making stuff usable]
     }
     //post the message.
     $msgid = $ticket->postMessage($vars['message'], $source, $vars['mid'], $vars['header'], true);
     // Configure service-level-agreement for this ticket
     $ticket->selectSLAId($vars['slaId']);
     //Auto assign staff or team - auto assignment based on filter rules.
     if ($vars['staffId'] && !$vars['assignId']) {
         $ticket->assignToStaff($vars['staffId'], 'auto-assignment');
     }
     if ($vars['teamId'] && !$vars['assignId']) {
         $ticket->assignToTeam($vars['teamId'], 'auto-assignment');
     }
     /**********   double check auto-response  ************/
     //Overwrite auto responder if the FROM email is one of the internal emails...loop control.
     if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
         $autorespond = false;
     }
     if ($autorespond && $dept && !$dept->autoRespONNewTicket()) {
         $autorespond = false;
     }
     # Messages that are clearly auto-responses from email systems should
     # not have a return 'ping' message
     if ($autorespond && $vars['header'] && EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) {
         $autorespond = false;
     }
     //Don't auto respond to mailer daemons.
     if ($autorespond && (strpos(strtolower($vars['email']), 'mailer-daemon@') !== false || strpos(strtolower($vars['email']), 'postmaster@') !== false)) {
         $autorespond = false;
     }
     /***** See if we need to send some alerts ****/
     $ticket->onNewTicket($vars['message'], $autorespond, $alertstaff);
     /************ check if the user JUST reached the max. open tickets limit **********/
     if ($cfg->getMaxOpenTickets() > 0 && ($client = $ticket->getClient()) && $client->getNumOpenTickets() == $cfg->getMaxOpenTickets()) {
         $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff'));
     }
     /* Phew! ... time for tea (KETEPA) */
     return $ticket;
 }
Beispiel #17
0
 function save($id, $vars, &$errors)
 {
     $vars['username'] = Format::striptags($vars['username']);
     $vars['firstname'] = Format::striptags($vars['firstname']);
     $vars['lastname'] = Format::striptags($vars['lastname']);
     if ($id && $id != $vars['id']) {
         $errors['err'] = 'Internal Error';
     }
     if (!$vars['firstname']) {
         $errors['firstname'] = 'First name required';
     }
     if (!$vars['lastname']) {
         $errors['lastname'] = 'Last name required';
     }
     $error = '';
     if (!$vars['username'] || !Validator::is_username($vars['username'], $error)) {
         $errors['username'] = $error ? $error : 'Username required';
     } elseif (($uid = Staff::getIdByUsername($vars['username'])) && $uid != $id) {
         $errors['username'] = '******';
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Valid email required';
     } elseif (Email::getIdByEmail($vars['email'])) {
         $errors['email'] = 'Already in-use system email';
     } elseif (($uid = Staff::getIdByEmail($vars['email'])) && $uid != $id) {
         $errors['email'] = 'Email already in use by another staff member';
     }
     if ($vars['phone'] && !Validator::is_phone($vars['phone'])) {
         $errors['phone'] = 'Valid number required';
     }
     if ($vars['mobile'] && !Validator::is_phone($vars['mobile'])) {
         $errors['mobile'] = 'Valid number required';
     }
     if ($vars['passwd1'] || $vars['passwd2'] || !$id) {
         if ($vars['passwd1'] && strcmp($vars['passwd1'], $vars['passwd2'])) {
             $errors['passwd2'] = 'Password(s) do not match';
         } elseif ($vars['backend'] != 'local' || $vars['welcome_email']) {
             // Password can be omitted
         } elseif (!$vars['passwd1'] && !$id) {
             $errors['passwd1'] = 'Temp. password required';
             $errors['temppasswd'] = 'Required';
         } elseif ($vars['passwd1'] && strlen($vars['passwd1']) < 6) {
             $errors['passwd1'] = 'Must be at least 6 characters';
         }
     }
     if (!$vars['dept_id']) {
         $errors['dept_id'] = 'Department required';
     }
     if (!$vars['group_id']) {
         $errors['group_id'] = 'Group required';
     }
     if (!$vars['timezone_id']) {
         $errors['timezone_id'] = 'Time zone required';
     }
     if ($errors) {
         return false;
     }
     $sql = 'SET updated=NOW() ' . ' ,isadmin=' . db_input($vars['isadmin']) . ' ,isactive=' . db_input($vars['isactive']) . ' ,isvisible=' . db_input(isset($vars['isvisible']) ? 1 : 0) . ' ,onvacation=' . db_input(isset($vars['onvacation']) ? 1 : 0) . ' ,assigned_only=' . db_input(isset($vars['assigned_only']) ? 1 : 0) . ' ,dept_id=' . db_input($vars['dept_id']) . ' ,group_id=' . db_input($vars['group_id']) . ' ,timezone_id=' . db_input($vars['timezone_id']) . ' ,daylight_saving=' . db_input(isset($vars['daylight_saving']) ? 1 : 0) . ' ,username='******'username']) . ' ,firstname=' . db_input($vars['firstname']) . ' ,lastname=' . db_input($vars['lastname']) . ' ,email=' . db_input($vars['email']) . ' ,backend=' . db_input($vars['backend']) . ' ,phone="' . db_input(Format::phone($vars['phone']), false) . '"' . ' ,phone_ext=' . db_input($vars['phone_ext']) . ' ,mobile="' . db_input(Format::phone($vars['mobile']), false) . '"' . ' ,signature=' . db_input(Format::sanitize($vars['signature'])) . ' ,notes=' . db_input(Format::sanitize($vars['notes']));
     if ($vars['passwd1']) {
         $sql .= ' ,passwd=' . db_input(Passwd::hash($vars['passwd1']));
         if (isset($vars['change_passwd'])) {
             $sql .= ' ,change_passwd=1';
         }
     } elseif (!isset($vars['change_passwd'])) {
         $sql .= ' ,change_passwd=0';
     }
     if ($id) {
         $sql = 'UPDATE ' . STAFF_TABLE . ' ' . $sql . ' WHERE staff_id=' . db_input($id);
         if (db_query($sql) && db_affected_rows()) {
             return true;
         }
         $errors['err'] = 'Unable to update the user. Internal error occurred';
     } else {
         $sql = 'INSERT INTO ' . STAFF_TABLE . ' ' . $sql . ', created=NOW()';
         if (db_query($sql) && ($uid = db_insert_id())) {
             return $uid;
         }
         $errors['err'] = 'Unable to create user. Internal error';
     }
     return false;
 }
Beispiel #18
0
 static function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $ost, $cfg, $thisclient, $_FILES;
     // Don't enforce form validation for email
     $field_filter = function ($type) use($origin) {
         return function ($f) use($origin, $type) {
             // Ultimately, only offer validation errors for web for
             // non-internal fields. For email, no validation can be
             // performed. For other origins, validate as usual
             switch (strtolower($origin)) {
                 case 'email':
                     return false;
                 case 'staff':
                     // Required 'Contact Information' fields aren't required
                     // when staff open tickets
                     return $type != 'user' || in_array($f->get('name'), array('name', 'email'));
                 case 'web':
                     return !$f->get('private');
                 default:
                     return true;
             }
         };
     };
     $reject_ticket = function ($message) use(&$errors) {
         global $ost;
         $errors = array('errno' => 403, 'err' => __('This help desk is for use by authorized users only'));
         $ost->logWarning(_S('Ticket Denied'), $message, false);
         return 0;
     };
     Signal::send('ticket.create.before', null, $vars);
     // Create and verify the dynamic form entry for the new ticket
     $form = TicketForm::getNewInstance();
     $form->setSource($vars);
     // If submitting via email or api, ensure we have a subject and such
     if (!in_array(strtolower($origin), array('web', 'staff'))) {
         foreach ($form->getFields() as $field) {
             $fname = $field->get('name');
             if ($fname && isset($vars[$fname]) && !$field->value) {
                 $field->value = $field->parse($vars[$fname]);
             }
         }
     }
     if (!$form->isValid($field_filter('ticket'))) {
         $errors += $form->errors();
     }
     if ($vars['uid']) {
         $user = User::lookup($vars['uid']);
     }
     $id = 0;
     $fields = array();
     $fields['message'] = array('type' => '*', 'required' => 1, 'error' => __('Message content is required'));
     switch (strtolower($origin)) {
         case 'web':
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Select a help topic'));
             break;
         case 'staff':
             $fields['deptId'] = array('type' => 'int', 'required' => 0, 'error' => __('Department selection is required'));
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Help topic selection is required'));
             $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => __('Invalid date format - must be MM/DD/YY'));
         case 'api':
             $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => __('Indicate ticket source'));
             break;
         case 'email':
             $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => __('Unknown system email'));
             break;
         default:
             # TODO: Return error message
             $errors['err'] = $errors['origin'] = __('Invalid ticket origin given');
     }
     if (!Validator::process($fields, $vars, $errors) && !$errors['err']) {
         $errors['err'] = __('Missing or invalid data - check the errors and try again');
     }
     //Make sure the due date is valid
     if ($vars['duedate']) {
         if (!$vars['time'] || strpos($vars['time'], ':') === false) {
             $errors['time'] = __('Select a time from the list');
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) {
             $errors['duedate'] = __('Invalid due date');
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) {
             $errors['duedate'] = __('Due date must be in the future');
         }
     }
     if (!$errors) {
         # Perform ticket filter actions on the new ticket arguments
         $__form = null;
         if ($vars['topicId']) {
             if (($__topic = Topic::lookup($vars['topicId'])) && ($__form = $__topic->getForm())) {
                 $__form = $__form->instanciate();
                 $__form->setSource($vars);
             }
         }
         try {
             $vars = self::filterTicketData($origin, $vars, array($form, $__form), $user);
         } catch (RejectedException $ex) {
             return $reject_ticket(sprintf(_S('Ticket rejected (%s) by filter "%s"'), $ex->vars['email'], $ex->getRejectingFilter()->getName()));
         }
         //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL)
         if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($_user = TicketUser::lookupByEmail($vars['email'])) && ($openTickets = $_user->getNumOpenTickets()) && $openTickets >= $cfg->getMaxOpenTickets()) {
             $errors = array('err' => __("You've reached the maximum open tickets allowed."));
             $ost->logWarning(sprintf(_S('Ticket denied - %s'), $vars['email']), sprintf(_S('Max open tickets (%1$d) reached for %2$s'), $cfg->getMaxOpenTickets(), $vars['email']), false);
             return 0;
         }
         // Allow vars to be changed in ticket filter and applied to the user
         // account created or detected
         if (!$user && $vars['email']) {
             $user = User::lookupByEmail($vars['email']);
         }
         if (!$user) {
             // Reject emails if not from registered clients (if
             // configured)
             if (strcasecmp($origin, 'email') === 0 && !$cfg->acceptUnregisteredEmail()) {
                 list($mailbox, $domain) = explode('@', $vars['email'], 2);
                 // Users not yet created but linked to an organization
                 // are still acceptable
                 if (!Organization::forDomain($domain)) {
                     return $reject_ticket(sprintf(_S('Ticket rejected (%s) (unregistered client)'), $vars['email']));
                 }
             }
             $user_form = UserForm::getUserForm()->getForm($vars);
             if (!$user_form->isValid($field_filter('user')) || !($user = User::fromVars($user_form->getClean()))) {
                 $errors['user'] = __('Incomplete client information');
             }
         }
     }
     if ($vars['topicId']) {
         if ($topic = Topic::lookup($vars['topicId'])) {
             if ($topic_form = $topic->getForm()) {
                 $TF = $topic_form->getForm($vars);
                 $topic_form = $topic_form->instanciate();
                 $topic_form->setSource($vars);
                 if (!$TF->isValid($field_filter('topic'))) {
                     $errors = array_merge($errors, $TF->errors());
                 }
             }
         } else {
             $errors['topicId'] = 'Invalid help topic selected';
         }
     }
     // Any error above is fatal.
     if ($errors) {
         return 0;
     }
     Signal::send('ticket.create.validated', null, $vars);
     # Some things will need to be unpacked back into the scope of this
     # function
     if (isset($vars['autorespond'])) {
         $autorespond = $vars['autorespond'];
     }
     # Apply filter-specific priority
     if ($vars['priorityId']) {
         $form->setAnswer('priority', null, $vars['priorityId']);
     }
     // If the filter specifies a help topic which has a form associated,
     // and there was previously either no help topic set or the help
     // topic did not have a form, there's no need to add it now as (1)
     // validation is closed, (2) there may be a form already associated
     // and filled out from the original  help topic, and (3) staff
     // members can always add more forms now
     // OK...just do it.
     $statusId = $vars['statusId'];
     $deptId = $vars['deptId'];
     //pre-selected Dept if any.
     $source = ucfirst($vars['source']);
     // Apply email settings for emailed tickets. Email settings should
     // trump help topic settins if the email has an associated help
     // topic
     if ($vars['emailId'] && ($email = Email::lookup($vars['emailId']))) {
         $deptId = $deptId ?: $email->getDeptId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $email->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $email->autoRespond();
         }
         if (!isset($topic) && ($T = $email->getTopic()) && $T->isActive()) {
             $topic = $T;
         }
         $email = null;
         $source = 'Email';
     }
     if (!isset($topic)) {
         // This may return NULL, no big deal
         $topic = $cfg->getDefaultTopic();
     }
     // Intenal mapping magic...see if we need to override anything
     if (isset($topic)) {
         $deptId = $deptId ?: $topic->getDeptId();
         $statusId = $statusId ?: $topic->getStatusId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $topic->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $topic->autoRespond();
         }
         //Auto assignment.
         if (!isset($vars['staffId']) && $topic->getStaffId()) {
             $vars['staffId'] = $topic->getStaffId();
         } elseif (!isset($vars['teamId']) && $topic->getTeamId()) {
             $vars['teamId'] = $topic->getTeamId();
         }
         //set default sla.
         if (isset($vars['slaId'])) {
             $vars['slaId'] = $vars['slaId'] ?: $cfg->getDefaultSLAId();
         } elseif ($topic && $topic->getSLAId()) {
             $vars['slaId'] = $topic->getSLAId();
         }
     }
     // Auto assignment to organization account manager
     if (($org = $user->getOrganization()) && $org->autoAssignAccountManager() && ($code = $org->getAccountManagerId())) {
         if (!isset($vars['staffId']) && $code[0] == 's') {
             $vars['staffId'] = substr($code, 1);
         } elseif (!isset($vars['teamId']) && $code[0] == 't') {
             $vars['teamId'] = substr($code, 1);
         }
     }
     // Last minute checks
     $priority = $form->getAnswer('priority');
     if (!$priority || !$priority->getIdValue()) {
         $form->setAnswer('priority', null, $cfg->getDefaultPriorityId());
     }
     $deptId = $deptId ?: $cfg->getDefaultDeptId();
     $statusId = $statusId ?: $cfg->getDefaultTicketStatusId();
     $topicId = isset($topic) ? $topic->getId() : 0;
     $ipaddress = $vars['ip'] ?: $_SERVER['REMOTE_ADDR'];
     $source = $source ?: 'Web';
     //We are ready son...hold on to the rails.
     $number = $topic ? $topic->getNewTicketNumber() : $cfg->getNewTicketNumber();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,user_id=' . db_input($user->getId()) . ' ,`number`=' . db_input($number) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source);
     if (isset($vars['emailId']) && $vars['emailId']) {
         $sql .= ', email_id=' . db_input($vars['emailId']);
     }
     //Make sure the origin is staff - avoid firebug hack!
     if ($vars['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time'])));
     }
     if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) {
         return null;
     }
     /* -------------------- POST CREATE ------------------------ */
     // Save the (common) dynamic form
     $form->setTicketId($id);
     $form->save();
     // Save the form data from the help-topic form, if any
     if ($topic_form) {
         $topic_form->setTicketId($id);
         $topic_form->save();
     }
     $ticket->loadDynamicData();
     $dept = $ticket->getDept();
     // Add organizational collaborators
     if ($org && $org->autoAddCollabs()) {
         $pris = $org->autoAddPrimaryContactsAsCollabs();
         $members = $org->autoAddMembersAsCollabs();
         $settings = array('isactive' => true);
         $collabs = array();
         foreach ($org->allMembers() as $u) {
             if ($members || $pris && $u->isPrimaryContact()) {
                 if ($c = $ticket->addCollaborator($u, $settings, $errors)) {
                     $collabs[] = (string) $c;
                 }
             }
         }
         //TODO: Can collaborators add others?
         if ($collabs) {
             //TODO: Change EndUser to name of  user.
             $ticket->logNote(sprintf(_S('Collaborators for %s organization added'), $org->getName()), implode("<br>", $collabs), $org->getName(), false);
         }
     }
     //post the message.
     $vars['title'] = $vars['subject'];
     //Use the initial subject as title of the post.
     $vars['userId'] = $ticket->getUserId();
     $message = $ticket->postMessage($vars, $origin, false);
     // Configure service-level-agreement for this ticket
     $ticket->selectSLAId($vars['slaId']);
     // Assign ticket to staff or team (new ticket by staff)
     if ($vars['assignId']) {
         $ticket->assign($vars['assignId'], $vars['note']);
     } else {
         // Auto assign staff or team - auto assignment based on filter
         // rules. Both team and staff can be assigned
         if ($vars['staffId']) {
             $ticket->assignToStaff($vars['staffId'], _S('Auto Assignment'));
         }
         if ($vars['teamId']) {
             // No team alert if also assigned to an individual agent
             $ticket->assignToTeam($vars['teamId'], _S('Auto Assignment'), !$vars['staffId']);
         }
     }
     // Apply requested status — this should be done AFTER assignment,
     // because if it is requested to be closed, it should not cause the
     // ticket to be reopened for assignment.
     if ($statusId) {
         $ticket->setStatus($statusId, false, false);
     }
     /**********   double check auto-response  ************/
     //Override auto responder if the FROM email is one of the internal emails...loop control.
     if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
         $autorespond = false;
     }
     # Messages that are clearly auto-responses from email systems should
     # not have a return 'ping' message
     if (isset($vars['flags']) && $vars['flags']['bounce']) {
         $autorespond = false;
     }
     if ($autorespond && $message->isAutoReply()) {
         $autorespond = false;
     }
     //post canned auto-response IF any (disables new ticket auto-response).
     if ($vars['cannedResponseId'] && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) {
         $ticket->markUnAnswered();
         //Leave the ticket as unanswred.
         $autorespond = false;
     }
     //Check department's auto response settings
     // XXX: Dept. setting doesn't affect canned responses.
     if ($autorespond && $dept && !$dept->autoRespONNewTicket()) {
         $autorespond = false;
     }
     //Don't send alerts to staff when the message is a bounce
     //  this is necessary to avoid possible loop (especially on new ticket)
     if ($alertstaff && $message->isBounce()) {
         $alertstaff = false;
     }
     /***** See if we need to send some alerts ****/
     $ticket->onNewTicket($message, $autorespond, $alertstaff);
     /************ check if the user JUST reached the max. open tickets limit **********/
     if ($cfg->getMaxOpenTickets() > 0 && ($user = $ticket->getOwner()) && $user->getNumOpenTickets() == $cfg->getMaxOpenTickets()) {
         $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff'));
     }
     /* Start tracking ticket lifecycle events */
     $ticket->logEvent('created');
     // Fire post-create signal (for extra email sending, searching)
     Signal::send('model.created', $ticket);
     /* Phew! ... time for tea (KETEPA) */
     return $ticket;
 }
Beispiel #19
0
 function create($var, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $cfg, $thisclient, $_FILES;
     /* Coders never code so fully and joyfully as when they do it for free  - Peter Rotich */
     $id = 0;
     $fields = array();
     $fields['name'] = array('type' => 'string', 'required' => 1, 'error' => 'Name required');
     $fields['email'] = array('type' => 'email', 'required' => 1, 'error' => 'Valid email required');
     $fields['subject'] = array('type' => 'string', 'required' => 1, 'error' => 'Subject required');
     $fields['message'] = array('type' => 'text', 'required' => 1, 'error' => 'Message required');
     if (strcasecmp($origin, 'web') == 0) {
         //Help topic only applicable on web tickets.
         $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Select help topic');
     } elseif (strcasecmp($origin, 'staff') == 0) {
         //tickets created by staff...e.g on callins.
         $fields['deptId'] = array('type' => 'int', 'required' => 1, 'error' => 'Dept. required');
         $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => 'Indicate source');
         $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => 'Invalid date - must be MM/DD/YY');
     } else {
         //Incoming emails
         $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => 'Email unknown');
     }
     $fields['pri'] = array('type' => 'int', 'required' => 0, 'error' => 'Invalid Priority');
     $fields['phone'] = array('type' => 'phone', 'required' => 0, 'error' => 'Valid phone # required');
     $validate = new Validator($fields);
     if (!$validate->validate($var)) {
         $errors = array_merge($errors, $validate->errors());
     }
     //Make sure the email is not banned
     if (!$errors && BanList::isbanned($var['email'])) {
         $errors['err'] = 'Ticket denied. Error #403';
         //We don't want to tell the user the real reason...Psssst.
         Sys::log(LOG_WARNING, 'Ticket denied', 'Banned email - ' . $var['email']);
         //We need to let admin know which email got banned.
     }
     if (!$errors && $thisclient && strcasecmp($thisclient->getEmail(), $var['email'])) {
         $errors['email'] = 'Email mismatch.';
     }
     //Make sure phone extension is valid
     if ($var['phone_ext']) {
         if (!is_numeric($var['phone_ext']) && !$errors['phone']) {
             $errors['phone'] = 'Invalid phone ext.';
         } elseif (!$var['phone']) {
             //make sure they just didn't enter ext without phone #
             $errors['phone'] = 'Phone number required';
         }
     }
     //Make sure the due date is valid
     if ($var['duedate']) {
         if (!$var['time'] || strpos($var['time'], ':') === false) {
             $errors['time'] = 'Select time';
         } elseif (strtotime($var['duedate'] . ' ' . $var['time']) === false) {
             $errors['duedate'] = 'Invalid duedate';
         } elseif (strtotime($var['duedate'] . ' ' . $var['time']) <= time()) {
             $errors['duedate'] = 'Due date must be in the future';
         }
     }
     //check attachment..if any is set ...only set on webbased tickets..
     if ($_FILES['attachment']['name'] && $cfg->allowOnlineAttachments()) {
         if (!$cfg->canUploadFileType($_FILES['attachment']['name'])) {
             $errors['attachment'] = 'Invalid file type [ ' . Format::htmlchars($_FILES['attachment']['name']) . ' ]';
         } elseif ($_FILES['attachment']['size'] > $cfg->getMaxFileSize()) {
             $errors['attachment'] = 'File is too big. Max ' . $cfg->getMaxFileSize() . ' bytes allowed';
         }
     }
     //check ticket limits..if limit set is >0
     //TODO: Base ticket limits on SLA...
     if ($var['email'] && !$errors && $cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff')) {
         $openTickets = Ticket::getOpenTicketsByEmail($var['email']);
         if ($openTickets >= $cfg->getMaxOpenTickets()) {
             $errors['err'] = "You've reached the maximum open tickets allowed.";
             //Send the notice only once (when the limit is reached) incase of autoresponders at client end.
             if ($cfg->getMaxOpenTickets() == $openTickets && $cfg->sendOverlimitNotice()) {
                 if ($var['deptId']) {
                     $dept = new Dept($var['deptId']);
                 }
                 if (!$dept || !($tplId = $dept->getTemplateId())) {
                     $tplId = $cfg->getDefaultTemplateId();
                 }
                 $sql = 'SELECT ticket_overlimit_subj,ticket_overlimit_body FROM ' . EMAIL_TEMPLATE_TABLE . ' WHERE cfg_id=' . db_input($cfg->getId()) . ' AND tpl_id=' . db_input($tplId);
                 $resp = db_query($sql);
                 if (db_num_rows($resp) && (list($subj, $body) = db_fetch_row($resp))) {
                     $body = str_replace("%name", $var['name'], $body);
                     $body = str_replace("%email", $var['email'], $body);
                     $body = str_replace("%url", $cfg->getBaseUrl(), $body);
                     $body = str_replace('%signature', $dept && $dept->isPublic() ? $dept->getSignature() : '', $body);
                     if (!$dept || !($email = $dept->getAutoRespEmail())) {
                         $email = $cfg->getDefaultEmail();
                     }
                     if ($email) {
                         $email->send($var['email'], $subj, $body);
                     }
                 }
                 //Alert admin...this might be spammy (no option to disable)...but it is helpful..I think.
                 $msg = 'Support ticket request denied for ' . $var['email'] . "\n" . 'Open ticket:' . $openTickets . "\n" . 'Max Allowed:' . $cfg->getMaxOpenTickets() . "\n\nNotice only sent once";
                 Sys::alertAdmin('Overlimit Notice', $msg);
             }
         }
     }
     //Any error above is fatal.
     if ($errors) {
         return 0;
     }
     // OK...just do it.
     $deptId = $var['deptId'];
     //pre-selected Dept if any.
     $priorityId = $var['pri'];
     $source = ucfirst($var['source']);
     $topic = NULL;
     // Intenal mapping magic...see if we need to overwrite anything
     if (isset($var['topicId'])) {
         //Ticket created via web by user/or staff
         if ($var['topicId'] && ($topic = new Topic($var['topicId'])) && $topic->getId()) {
             $deptId = $deptId ? $deptId : $topic->getDeptId();
             $priorityId = $priorityId ? $priorityId : $topic->getPriorityId();
             $topicDesc = $topic->getName();
             if ($autorespond) {
                 $autorespond = $topic->autoRespond();
             }
         }
         $source = $var['source'] ? $var['source'] : 'Web';
     } elseif ($var['emailId'] && !$var['deptId']) {
         //Emailed Tickets
         $email = new Email($var['emailId']);
         if ($email && $email->getId()) {
             $deptId = $email->getDeptId();
             $priorityId = $priorityId ? $priorityId : $email->getPriorityId();
             if ($autorespond) {
                 $autorespond = $email->autoRespond();
             }
         }
         $email = null;
         $source = 'Email';
     } elseif ($var['deptId']) {
         //Opened by staff.
         $deptId = $var['deptId'];
         $source = ucfirst($var['source']);
     }
     //Don't auto respond to mailer daemons.
     if (strpos(strtolower($var['email']), 'mailer-daemon@') !== false || strpos(strtolower($var['email']), 'postmaster@') !== false) {
         $autorespond = false;
     }
     //Last minute checks
     $priorityId = $priorityId ? $priorityId : $cfg->getDefaultPriorityId();
     $deptId = $deptId ? $deptId : $cfg->getDefaultDeptId();
     $topicId = $var['topicId'] ? $var['topicId'] : 0;
     $ipaddress = $var['ip'] ? $var['ip'] : $_SERVER['REMOTE_ADDR'];
     //We are ready son...hold on to the rails.
     $extId = Ticket::genExtRandID();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ',ticketID=' . db_input($extId) . ',dept_id=' . db_input($deptId) . ',topic_id=' . db_input($topicId) . ',priority_id=' . db_input($priorityId) . ',email=' . db_input($var['email']) . ',name=' . db_input(Format::striptags($var['name'])) . ',subject=' . db_input(Format::striptags($var['subject'])) . ',helptopic=' . db_input(Format::striptags($topicDesc)) . ',phone="' . db_input($var['phone'], false) . '"' . ',phone_ext=' . db_input($var['phone_ext'] ? $var['phone_ext'] : '') . ',ip_address=' . db_input($ipaddress) . ',source=' . db_input($source);
     //Make sure the origin is staff - avoid firebug hack!
     if ($var['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ',duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($var['duedate'] . ' ' . $var['time'])));
     }
     //echo $sql;
     $ticket = null;
     //return $ticket;
     if (db_query($sql) && ($id = db_insert_id())) {
         if (!$cfg->useRandomIds()) {
             //Sequential ticketIDs support really..really suck arse.
             $extId = $id;
             //To make things really easy we are going to use autoincrement ticket_id.
             db_query('UPDATE ' . TICKET_TABLE . ' SET ticketID=' . db_input($extId) . ' WHERE ticket_id=' . $id);
             //TODO: RETHING what happens if this fails?? [At the moment on failure random ID is used...making stuff usable]
         }
         //Load newly created ticket.
         $ticket = new Ticket($id);
         //post the message.
         $msgid = $ticket->postMessage($var['message'], $source, $var['mid'], $var['header'], true);
         //TODO: recover from postMessage error??
         //Upload attachments...web based.
         if ($_FILES['attachment']['name'] && $cfg->allowOnlineAttachments() && $msgid) {
             if (!$cfg->allowAttachmentsOnlogin() || $cfg->allowAttachmentsOnlogin() && ($thisclient && $thisclient->isValid())) {
                 $ticket->uploadAttachment($_FILES['attachment'], $msgid, 'M');
                 //TODO: recover from upload issues?
             }
         }
         $dept = $ticket->getDept();
         if (!$dept || !($tplId = $dept->getTemplateId())) {
             $tplId = $cfg->getDefaultTemplateId();
         }
         //Overwrite auto responder if the FROM email is one of the internal emails...loop control.
         if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
             $autorespond = false;
         }
         //SEND OUT NEW TICKET AUTORESP && ALERTS.
         //New Ticket AutoResponse..
         if ($autorespond && $cfg->autoRespONNewTicket() && $dept->autoRespONNewTicket()) {
             $sql = 'SELECT ticket_autoresp_subj,ticket_autoresp_body FROM ' . EMAIL_TEMPLATE_TABLE . ' WHERE cfg_id=' . db_input($cfg->getId()) . ' AND tpl_id=' . db_input($tplId);
             if (($resp = db_query($sql)) && db_num_rows($resp) && (list($subj, $body) = db_fetch_row($resp))) {
                 $body = $ticket->replaceTemplateVars($body);
                 $subj = $ticket->replaceTemplateVars($subj);
                 $body = str_replace('%message', $var['issue'] ? $var['issue'] : $var['message'], $body);
                 $body = str_replace('%signature', $dept && $dept->isPublic() ? $dept->getSignature() : '', $body);
                 if (!$dept || !($email = $dept->getAutoRespEmail())) {
                     $email = $cfg->getDefaultEmail();
                 }
                 if ($email) {
                     //Reply separator tag.
                     if ($cfg->stripQuotedReply() && ($tag = $cfg->getReplySeparator())) {
                         $body = "\n{$tag}\n\n" . $body;
                     }
                     $email->send($ticket->getEmail(), $subj, $body);
                 }
             } else {
                 Sys::log(LOG_WARNING, 'Template Fetch Error', "Unable to fetch autoresponse template #{$tplId}");
             }
         }
         //If enabled...send alert to staff (New Ticket Alert)
         if ($alertstaff && $cfg->alertONNewTicket() && is_object($ticket)) {
             $sql = 'SELECT ticket_alert_subj,ticket_alert_body FROM ' . EMAIL_TEMPLATE_TABLE . ' WHERE cfg_id=' . db_input($cfg->getId()) . ' AND tpl_id=' . db_input($tplId);
             if (($resp = db_query($sql)) && db_num_rows($resp) && (list($subj, $body) = db_fetch_row($resp))) {
                 $body = $ticket->replaceTemplateVars($body);
                 $subj = $ticket->replaceTemplateVars($subj);
                 $body = str_replace('%message', $var['issue'] ? $var['issue'] : $var['message'], $body);
                 if (!($email = $cfg->getAlertEmail())) {
                     $email = $cfg->getDefaultEmail();
                 }
                 if ($email && $email->getId()) {
                     $sentlist = array();
                     //Admin Alert.
                     if ($cfg->alertAdminONNewTicket()) {
                         $alert = str_replace("%staff", 'Admin', $body);
                         $email->send($cfg->getAdminEmail(), $subj, $alert);
                         $sentlist[] = $cfg->getAdminEmail();
                     }
                     //get the list
                     $recipients = array();
                     //Dept. Manager
                     if ($cfg->alertDeptManagerONNewTicket()) {
                         $recipients[] = $dept->getManager();
                     }
                     //Staff members
                     if ($cfg->alertDeptMembersONNewTicket()) {
                         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE onvacation=0 AND dept_id=' . db_input($dept->getId());
                         if (($users = db_query($sql)) && db_num_rows($users)) {
                             while (list($id) = db_fetch_row($users)) {
                                 $recipients[] = new Staff($id);
                             }
                         }
                     }
                     foreach ($recipients as $k => $staff) {
                         if (!$staff || !is_object($staff) || !$staff->isAvailable()) {
                             continue;
                         }
                         if (in_array($staff->getEmail(), $sentlist)) {
                             continue;
                         }
                         //avoid duplicate emails.
                         $alert = str_replace("%staff", $staff->getFirstName(), $body);
                         $email->send($staff->getEmail(), $subj, $alert);
                         $sentlist[] = $staff->getEmail();
                     }
                 }
             } else {
                 Sys::log(LOG_WARNING, 'Template Fetch Error', "Unable to fetch 'new ticket' alert template #{$tplId}");
             }
         }
     }
     return $ticket;
 }
 function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $cfg, $thisclient, $_FILES;
     //Make sure the email is not banned
     if ($vars['email'] && EmailFilter::isBanned($vars['email'])) {
         $errors['err'] = 'Ticket denied. Error #403';
         Sys::log(LOG_WARNING, 'Ticket denied', 'Banned email - ' . $vars['email']);
         return 0;
     }
     $id = 0;
     $fields = array();
     $fields['name'] = array('type' => 'string', 'required' => 1, 'error' => 'Name required');
     $fields['email'] = array('type' => 'email', 'required' => 1, 'error' => 'Valid email required');
     $fields['subject'] = array('type' => 'string', 'required' => 1, 'error' => 'Subject required');
     $fields['message'] = array('type' => 'text', 'required' => 1, 'error' => 'Message required');
     switch (strtolower($origin)) {
         case 'web':
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Select help topic');
             break;
         case 'staff':
             $fields['deptId'] = array('type' => 'int', 'required' => 1, 'error' => 'Dept. required');
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Topic required');
             $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => 'Invalid date - must be MM/DD/YY');
         case 'api':
             $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => 'Indicate source');
             break;
         case 'email':
             $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => 'Email unknown');
             break;
         default:
             # TODO: Return error message
             $errors['origin'] = 'Invalid origin given';
     }
     $fields['pri'] = array('type' => 'int', 'required' => 0, 'error' => 'Invalid Priority');
     $fields['phone'] = array('type' => 'phone', 'required' => 0, 'error' => 'Valid phone # required');
     if (!Validator::process($fields, $vars, $errors) && !$errors['err']) {
         $errors['err'] = 'Missing or invalid data - check the errors and try again';
     }
     //Make sure phone extension is valid
     if ($vars['phone_ext']) {
         if (!is_numeric($vars['phone_ext']) && !$errors['phone']) {
             $errors['phone'] = 'Invalid phone ext.';
         } elseif (!$vars['phone']) {
             //make sure they just didn't enter ext without phone # XXX: reconsider allowing!
             $errors['phone'] = 'Phone number required';
         }
     }
     //Make sure the due date is valid
     if ($vars['duedate']) {
         if (!$vars['time'] || strpos($vars['time'], ':') === false) {
             $errors['time'] = 'Select time';
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) {
             $errors['duedate'] = 'Invalid duedate';
         } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) {
             $errors['duedate'] = 'Due date must be in the future';
         }
     }
     //check attachment..if any is set ...only set on webbased tickets..
     //XXX:?? Create ticket anyway and simply drop the attachments?? We're already doing so with emails.
     if ($_FILES['attachment']['name'] && $cfg->allowOnlineAttachments()) {
         if (!$cfg->canUploadFileType($_FILES['attachment']['name'])) {
             $errors['attachment'] = 'Invalid file type [ ' . Format::htmlchars($_FILES['attachment']['name']) . ' ]';
         } elseif ($_FILES['attachment']['size'] > $cfg->getMaxFileSize()) {
             $errors['attachment'] = 'File is too big. Max ' . $cfg->getMaxFileSize() . ' bytes allowed';
         }
     }
     # Perform email filter actions on the new ticket arguments XXX: Move filter to the top and check for reject...
     if (!$errors && ($ef = new EmailFilter($vars))) {
         $ef->apply($vars);
     }
     # Some things will need to be unpacked back into the scope of this
     # function
     if (isset($vars['autorespond'])) {
         $autorespond = $vars['autorespond'];
     }
     //check ticket limits..if limit set is >0
     //TODO: Base ticket limits on SLA... XXX: move it elsewhere??
     if ($vars['email'] && !$errors && $cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff')) {
         $openTickets = Ticket::getOpenTicketsByEmail($vars['email']);
         if ($openTickets >= $cfg->getMaxOpenTickets()) {
             $errors['err'] = "You've reached the maximum open tickets allowed.";
             //Send the notice only once (when the limit is reached) incase of autoresponders at client end.
             if ($cfg->getMaxOpenTickets() == $openTickets && $cfg->sendOverlimitNotice()) {
                 if ($vars['deptId']) {
                     $dept = Dept::lookup($vars['deptId']);
                 }
                 if (!$dept || !($tpl = $dept->getTemplate())) {
                     $tpl = $cfg->getDefaultTemplate();
                 }
                 if (!$dept || !($email = $dept->getAutoRespEmail())) {
                     $email = $cfg->getDefaultEmail();
                 }
                 if ($tpl && ($msg = $tpl->getOverlimitMsgTemplate()) && $email) {
                     $body = str_replace('%name', $vars['name'], $msg['body']);
                     $body = str_replace('%email', $vars['email'], $msg['body']);
                     $body = str_replace('%url', $cfg->getBaseUrl(), $body);
                     $body = str_replace('%signature', $dept && $dept->isPublic() ? $dept->getSignature() : '', $body);
                     $email->send($vars['email'], $msg['subj'], $body);
                 }
                 //Log + Alert admin...this might be spammy (no option to disable)...but it is helpful..I think.
                 $msg = 'Support ticket request denied for ' . $vars['email'] . "\n" . 'Open ticket:' . $openTickets . "\n" . 'Max Allowed:' . $cfg->getMaxOpenTickets() . "\n\nNotice only sent once";
                 Sys::log(LOG_CRIT, 'Overlimit Notice', $msg);
             }
         }
     }
     //Any error above is fatal.
     if ($errors) {
         return 0;
     }
     // OK...just do it.
     $deptId = $vars['deptId'];
     //pre-selected Dept if any.
     $priorityId = $vars['pri'];
     $source = ucfirst($vars['source']);
     $topic = NULL;
     // Intenal mapping magic...see if we need to overwrite anything
     if (isset($vars['topicId']) && ($topic = Topic::lookup($vars['topicId']))) {
         //Ticket created via web by user/or staff
         $deptId = $deptId ? $deptId : $topic->getDeptId();
         $priorityId = $priorityId ? $priorityId : $topic->getPriorityId();
         if ($autorespond) {
             $autorespond = $topic->autoRespond();
         }
         $source = $vars['source'] ? $vars['source'] : 'Web';
     } elseif ($vars['emailId'] && !$vars['deptId'] && ($email = Email::lookup($vars['emailId']))) {
         //Emailed Tickets
         $deptId = $email->getDeptId();
         $priorityId = $priorityId ? $priorityId : $email->getPriorityId();
         if ($autorespond) {
             $autorespond = $email->autoRespond();
         }
         $email = null;
         $source = 'Email';
     } elseif ($vars['deptId']) {
         //Opened by staff.
         $deptId = $vars['deptId'];
         $source = ucfirst($vars['source']);
     }
     //Last minute checks
     $priorityId = $priorityId ? $priorityId : $cfg->getDefaultPriorityId();
     $deptId = $deptId ? $deptId : $cfg->getDefaultDeptId();
     $topicId = $vars['topicId'] ? $vars['topicId'] : 0;
     $ipaddress = $vars['ip'] ? $vars['ip'] : $_SERVER['REMOTE_ADDR'];
     //We are ready son...hold on to the rails.
     $extId = Ticket::genExtRandID();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,ticketID=' . db_input($extId) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,priority_id=' . db_input($priorityId) . ' ,email=' . db_input($vars['email']) . ' ,name=' . db_input(Format::striptags($vars['name'])) . ' ,subject=' . db_input(Format::striptags($vars['subject'])) . ' ,phone="' . db_input($vars['phone'], false) . '"' . ' ,phone_ext=' . db_input($vars['phone_ext'] ? $vars['phone_ext'] : '') . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source);
     //Make sure the origin is staff - avoid firebug hack!
     if ($vars['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time'])));
     }
     if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) {
         return null;
     }
     /* -------------------- POST CREATE ------------------------ */
     $dept = $ticket->getDept();
     if (!$cfg->useRandomIds()) {
         //Sequential ticketIDs support really..really suck arse.
         $extId = $id;
         //To make things really easy we are going to use autoincrement ticket_id.
         db_query('UPDATE ' . TICKET_TABLE . ' SET ticketID=' . db_input($extId) . ' WHERE ticket_id=' . $id . ' LIMIT 1');
         //TODO: RETHING what happens if this fails?? [At the moment on failure random ID is used...making stuff usable]
     }
     //post the message.
     $msgid = $ticket->postMessage($vars['message'], $source, $vars['mid'], $vars['header'], true);
     //TODO: recover from postMessage error??
     //Upload attachments...web based. - XXX: Assumes user uploaded attachments!! XXX: move it to client interface.
     if ($_FILES['attachment']['name'] && $cfg->allowOnlineAttachments() && $msgid) {
         if (!$cfg->allowAttachmentsOnlogin() || $cfg->allowAttachmentsOnlogin() && ($thisuser && $thisuser->isValid())) {
             $ticket->uploadAttachment($_FILES['attachment'], $msgid, 'M');
         }
     }
     // Configure service-level-agreement for this ticket
     $ticket->selectSLAId($vars['slaId']);
     //Auto assign staff or team - auto assignment based on filter rules.
     if ($vars['staffId'] && !$vars['assignId']) {
         $ticket->assignToStaff($vars['staffId'], 'auto-assignment');
     }
     if ($vars['teamId'] && !$vars['assignId']) {
         $ticket->assignToTeam($vars['teamId'], 'auto-assignment');
     }
     /**********   double check auto-response  ************/
     //Overwrite auto responder if the FROM email is one of the internal emails...loop control.
     if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
         $autorespond = false;
     }
     if ($autorespond && $dept && !$dept->autoRespONNewTicket()) {
         $autorespond = false;
     }
     # Messages that are clearly auto-responses from email systems should
     # not have a return 'ping' message
     if ($autorespond && $vars['header'] && EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) {
         $autorespond = false;
     }
     //Don't auto respond to mailer daemons.
     if ($autorespond && (strpos(strtolower($vars['email']), 'mailer-daemon@') !== false || strpos(strtolower($vars['email']), 'postmaster@') !== false)) {
         $autorespond = false;
     }
     /***** See if we need to send some alerts ****/
     $ticket->onNewTicket($vars['message'], $autorespond, $alertstaff);
     return $ticket;
 }
Beispiel #21
0
 function save($id, $vars, &$errors)
 {
     $vars['username'] = Format::striptags($vars['username']);
     $vars['firstname'] = Format::striptags($vars['firstname']);
     $vars['lastname'] = Format::striptags($vars['lastname']);
     if ($id && $id != $vars['id']) {
         $errors['err'] = __('Internal Error');
     }
     if (!$vars['firstname']) {
         $errors['firstname'] = __('First name required');
     }
     if (!$vars['lastname']) {
         $errors['lastname'] = __('Last name required');
     }
     $error = '';
     if (!$vars['username'] || !Validator::is_username($vars['username'], $error)) {
         $errors['username'] = $error ? $error : __('Username is required');
     } elseif (($uid = Staff::getIdByUsername($vars['username'])) && $uid != $id) {
         $errors['username'] = __('Username already in use');
     }
     if (!$vars['email'] || !Validator::is_valid_email($vars['email'])) {
         $errors['email'] = __('Valid email is required');
     } elseif (Email::getIdByEmail($vars['email'])) {
         $errors['email'] = __('Already in use system email');
     } elseif (($uid = Staff::getIdByEmail($vars['email'])) && $uid != $id) {
         $errors['email'] = __('Email already in use by another agent');
     }
     if ($vars['phone'] && !Validator::is_phone($vars['phone'])) {
         $errors['phone'] = __('Valid phone number is required');
     }
     if ($vars['mobile'] && !Validator::is_phone($vars['mobile'])) {
         $errors['mobile'] = __('Valid phone number is required');
     }
     if ($vars['passwd1'] || $vars['passwd2'] || !$id) {
         if ($vars['passwd1'] && strcmp($vars['passwd1'], $vars['passwd2'])) {
             $errors['passwd2'] = __('Passwords do not match');
         } elseif ($vars['backend'] != 'local' || $vars['welcome_email']) {
             // Password can be omitted
         } elseif (!$vars['passwd1'] && !$id) {
             $errors['passwd1'] = __('Temporary password is required');
             $errors['temppasswd'] = __('Required');
         } elseif ($vars['passwd1'] && strlen($vars['passwd1']) < 6) {
             $errors['passwd1'] = __('Password must be at least 6 characters');
         }
     }
     if (!$vars['dept_id']) {
         $errors['dept_id'] = __('Department is required');
     }
     if (!$vars['group_id']) {
         $errors['group_id'] = __('Group is required');
     }
     if (!$vars['timezone_id']) {
         $errors['timezone_id'] = __('Time zone selection is required');
     }
     // Ensure we will still have an administrator with access
     if ($vars['isadmin'] !== '1' || $vars['isactive'] !== '1') {
         $sql = 'select count(*), max(staff_id) from ' . STAFF_TABLE . ' WHERE isadmin=1 and isactive=1';
         if (($res = db_query($sql)) && (list($count, $sid) = db_fetch_row($res))) {
             if ($count == 1 && $sid == $id) {
                 $errors['isadmin'] = __('Cowardly refusing to remove or lock out the only active administrator');
             }
         }
     }
     if ($errors) {
         return false;
     }
     $sql = 'SET updated=NOW() ' . ' ,isadmin=' . db_input($vars['isadmin']) . ' ,isactive=' . db_input($vars['isactive']) . ' ,isvisible=' . db_input(isset($vars['isvisible']) ? 1 : 0) . ' ,onvacation=' . db_input(isset($vars['onvacation']) ? 1 : 0) . ' ,assigned_only=' . db_input(isset($vars['assigned_only']) ? 1 : 0) . ' ,dept_id=' . db_input($vars['dept_id']) . ' ,group_id=' . db_input($vars['group_id']) . ' ,timezone_id=' . db_input($vars['timezone_id']) . ' ,daylight_saving=' . db_input(isset($vars['daylight_saving']) ? 1 : 0) . ' ,username='******'username']) . ' ,firstname=' . db_input($vars['firstname']) . ' ,lastname=' . db_input($vars['lastname']) . ' ,email=' . db_input($vars['email']) . ' ,backend=' . db_input($vars['backend']) . ' ,phone="' . db_input(Format::phone($vars['phone']), false) . '"' . ' ,phone_ext=' . db_input($vars['phone_ext']) . ' ,mobile="' . db_input(Format::phone($vars['mobile']), false) . '"' . ' ,signature=' . db_input(Format::sanitize($vars['signature'])) . ' ,notes=' . db_input(Format::sanitize($vars['notes']));
     if ($vars['passwd1']) {
         $sql .= ' ,passwd=' . db_input(Passwd::hash($vars['passwd1']));
         if (isset($vars['change_passwd'])) {
             $sql .= ' ,change_passwd=1';
         }
     } elseif (!isset($vars['change_passwd'])) {
         $sql .= ' ,change_passwd=0';
     }
     if ($id) {
         $sql = 'UPDATE ' . STAFF_TABLE . ' ' . $sql . ' WHERE staff_id=' . db_input($id);
         if (db_query($sql) && db_affected_rows()) {
             return true;
         }
         $errors['err'] = sprintf(__('Unable to update %s.'), __('this agent')) . ' ' . __('Internal error occurred');
     } else {
         $sql = 'INSERT INTO ' . STAFF_TABLE . ' ' . $sql . ', created=NOW()';
         if (db_query($sql) && ($uid = db_insert_id())) {
             return $uid;
         }
         $errors['err'] = sprintf(__('Unable to create %s.'), __('this agent')) . ' ' . __('Internal error occurred');
     }
     return false;
 }
Beispiel #22
0
 function parse($stream)
 {
     global $cfg;
     $contents = '';
     if (is_resource($stream)) {
         while (!feof($stream)) {
             $contents .= fread($stream, 8192);
         }
     } else {
         $contents = $stream;
     }
     $parser = new Mail_Parse($contents);
     if (!$parser->decode()) {
         //Decode...returns false on decoding errors
         return $this->err('Email parse failed [' . $parser->getError() . ']');
     }
     $data = array();
     $data['emailId'] = 0;
     $data['recipients'] = array();
     $data['subject'] = $parser->getSubject();
     $data['header'] = $parser->getHeader();
     $data['mid'] = $parser->getMessageId();
     $data['priorityId'] = $parser->getPriority();
     $data['flags'] = new ArrayObject();
     //FROM address: who sent the email.
     if ($fromlist = $parser->getFromAddressList()) {
         $from = $fromlist[0];
         //Default.
         foreach ($fromlist as $fromobj) {
             if (!Validator::is_email($fromobj->mailbox . '@' . $fromobj->host)) {
                 continue;
             }
             $from = $fromobj;
             break;
         }
         $data['email'] = $from->mailbox . '@' . $from->host;
         $data['name'] = trim($from->personal, '"');
         if ($from->comment && $from->comment[0]) {
             $data['name'] .= ' (' . $from->comment[0] . ')';
         }
         //Use email address as name  when FROM address doesn't  have a name.
         if (!$data['name'] && $data['email']) {
             $data['name'] = $data['email'];
         }
     }
     /* Scan through the list of addressees (via To, Cc, and Delivered-To headers), and identify
      * how the mail arrived at the system. One of the mails should be in the system email list.
      * The recipient list (without the Delivered-To addressees) will be made available to the
      * ticket filtering system. However, addresses in the Delivered-To header should never be
      * considered for the collaborator list.
      */
     $tolist = array();
     if ($to = $parser->getToAddressList()) {
         $tolist['to'] = $to;
     }
     if ($cc = $parser->getCcAddressList()) {
         $tolist['cc'] = $cc;
     }
     if ($dt = $parser->getDeliveredToAddressList()) {
         $tolist['delivered-to'] = $dt;
     }
     foreach ($tolist as $source => $list) {
         foreach ($list as $addr) {
             if (!($emailId = Email::getIdByEmail(strtolower($addr->mailbox) . '@' . $addr->host))) {
                 //Skip virtual Delivered-To addresses
                 if ($source == 'delivered-to') {
                     continue;
                 }
                 $data['recipients'][] = array('source' => sprintf(_S("Email (%s)"), $source), 'name' => trim(@$addr->personal, '"'), 'email' => strtolower($addr->mailbox) . '@' . $addr->host);
             } elseif (!$data['emailId']) {
                 $data['emailId'] = $emailId;
             }
         }
     }
     /*
      * In the event that the mail was delivered to the system although none of the system
      * mail addresses are in the addressee lists, be careful not to include the addressee
      * in the collaborator list. Therefore, the delivered-to addressees should be flagged so they
      * are not added to the collaborator list in the ticket creation process.
      */
     if ($tolist['delivered-to']) {
         foreach ($tolist['delivered-to'] as $addr) {
             foreach ($data['recipients'] as $i => $r) {
                 if (strcasecmp($r['email'], $addr->mailbox . '@' . $addr->host) === 0) {
                     $data['recipients'][$i]['source'] = 'delivered-to';
                 }
             }
         }
     }
     //maybe we got BCC'ed??
     if (!$data['emailId']) {
         $emailId = 0;
         if ($bcc = $parser->getBccAddressList()) {
             foreach ($bcc as $addr) {
                 if ($emailId = Email::getIdByEmail($addr->mailbox . '@' . $addr->host)) {
                     break;
                 }
             }
         }
         $data['emailId'] = $emailId;
     }
     if ($parser->isBounceNotice()) {
         // Fetch the original References and assign to 'references'
         if ($headers = $parser->getOriginalMessageHeaders()) {
             $data['references'] = $headers['references'];
             $data['in-reply-to'] = @$headers['in-reply-to'] ?: null;
         }
         // Fetch deliver status report
         $data['message'] = $parser->getDeliveryStatusMessage() ?: $parser->getBody();
         $data['thread-type'] = 'N';
         $data['flags']['bounce'] = true;
     } else {
         // Typical email
         $data['message'] = $parser->getBody();
         $data['in-reply-to'] = @$parser->struct->headers['in-reply-to'];
         $data['references'] = @$parser->struct->headers['references'];
         $data['flags']['bounce'] = TicketFilter::isBounce($data['header']);
     }
     $data['to-email-id'] = $data['emailId'];
     if ($replyto = $parser->getReplyTo()) {
         $replyto = $replyto[0];
         $data['reply-to'] = $replyto->mailbox . '@' . $replyto->host;
         if ($replyto->personal) {
             $data['reply-to-name'] = trim($replyto->personal, " \t\n\r\v\"");
         }
     }
     $data['attachments'] = $parser->getAttachments();
     return $data;
 }
 function save($id, $vars, &$errors)
 {
     include_once INCLUDE_DIR . 'class.dept.php';
     if ($id && $id != $vars['staff_id']) {
         $errors['err'] = 'Error Interno';
     }
     if (!$vars['firstname'] || !$vars['lastname']) {
         $errors['name'] = 'Nombre y apellidos requerido';
     }
     if (!$vars['username'] || strlen($vars['username']) < 3) {
         $errors['username'] = '******';
     } else {
         //check if the username is already in-use.
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE username='******'username']);
         if ($id) {
             $sql .= ' AND staff_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['username'] = '******';
         }
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Se requiere email Valido';
     } elseif (Email::getIdByEmail($vars['email'])) {
         $errors['email'] = 'Este Email ya se esta usando como Email del sistema';
     }
     if ($vars['phone'] && !Validator::is_phone($vars['phone'])) {
         $errors['phone'] = 'Numero de tel&aacute;fono requerido';
     }
     if ($vars['mobile'] && !Validator::is_phone($vars['mobile'])) {
         $errors['mobile'] = 'Numero de movil Requerido';
     }
     if ($vars['npassword'] || $vars['vpassword'] || !$id) {
         if (!$vars['npassword'] && !$id) {
             $errors['npassword'] = '******';
         } elseif ($vars['npassword'] && strcmp($vars['npassword'], $vars['vpassword'])) {
             $errors['vpassword'] = '******';
         } elseif ($vars['npassword'] && strlen($vars['npassword']) < 6) {
             $errors['npassword'] = '******';
         }
     }
     if (!$vars['dept_id']) {
         $errors['dept'] = 'Departamento requerido';
     }
     if (!$vars['group_id']) {
         $errors['group'] = 'Grupo requerido';
     }
     if (!$errors) {
         $sql = ' SET updated=NOW() ' . ',isadmin=' . db_input($vars['isadmin']) . ',isactive=' . db_input($vars['isactive']) . ',isvisible=' . db_input(isset($vars['isvisible']) ? 1 : 0) . ',onvacation=' . db_input(isset($vars['onvacation']) ? 1 : 0) . ',dept_id=' . db_input($vars['dept_id']) . ',group_id=' . db_input($vars['group_id']) . ',username='******'username'])) . ',firstname=' . db_input(Format::striptags($vars['firstname'])) . ',lastname=' . db_input(Format::striptags($vars['lastname'])) . ',email=' . db_input($vars['email']) . ',phone="' . db_input($vars['phone'], false) . '"' . ',phone_ext=' . db_input($vars['phone_ext']) . ',mobile="' . db_input($vars['mobile'], false) . '"' . ',signature=' . db_input(Format::striptags($vars['signature']));
         if ($vars['npassword']) {
             $sql .= ',passwd=' . db_input(md5($vars['npassword']));
         }
         if (isset($vars['resetpasswd'])) {
             $sql .= ',change_passwd=1';
         }
         if ($id) {
             $sql = 'UPDATE ' . STAFF_TABLE . ' ' . $sql . ' WHERE staff_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = 'No se puede actualizar el usuario. Error interno';
             }
         } else {
             $sql = 'INSERT INTO ' . STAFF_TABLE . ' ' . $sql . ',created=NOW()';
             if (db_query($sql) && ($uID = db_insert_id())) {
                 return $uID;
             }
             $errors['err'] = 'No se puede crear el usuario. Error interno';
         }
     }
     return $errors ? false : true;
 }
 function save($id, $vars, &$errors)
 {
     include_once INCLUDE_DIR . 'class.dept.php';
     if ($id && $id != $vars['staff_id']) {
         $errors['err'] = 'Internal Error';
     }
     if (!$vars['firstname'] || !$vars['lastname']) {
         $errors['name'] = 'First and last name required';
     }
     if (!$vars['username'] || strlen($vars['username']) < 3) {
         $errors['username'] = '******';
     } else {
         //check if the username is already in-use.
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE username='******'username']);
         if ($id) {
             $sql .= ' AND staff_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['username'] = '******';
         }
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Valid email required';
     } elseif (Email::getIdByEmail($vars['email'])) {
         $errors['email'] = 'Already in-use system email';
     }
     if ($vars['phone'] && !Validator::is_phone($vars['phone'])) {
         $errors['phone'] = 'Valid number required';
     }
     if ($vars['mobile'] && !Validator::is_phone($vars['mobile'])) {
         $errors['mobile'] = 'Valid number required';
     }
     if ($vars['npassword'] || $vars['vpassword'] || !$id) {
         if (!$vars['npassword'] && !$id) {
             $errors['npassword'] = '******';
         } elseif ($vars['npassword'] && strcmp($vars['npassword'], $vars['vpassword'])) {
             $errors['vpassword'] = '******';
         } elseif ($vars['npassword'] && strlen($vars['npassword']) < 6) {
             $errors['npassword'] = '******';
         }
     }
     if (!$vars['dept_id']) {
         $errors['dept'] = 'Department required';
     }
     if (!$vars['group_id']) {
         $errors['group'] = 'Group required';
     }
     if (!$errors) {
         $sql = ' SET updated=NOW() ' . ',isadmin=' . db_input($vars['isadmin']) . ',isactive=' . db_input($vars['isactive']) . ',new_tkt_not=' . db_input($vars['new_tkt_not']) . ',close_tkt_not=' . db_input($vars['close_tkt_not']) . ',isvisible=' . db_input(isset($vars['isvisible']) ? 1 : 0) . ',onvacation=' . db_input(isset($vars['onvacation']) ? 1 : 0) . ',dept_id=' . db_input($vars['dept_id']) . ',group_id=' . db_input($vars['group_id']) . ',username='******'username'])) . ',firstname=' . db_input(Format::striptags($vars['firstname'])) . ',lastname=' . db_input(Format::striptags($vars['lastname'])) . ',email=' . db_input($vars['email']) . ',phone="' . db_input($vars['phone'], false) . '"' . ',phone_ext=' . db_input($vars['phone_ext']) . ',mobile="' . db_input($vars['mobile'], false) . '"' . ',signature=' . db_input(Format::striptags($vars['signature']));
         if ($vars['npassword']) {
             $sql .= ',passwd=' . db_input(md5($vars['npassword']));
         }
         if (isset($vars['resetpasswd'])) {
             $sql .= ',change_passwd=1';
         }
         if ($id) {
             $sql = 'UPDATE ' . STAFF_TABLE . ' ' . $sql . ' WHERE staff_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = 'Unable to update the user. Internal error occured';
             }
         } else {
             $sql = 'INSERT INTO ' . STAFF_TABLE . ' ' . $sql . ',created=NOW()';
             if (db_query($sql) && ($uID = db_insert_id())) {
                 return $uID;
             }
             $errors['err'] = 'Unable to create user. Internal error';
         }
     }
     return $errors ? false : true;
 }
Beispiel #25
0
 function save($id, $vars, &$errors)
 {
     global $cfg;
     //very basic checks
     $vars['name'] = Format::striptags(trim($vars['name']));
     if ($id && $id != $vars['id']) {
         $errors['err'] = 'Internal error. Get technical help.';
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Valid email required';
     } elseif (($eid = Email::getIdByEmail($vars['email'])) && $eid != $id) {
         $errors['email'] = 'Email already exits';
     } elseif ($cfg && !strcasecmp($cfg->getAdminEmail(), $vars['email'])) {
         $errors['email'] = 'Email already used as admin email!';
     } elseif (Staff::getIdByEmail($vars['email'])) {
         //make sure the email doesn't belong to any of the staff
         $errors['email'] = 'Email in-use by a staff member';
     }
     if (!$vars['name']) {
         $errors['name'] = 'Email name required';
     }
     if ($vars['mail_active'] || $vars['smtp_active'] && $vars['smtp_auth']) {
         if (!$vars['userid']) {
             $errors['userid'] = 'Username missing';
         }
         if (!$id && !$vars['passwd']) {
             $errors['passwd'] = 'Password required';
         }
     }
     if ($vars['mail_active']) {
         //Check pop/imapinfo only when enabled.
         if (!function_exists('imap_open')) {
             $errors['mail_active'] = 'IMAP doesn\'t exist. PHP must be compiled with IMAP enabled.';
         }
         if (!$vars['mail_host']) {
             $errors['mail_host'] = 'Host name required';
         }
         if (!$vars['mail_port']) {
             $errors['mail_port'] = 'Port required';
         }
         if (!$vars['mail_protocol']) {
             $errors['mail_protocol'] = 'Select protocol';
         }
         if (!$vars['mail_fetchfreq'] || !is_numeric($vars['mail_fetchfreq'])) {
             $errors['mail_fetchfreq'] = 'Fetch interval required';
         }
         if (!$vars['mail_fetchmax'] || !is_numeric($vars['mail_fetchmax'])) {
             $errors['mail_fetchmax'] = 'Maximum emails required';
         }
         if (!$vars['dept_id'] || !is_numeric($vars['dept_id'])) {
             $errors['dept_id'] = 'You must select a Dept.';
         }
         if (!$vars['priority_id']) {
             $errors['priority_id'] = 'You must select a priority';
         }
         if (!isset($vars['postfetch'])) {
             $errors['postfetch'] = 'Indicate what to do with fetched emails';
         } elseif (!strcasecmp($vars['postfetch'], 'archive')) {
             if (!$vars['mail_archivefolder']) {
                 $errors['postfetch'] = 'Valid folder required';
             }
         }
     }
     if ($vars['smtp_active']) {
         if (!$vars['smtp_host']) {
             $errors['smtp_host'] = 'Host name required';
         }
         if (!$vars['smtp_port']) {
             $errors['smtp_port'] = 'Port required';
         }
     }
     //abort on errors
     if ($errors) {
         return false;
     }
     if (!$errors && ($vars['mail_host'] && $vars['userid'])) {
         $sql = 'SELECT email_id FROM ' . EMAIL_TABLE . ' WHERE mail_host=' . db_input($vars['mail_host']) . ' AND userid=' . db_input($vars['userid']);
         if ($id) {
             $sql .= ' AND email_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['userid'] = $errors['host'] = 'Host/userid combination already in-use.';
         }
     }
     $passwd = $vars['passwd'] ? $vars['passwd'] : $vars['cpasswd'];
     if (!$errors && $vars['mail_active']) {
         //note: password is unencrypted at this point...MailFetcher expect plain text.
         $fetcher = new MailFetcher($vars['userid'], $passwd, $vars['mail_host'], $vars['mail_port'], $vars['mail_protocol'], $vars['mail_encryption']);
         if (!$fetcher->connect()) {
             $errors['err'] = 'Invalid login. Check ' . Format::htmlchars($vars['mail_protocol']) . ' settings';
             $errors['mail'] = '<br>' . $fetcher->getLastError();
         } elseif ($vars['mail_archivefolder'] && !$fetcher->checkMailbox($vars['mail_archivefolder'], true)) {
             $errors['postfetch'] = 'Invalid or unknown mail folder! >> ' . $fetcher->getLastError() . '';
             if (!$errors['mail']) {
                 $errors['mail'] = 'Invalid or unknown archive folder!';
             }
         }
     }
     if (!$errors && $vars['smtp_active']) {
         //Check SMTP login only.
         require_once 'Mail.php';
         // PEAR Mail package
         $smtp = mail::factory('smtp', array('host' => $vars['smtp_host'], 'port' => $vars['smtp_port'], 'auth' => $vars['smtp_auth'] ? true : false, 'username' => $vars['userid'], 'password' => $passwd, 'timeout' => 20, 'debug' => false));
         $mail = $smtp->connect();
         if (PEAR::isError($mail)) {
             $errors['err'] = 'Unable to login. Check SMTP settings.';
             $errors['smtp'] = '<br>' . $mail->getMessage();
         } else {
             $smtp->disconnect();
             //Thank you, sir!
         }
     }
     if ($errors) {
         return false;
     }
     //Default to default priority and dept..
     if (!$vars['priority_id'] && $cfg) {
         $vars['priority_id'] = $cfg->getDefaultPriorityId();
     }
     if (!$vars['dept_id'] && $cfg) {
         $vars['dept_id'] = $cfg->getDefaultDeptId();
     }
     $sql = 'updated=NOW(),mail_errors=0, mail_lastfetch=NULL' . ',email=' . db_input($vars['email']) . ',name=' . db_input(Format::striptags($vars['name'])) . ',dept_id=' . db_input($vars['dept_id']) . ',priority_id=' . db_input($vars['priority_id']) . ',noautoresp=' . db_input(isset($vars['noautoresp']) ? 1 : 0) . ',userid=' . db_input($vars['userid']) . ',mail_active=' . db_input($vars['mail_active']) . ',mail_host=' . db_input($vars['mail_host']) . ',mail_protocol=' . db_input($vars['mail_protocol'] ? $vars['mail_protocol'] : 'POP') . ',mail_encryption=' . db_input($vars['mail_encryption']) . ',mail_port=' . db_input($vars['mail_port'] ? $vars['mail_port'] : 0) . ',mail_fetchfreq=' . db_input($vars['mail_fetchfreq'] ? $vars['mail_fetchfreq'] : 0) . ',mail_fetchmax=' . db_input($vars['mail_fetchmax'] ? $vars['mail_fetchmax'] : 0) . ',smtp_active=' . db_input($vars['smtp_active']) . ',smtp_host=' . db_input($vars['smtp_host']) . ',smtp_port=' . db_input($vars['smtp_port'] ? $vars['smtp_port'] : 0) . ',smtp_auth=' . db_input($vars['smtp_auth']) . ',smtp_spoofing=' . db_input(isset($vars['smtp_spoofing']) ? 1 : 0) . ',notes=' . db_input($vars['notes']);
     //Post fetch email handling...
     if ($vars['postfetch'] && !strcasecmp($vars['postfetch'], 'delete')) {
         $sql .= ',mail_delete=1,mail_archivefolder=NULL';
     } elseif ($vars['postfetch'] && !strcasecmp($vars['postfetch'], 'archive') && $vars['mail_archivefolder']) {
         $sql .= ',mail_delete=0,mail_archivefolder=' . db_input($vars['mail_archivefolder']);
     } else {
         $sql .= ',mail_delete=0,mail_archivefolder=NULL';
     }
     if ($vars['passwd']) {
         //New password - encrypt.
         $sql .= ',userpass='******'passwd'], SECRET_SALT));
     }
     if ($id) {
         //update
         $sql = 'UPDATE ' . EMAIL_TABLE . ' SET ' . $sql . ' WHERE email_id=' . db_input($id);
         if (db_query($sql) && db_affected_rows()) {
             return true;
         }
         $errors['err'] = 'Unable to update email. Internal error occurred';
     } else {
         $sql = 'INSERT INTO ' . EMAIL_TABLE . ' SET ' . $sql . ',created=NOW()';
         if (db_query($sql) && ($id = db_insert_id())) {
             return $id;
         }
         $errors['err'] = 'Unable to add email. Internal error';
     }
     return false;
 }
Beispiel #26
0
        continue;
    }
    $from = $fromobj;
    break;
}
//TO Address:Try to figure out the email associated with the message.
$tolist = $parser->getToAddressList();
foreach ($tolist as $toaddr) {
    if ($emailId = Email::getIdByEmail($toaddr->mailbox . '@' . $toaddr->host)) {
        //We've found target email.
        break;
    }
}
if (!$emailId && ($cclist = $parser->getCcAddressList())) {
    foreach ($cclist as $ccaddr) {
        if ($emailId = Email::getIdByEmail($ccaddr->mailbox . '@' . $ccaddr->host)) {
            break;
        }
    }
}
//TODO: Options to reject emails without a matching To address in db? May be it was Bcc? Current Policy: If you pipe, we accept policy
require_once INCLUDE_DIR . 'class.ticket.php';
//We now need this bad boy!
$var = array();
$deptId = 0;
$name = trim($from->personal, '"');
if ($from->comment && $from->comment[0]) {
    $name .= ' (' . $from->comment[0] . ')';
}
$subj = utf8_encode($parser->getSubject());
if (!($body = Format::stripEmptyLines($parser->getBody())) && $subj) {
 function updateEmailsSetting($vars, &$errors)
 {
     $f = array();
     $f['default_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Default email required');
     $f['alert_email_id'] = array('type' => 'int', 'required' => 1, 'error' => 'Selection required');
     $f['admin_email'] = array('type' => 'email', 'required' => 1, 'error' => 'System admin email required');
     if ($vars['strip_quoted_reply'] && !$vars['reply_separator']) {
         $errors['reply_separator'] = 'Reply separator required to strip quoted reply.';
     }
     if ($vars['admin_email'] && Email::getIdByEmail($vars['admin_email'])) {
         //Make sure admin email is not also a system email.
         $errors['admin_email'] = 'Email already setup as system email';
     }
     if (!Validator::process($f, $vars, $errors) || $errors) {
         return false;
     }
     $sql = 'UPDATE ' . CONFIG_TABLE . ' SET updated=NOW() ' . ',default_email_id=' . db_input($vars['default_email_id']) . ',alert_email_id=' . db_input($vars['alert_email_id']) . ',default_smtp_id=' . db_input($vars['default_smtp_id']) . ',admin_email=' . db_input($vars['admin_email']) . ',enable_mail_polling=' . db_input(isset($vars['enable_mail_polling']) ? 1 : 0) . ',enable_email_piping=' . db_input(isset($vars['enable_email_piping']) ? 1 : 0) . ',strip_quoted_reply=' . db_input(isset($vars['strip_quoted_reply']) ? 1 : 0) . ',reply_separator=' . db_input($vars['reply_separator']) . ' WHERE id=' . db_input($this->getId());
     return db_query($sql);
 }
 function save($id, $vars, &$errors)
 {
     global $cfg;
     //very basic checks
     if ($id && $id != $vars['email_id']) {
         $errors['err'] = 'Error Interno.';
     }
     if (!$vars['email'] || !Validator::is_email($vars['email'])) {
         $errors['email'] = 'Se Requiere un Email Valido';
     } elseif (($eid = Email::getIdByEmail($vars['email'])) && $eid != $id) {
         $errors['email'] = 'Este Email ya existe';
     } elseif (!strcasecmp($cfg->getAdminEmail(), $vars['email'])) {
         $errors['email'] = 'Este Email ya se esta usando en la cuenta de Administrador';
     } else {
         //make sure the email doesn't belong to any of the staff
         $sql = 'SELECT staff_id FROM ' . STAFF_TABLE . ' WHERE email=' . db_input($vars['email']);
         if (($res = db_query($sql)) && db_num_rows($res)) {
             $errors['email'] = 'Este Email ya se esta usando por un miembro del Staff';
         }
     }
     if (!$vars['dept_id'] || !is_numeric($vars['dept_id'])) {
         $errors['dept_id'] = 'Debes seleccionar un Departamento';
     }
     if (!$vars['priority_id']) {
         $errors['priority_id'] = 'Debes seleccionar prioridad';
     }
     if ($vars['mail_active'] || $vars['smtp_active'] && $vars['smtp_auth']) {
         if (!$vars['userid']) {
             $errors['userid'] = 'Falta nombre de Usuario';
         }
         if (!$vars['userpass']) {
             $errors['userpass'] = '******';
         }
     }
     if ($vars['mail_active']) {
         //Check pop/imapinfo only when enabled.
         if (!function_exists('imap_open')) {
             $errors['mail_active'] = 'IMAP no existe. PHP debe ser compilado con IMAP.';
         }
         if (!$vars['mail_host']) {
             $errors['mail_host'] = 'Se requiere nombre del Host';
         }
         if (!$vars['mail_port']) {
             $errors['mail_port'] = 'Se requiere numero de Puerto';
         }
         if (!$vars['mail_protocol']) {
             $errors['mail_protocol'] = 'Selecciona Protocolo';
         }
         if (!$vars['mail_fetchfreq'] || !is_numeric($vars['mail_fetchfreq'])) {
             $errors['mail_fetchfreq'] = 'Se requiere frecuencia de captura';
         }
         if (!$vars['mail_fetchmax'] || !is_numeric($vars['mail_fetchmax'])) {
             $errors['mail_fetchmax'] = 'Se requiere numero m&aacute;ximo de correos por captura';
         }
     }
     if ($vars['smtp_active']) {
         if (!$vars['smtp_host']) {
             $errors['smtp_host'] = 'Se requiere nombre del Host';
         }
         if (!$vars['smtp_port']) {
             $errors['smtp_port'] = 'Se requiere numero de puerto';
         }
     }
     if (!$errors && ($vars['mail_host'] && $vars['userid'])) {
         $sql = 'SELECT email_id FROM ' . EMAIL_TABLE . ' WHERE mail_host=' . db_input($vars['mail_host']) . ' AND userid=' . db_input($vars['userid']);
         if ($id) {
             $sql .= ' AND email_id!=' . db_input($id);
         }
         if (db_num_rows(db_query($sql))) {
             $errors['userid'] = $errors['host'] = 'La combinacion Host/Nombre de usuario ya esta en uso por otro departamento.';
         }
     }
     if (!$errors && $vars['mail_active']) {
         //note: password is unencrypted at this point...MailFetcher expect plain text.
         $fetcher = new MailFetcher($vars['userid'], $vars['userpass'], $vars['mail_host'], $vars['mail_port'], $vars['mail_protocol'], $vars['mail_encryption']);
         if (!$fetcher->connect()) {
             $errors['userpass'] = '******' . $vars['mail_protocol'] . '';
             $errors['mail'] = '<br>' . $fetcher->getLastError();
         }
     }
     if (!$errors && $vars['smtp_active']) {
         //Check SMTP login only.
         require_once 'Mail.php';
         // PEAR Mail package
         $smtp = mail::factory('smtp', array('host' => $vars['smtp_host'], 'port' => $vars['smtp_port'], 'auth' => $vars['smtp_auth'] ? true : false, 'username' => $vars['userid'], 'password' => $vars['userpass'], 'timeout' => 20, 'debug' => false));
         $mail = $smtp->connect();
         if (PEAR::isError($mail)) {
             $errors['userpass'] = '******';
             $errors['smtp'] = '<br>' . $mail->getMessage();
         } else {
             $smtp->disconnect();
             //Thank you, sir!
         }
     }
     if (!$errors) {
         $sql = 'updated=NOW(),mail_errors=0, mail_lastfetch=NULL' . ',email=' . db_input($vars['email']) . ',name=' . db_input(Format::striptags($vars['name'])) . ',dept_id=' . db_input($vars['dept_id']) . ',priority_id=' . db_input($vars['priority_id']) . ',noautoresp=' . db_input(isset($vars['noautoresp']) ? 1 : 0) . ',userid=' . db_input($vars['userid']) . ',userpass='******'userpass'], SECRET_SALT)) . ',mail_active=' . db_input($vars['mail_active']) . ',mail_host=' . db_input($vars['mail_host']) . ',mail_protocol=' . db_input($vars['mail_protocol'] ? $vars['mail_protocol'] : 'POP') . ',mail_encryption=' . db_input($vars['mail_encryption']) . ',mail_port=' . db_input($vars['mail_port'] ? $vars['mail_port'] : 0) . ',mail_fetchfreq=' . db_input($vars['mail_fetchfreq'] ? $vars['mail_fetchfreq'] : 0) . ',mail_fetchmax=' . db_input($vars['mail_fetchmax'] ? $vars['mail_fetchmax'] : 0) . ',mail_delete=' . db_input(isset($vars['mail_delete']) ? $vars['mail_delete'] : 0) . ',smtp_active=' . db_input($vars['smtp_active']) . ',smtp_host=' . db_input($vars['smtp_host']) . ',smtp_port=' . db_input($vars['smtp_port'] ? $vars['smtp_port'] : 0) . ',smtp_auth=' . db_input($vars['smtp_auth']);
         if ($id) {
             //update
             $sql = 'UPDATE ' . EMAIL_TABLE . ' SET ' . $sql . ' WHERE email_id=' . db_input($id);
             if (!db_query($sql) || !db_affected_rows()) {
                 $errors['err'] = 'No se a podido actualizar el Email, Error interno';
             }
         } else {
             $sql = 'INSERT INTO ' . EMAIL_TABLE . ' SET ' . $sql . ',created=NOW()';
             if (!db_query($sql) or !($emailID = db_insert_id())) {
                 $errors['err'] = 'No se a podido añadir el Email, Error interno ';
             } else {
                 return $emailID;
             }
             //newly created email.
         }
     } else {
         $errors['err'] = 'Se an producido Errores, intentelo de nuevo';
     }
     return $errors ? FALSE : TRUE;
 }