private function _handleCronSensorsPost($event)
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $translate = DevblocksPlatform::getTranslationService();
     $sensors = DAO_Sensor::getAll();
     // Check that all external sensors aren't over their M.I.A. time
     if (is_array($sensors)) {
         foreach ($sensors as $sensor) {
             /* @var $sensor Model_Sensor */
             // Only external sensors
             if ('sensor.external' != $sensor->extension_id) {
                 continue;
             }
             // Skip if the sensor hasn't run once yet
             if (0 == $sensor->updated_date) {
                 continue;
             }
             $mia_secs = intval($sensor->params->mia_secs);
             $elapsed = time() - $sensor->updated_date;
             if ($mia_secs && $elapsed > $mia_secs) {
                 $fields = array(DAO_Sensor::STATUS => 2, DAO_Sensor::FAIL_COUNT => intval($sensor->fail_count) + 1, DAO_Sensor::METRIC => $translate->_('sensor.status.mia'), DAO_Sensor::OUTPUT => $translate->_('sensor.status.mia'));
                 DAO_Sensor::update($sensor->id, $fields);
                 $logger->info($sensor->name . " is M.I.A. for {$elapsed} seconds.");
             }
         }
     }
 }
 function run(Model_Alert $alert, $sensors)
 {
     @($to = DevblocksPlatform::parseCsvString($alert->actions[self::EXTENSION_ID]['to']));
     @($template_subject = $alert->actions[self::EXTENSION_ID]['template_subject']);
     @($template_body = $alert->actions[self::EXTENSION_ID]['template_body']);
     $logger = DevblocksPlatform::getConsoleLog();
     // Assign template variables
     $tpl = DevblocksPlatform::getTemplateService();
     $tpl->clear_all_assign();
     $tpl->assign('alert', $alert);
     $tpl->assign('sensors', $sensors);
     $tpl->assign('num_sensors', count($sensors));
     // Build template
     $tpl_builder = DevblocksPlatform::getTemplateBuilder();
     $errors = array();
     // Subject
     if (false == ($subject = $tpl_builder->build($template_subject))) {
         $errors += $tpl_builder->getErrors();
     }
     // Body
     if (false == ($body = $tpl_builder->build($template_body))) {
         $errors += $tpl_builder->getErrors();
     }
     if (!empty($errors)) {
         $logger->err(sprintf("Errors in mail template (skipping): %s", implode("<br>\r\n", $errors)));
         return false;
     }
     if (is_array($to)) {
         foreach ($to as $address) {
             $logger->info(sprintf("Sending mail to %s about %d sensors", $address, count($sensors)));
             PortSensorMail::quickSend($address, $subject, $body);
         }
     }
 }
Exemple #3
0
 function run()
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $logger->info("[Heartbeat] Starting Heartbeat Task");
     // Heartbeat Event
     $eventMgr = DevblocksPlatform::getEventService();
     $eventMgr->trigger(new Model_DevblocksEvent('cron.heartbeat', array()));
 }
Exemple #4
0
 function run(Model_Alert $alert, $sensors)
 {
     @($to = DevblocksPlatform::parseCsvString($alert->actions[self::EXTENSION_ID]['to']));
     @($template_msg = $alert->actions[self::EXTENSION_ID]['template_msg']);
     $result = true;
     $logger = DevblocksPlatform::getConsoleLog();
     $settings = DevblocksPlatform::getPluginSettingsService();
     // Assign template variables
     $tpl = DevblocksPlatform::getTemplateService();
     $tpl->clear_all_assign();
     $tpl->assign('alert', $alert);
     $tpl->assign('sensors', $sensors);
     $tpl->assign('num_sensors', count($sensors));
     // Build template
     $tpl_builder = DevblocksPlatform::getTemplateBuilder();
     $errors = array();
     // Body
     if (false == ($text = $tpl_builder->build($template_msg))) {
         $errors += $tpl_builder->getErrors();
     }
     if (!empty($errors)) {
         $logger->err(sprintf("Errors in SMS template (skipping): %s", implode("<br>\r\n", $errors)));
         return false;
     }
     // Truncate message to 155 chars
     if (155 <= strlen($text)) {
         $text = substr($text, 0, 152) . '...';
     }
     // Clickatell SMS gateways
     $user = $settings->get('portsensor.sms', 'clickatell_username', '');
     $password = $settings->get('portsensor.sms', 'clickatell_password', '');
     $api_id = $settings->get('portsensor.sms', 'clickatell_api_id', '');
     if (empty($user) || empty($password) || empty($api_id)) {
         return;
     }
     if (is_array($to)) {
         foreach ($to as $phone) {
             $logger->info(sprintf("Sending SMS to %s about %d sensors", $phone, count($sensors)));
             $url = sprintf("http://api.clickatell.com/http/sendmsg?user=%s&password=%s&api_id=%s&to=%s&text=%s", urlencode($user), urlencode($password), urlencode($api_id), urlencode($phone), urlencode($text));
             $ch = curl_init();
             curl_setopt($ch, CURLOPT_URL, $url);
             curl_setopt($ch, CURLOPT_HEADER, 0);
             curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
             curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
             $out = curl_exec($ch);
             curl_close($ch);
             $result = 0 == strcasecmp("ID:", substr($out, 0, 3));
         }
     }
     return $result;
 }
Exemple #5
0
 /**
  * @param Model_DevblocksEvent $event
  */
 function handleEvent(Model_DevblocksEvent $event)
 {
     switch ($event->id) {
         case 'cron.maint':
             $records_removed = 0;
             $logger = DevblocksPlatform::getConsoleLog();
             $logger->info("[Answernet.com Maint] Starting Purging Contact Addresses task");
             @set_time_limit(0);
             // Unlimited (if possible)
             @ini_set('memory_limit', '128M');
             $logger->info("[Answernet.com Maint] Overloaded memory_limit to: " . ini_get('memory_limit'));
             $logger->info("[Answernet.com Maint] Overloaded max_execution_time to: " . ini_get('max_execution_time'));
             $runtime = microtime(true);
             //Do something
             $db = DevblocksPlatform::getDatabaseService();
             $sql = "SELECT a.id ";
             $sql .= "FROM address a ";
             $sql .= "LEFT JOIN message m ON a.id = m.address_id ";
             $sql .= "LEFT JOIN requester r ON a.id = r.address_id ";
             $sql .= "LEFT JOIN ticket_comment tc ON a.id = tc.address_id ";
             $sql .= "WHERE a.contact_org_id = 0 ";
             $sql .= "AND m.address_id IS NULL ";
             $sql .= "AND r.address_id IS NULL ";
             $sql .= "AND tc.address_id IS NULL ";
             $sql .= "ORDER BY a.id ASC ";
             $rs = $db->Execute($sql);
             while (!$rs->EOF) {
                 // Loop though the records.
                 DAO_Address::delete($rs->fields['id']);
                 // Increament the records removed connecter
                 $records_removed++;
                 $rs->MoveNext();
             }
             $logger->info("[Answernet.com Maint] Total Records Removed: " . $records_removed);
             $logger->info("[Answernet.com Maint] Total Runtime: " . (microtime(true) - $runtime) * 1000 . " ms");
             break;
     }
 }
Exemple #6
0
 function handleRequest(DevblocksHttpRequest $request)
 {
     @($reload = DevblocksPlatform::importGPC($_REQUEST['reload'], 'integer', 0));
     @($loglevel = DevblocksPlatform::importGPC($_REQUEST['loglevel'], 'integer', 0));
     $logger = DevblocksPlatform::getConsoleLog();
     $translate = DevblocksPlatform::getTranslationService();
     $settings = CerberusSettings::getInstance();
     $authorized_ips_str = $settings->get(CerberusSettings::AUTHORIZED_IPS);
     $authorized_ips = DevblocksPlatform::parseCrlfString($authorized_ips_str);
     $authorized_ip_defaults = DevblocksPlatform::parseCsvString(AUTHORIZED_IPS_DEFAULTS);
     $authorized_ips = array_merge($authorized_ips, $authorized_ip_defaults);
     @($is_ignoring_wait = DevblocksPlatform::importGPC($_REQUEST['ignore_wait'], 'integer', 0));
     $pass = false;
     foreach ($authorized_ips as $ip) {
         if (substr($ip, 0, strlen($ip)) == substr($_SERVER['REMOTE_ADDR'], 0, strlen($ip))) {
             $pass = true;
             break;
         }
     }
     if (!$pass) {
         echo vsprintf($translate->_('cron.ip_unauthorized'), $_SERVER['REMOTE_ADDR']);
         return;
     }
     $stack = $request->path;
     array_shift($stack);
     // cron
     $job_id = array_shift($stack);
     @set_time_limit(0);
     // Unlimited (if possible)
     $url = DevblocksPlatform::getUrlService();
     $timelimit = intval(ini_get('max_execution_time'));
     if ($reload) {
         $reload_url = sprintf("%s?reload=%d&loglevel=%d&ignore_wait=%d", $url->write('c=cron' . ($job_id ? "&a=" . $job_id : "")), intval($reload), intval($loglevel), intval($is_ignoring_wait));
         echo "<HTML>" . "<HEAD>" . "<TITLE></TITLE>" . "<meta http-equiv='Refresh' content='" . intval($reload) . ";" . $reload_url . "'>" . "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>" . "</HEAD>" . "<BODY>";
         // onload=\"setTimeout(\\\"window.location.replace('".$url->write('c=cron')."')\\\",30);\"
     }
     // [TODO] Determine if we're on a time limit under 60 seconds
     $cron_manifests = DevblocksPlatform::getExtensions('cerberusweb.cron', true, true);
     $jobs = array();
     if (empty($job_id)) {
         // do everything
         // Determine who wants to go first by next time and longest waiting
         $nexttime = time() + 86400;
         if (is_array($cron_manifests)) {
             foreach ($cron_manifests as $idx => $instance) {
                 /* @var $instance CerberusCronPageExtension */
                 $lastrun = $instance->getParam(CerberusCronPageExtension::PARAM_LASTRUN, 0);
                 if ($instance->isReadyToRun($is_ignoring_wait)) {
                     if ($timelimit) {
                         if ($lastrun < $nexttime) {
                             $jobs[0] = $cron_manifests[$idx];
                             $nexttime = $lastrun;
                         }
                     } else {
                         $jobs[] =& $cron_manifests[$idx];
                     }
                 }
             }
         }
     } else {
         // single job
         $manifest = DevblocksPlatform::getExtension($job_id, false, true);
         if (empty($manifest)) {
             exit;
         }
         $instance = $manifest->createInstance();
         if ($instance) {
             if ($instance->isReadyToRun($is_ignoring_wait)) {
                 $jobs[0] =& $instance;
             }
         }
     }
     if (!empty($jobs)) {
         foreach ($jobs as $nextjob) {
             $nextjob->setParam(CerberusCronPageExtension::PARAM_LOCKED, time());
             $nextjob->_run();
         }
     } elseif ($reload) {
         $logger->info(vsprintf($translate->_('cron.nothing_to_do'), intval($reload)));
     }
     if ($reload) {
         echo "</BODY>" . "</HTML>";
     }
     exit;
 }
Exemple #7
0
 function run()
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $logger->info("[POP3] Starting POP3 Task");
     if (!extension_loaded("imap")) {
         die("IMAP Extension not loaded!");
     }
     @set_time_limit(0);
     // Unlimited (if possible)
     @ini_set('memory_limit', '64M');
     $accounts = DAO_Mail::getPop3Accounts();
     /* @var $accounts CerberusPop3Account[] */
     $timeout = ini_get('max_execution_time');
     // Allow runtime overloads (by host, etc.)
     @($gpc_pop3_max = DevblocksPlatform::importGPC($_REQUEST['pop3_max'], 'integer'));
     $max_downloads = !empty($gpc_pop3_max) ? $gpc_pop3_max : $this->getParam('max_messages', $timeout ? 20 : 50);
     // [JAS]: Make sure our output directory is writeable
     if (!is_writable(APP_MAIL_PATH . 'new' . DIRECTORY_SEPARATOR)) {
         $logger->err("[POP3] The mail storage directory is not writeable.  Skipping POP3 download.");
         return;
     }
     foreach ($accounts as $account) {
         /* @var $account CerberusPop3Account */
         if (!$account->enabled) {
             continue;
         }
         $logger->info('[POP3] Account being parsed is ' . $account->nickname);
         switch ($account->protocol) {
             default:
             case 'pop3':
                 // 110
                 $connect = sprintf("{%s:%d/pop3/notls}INBOX", $account->host, $account->port);
                 break;
             case 'pop3-ssl':
                 // 995
                 $connect = sprintf("{%s:%d/pop3/ssl/novalidate-cert}INBOX", $account->host, $account->port);
                 break;
             case 'imap':
                 // 143
                 $connect = sprintf("{%s:%d/notls}INBOX", $account->host, $account->port);
                 break;
             case 'imap-ssl':
                 // 993
                 $connect = sprintf("{%s:%d/imap/ssl/novalidate-cert}INBOX", $account->host, $account->port);
                 break;
         }
         $runtime = microtime(true);
         if (false === ($mailbox = @imap_open($connect, !empty($account->username) ? $account->username : "", !empty($account->password) ? $account->password : ""))) {
             $logger->err("[POP3] Failed with error: " . imap_last_error());
             continue;
         }
         $messages = array();
         $check = imap_check($mailbox);
         // [TODO] Make this an account setting?
         $total = min($max_downloads, $check->Nmsgs);
         $logger->info('[POP3] Init time: ' . (microtime(true) - $runtime) * 1000, " ms");
         $runtime = microtime(true);
         for ($i = 1; $i <= $total; $i++) {
             /*
              * [TODO] Logic for max message size (>1MB, etc.) handling.  If over a
              * threshold then use the attachment parser (imap_fetchstructure) to toss
              * non-plaintext until the message fits.
              */
             $msgno = $i;
             $time = microtime(true);
             $headers = imap_fetchheader($mailbox, $msgno);
             $body = imap_body($mailbox, $msgno);
             do {
                 $unique = sprintf("%s.%04d", time(), mt_rand(0, 9999));
                 $filename = APP_MAIL_PATH . 'new' . DIRECTORY_SEPARATOR . $unique;
             } while (file_exists($filename));
             $fp = fopen($filename, 'w');
             if ($fp) {
                 fwrite($fp, $headers, strlen($headers));
                 fwrite($fp, "\r\n\r\n");
                 fwrite($fp, $body, strlen($body));
                 @fclose($fp);
             }
             /*
              * [JAS]: We don't add the .msg extension until we're done with the file,
              * since this will safely be ignored by the parser until we're ready
              * for it.
              */
             rename($filename, dirname($filename) . DIRECTORY_SEPARATOR . basename($filename) . '.msg');
             unset($headers);
             unset($body);
             $time = microtime(true) - $time;
             $logger->info("[POP3] Downloaded message " . $msgno . " (" . sprintf("%d", $time * 1000) . " ms)");
             imap_delete($mailbox, $msgno);
             continue;
         }
         imap_expunge($mailbox);
         imap_close($mailbox);
         imap_errors();
         $logger->info("[POP3] Total Runtime: " . (microtime(true) - $runtime) * 1000 . " ms");
     }
 }
Exemple #8
0
 function run()
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $logger->info("[Alerts] Starting...");
     $alerts = DAO_Alert::getAll();
     $check_sensors = DAO_Sensor::getAll();
     $workers = DAO_Worker::getAll();
     if (is_array($alerts)) {
         foreach ($alerts as $alert) {
             /* @var $alert Model_Alert */
             if (!isset($workers[$alert->worker_id])) {
                 continue;
             }
             $logger->info(sprintf("[Alerts] Checking '%s' for %s...", $alert->name, $workers[$alert->worker_id]->getName()));
             $hit_sensors = $alert->getMatches($check_sensors);
             if (is_array($hit_sensors)) {
                 $alert->run($hit_sensors);
             }
         }
     }
     $logger->info("[Alerts] Finished!");
 }
Exemple #9
0
 function run(Model_PreParseRule $filter, CerberusParserMessage $message)
 {
     $message_headers = $message->headers;
     $subject = $message->headers['subject'];
     $ticket_fields = DAO_CustomField::getAll();
     $params = $filter->actions[self::EXTENSION_ID];
     $day_of_week = date('N');
     $logger = DevblocksPlatform::getConsoleLog();
     $logger->info("Answernet: Running Filter on New Mail");
     // Houser,Colin <1034179><Missing Serviced Customer information>
     // Current custom_fields numbers
     // 1 = Due Date
     // 2 = RM Employee ID
     // 3 = RM Name
     // 4 = Topic_metlife /0/2/4/6/8/10/12/14
     // 5 = SLA
     // 6 = New Hire Yes = 0 / No = 2
     //
     $sub = explode(',', $subject, 2);
     $lname = $sub[0];
     $sub2 = explode("<", $sub[1]);
     $fname = $sub2[0];
     $emp_id = $sub2[1];
     $topic_metlife = $sub2[2];
     $message->custom_fields['2'] = substr($emp_id, 0, -1);
     $message->custom_fields['3'] = trim($fname) . " " . trim($lname);
     // If topic == Import contacts
     if (preg_match('/import/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Import contacts";
         $message->custom_fields['5'] = 1;
         $message->custom_fields['6'] = "Yes";
     }
     // If topic == Create mailing list from existing data
     if (preg_match('/mailing/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Create mailing list from existing data";
         $message->custom_fields['5'] = 3;
         $message->custom_fields['6'] = "Yes";
     }
     // If topic == Update existing contacts
     if (preg_match('/Update/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Update existing contacts";
         $message->custom_fields['5'] = 3;
         $message->custom_fields['6'] = "No";
     }
     // If topic == Research missing customer info
     if (preg_match('/Research/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Research missing customer info";
         $message->custom_fields['5'] = 5;
         $message->custom_fields['6'] = "No";
     }
     // If topic == Create labels
     if (preg_match('/labels/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Create labels";
         $message->custom_fields['5'] = 1;
         $message->custom_fields['6'] = "No";
     }
     // If topic == Export third-party file
     if (preg_match('/third/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Export third-party file";
         $message->custom_fields['5'] = 3;
         $message->custom_fields['6'] = "No";
     }
     // If topic == Other
     if (preg_match('/Other/i', $topic_metlife)) {
         $message->custom_fields['4'] = "Other";
         $message->custom_fields['5'] = 5;
         $message->custom_fields['6'] = "No";
     }
     // SLA of 1.  Process day of week Busness Days suck.
     if ($message->custom_fields['5'] == 1) {
         if ($day_of_week < 5 || $day_of_week == 7) {
             $message->custom_fields['1'] = strtotime("+1 Days");
         }
         if ($day_of_week == 6) {
             $message->custom_fields['1'] = strtotime("+2 Days");
         }
         if ($day_of_week == 5) {
             $message->custom_fields['1'] = strtotime("+3 Days");
         }
     }
     // SLA of 3.  Process day of week Busness Days suck.
     if ($message->custom_fields['5'] == 3) {
         if ($day_of_week < 4 || $day_of_week == 7) {
             $message->custom_fields['1'] = strtotime("+3 Days");
         }
         if ($day_of_week == 6) {
             $message->custom_fields['1'] = strtotime("+4 Days");
         }
         if ($day_of_week > 3 && $day_of_week < 6) {
             $message->custom_fields['1'] = strtotime("+5 Days");
         }
     }
     // SLA of 5.  Process day of week Busness Days suck.
     if ($message->custom_fields['5'] == 5) {
         if ($day_of_week == 1 || $day_of_week == 7) {
             $message->custom_fields['1'] = strtotime("+5 Days");
         }
         if ($day_of_week == 6) {
             $message->custom_fields['1'] = strtotime("+6 Days");
         }
         if ($day_of_week > 1 && $day_of_week < 6) {
             $message->custom_fields['1'] = strtotime("+7 Days");
         }
     }
 }
Exemple #10
0
 /**
  * Enter description here...
  *
  * @param CerberusParserMessage $message
  * @return integer
  */
 public static function parseMessage(CerberusParserMessage $message, $options = array())
 {
     /*
      * options:
      * 'no_autoreply'
      */
     $logger = DevblocksPlatform::getConsoleLog();
     $settings = DevblocksPlatform::getPluginSettingsService();
     $helpdesk_senders = CerberusApplication::getHelpdeskSenders();
     // Pre-parse mail filters
     $pre_filters = Model_PreParseRule::getMatches($message);
     if (is_array($pre_filters) && !empty($pre_filters)) {
         // Load filter action manifests for reuse
         $ext_action_mfts = DevblocksPlatform::getExtensions('cerberusweb.mail_filter.action', false);
         // Loop through all matching filters
         foreach ($pre_filters as $pre_filter) {
             // Do something with matching filter's actions
             foreach ($pre_filter->actions as $action_key => $action) {
                 switch ($action_key) {
                     case 'blackhole':
                         return NULL;
                         break;
                     case 'redirect':
                         @($to = $action['to']);
                         CerberusMail::reflect($message, $to);
                         return NULL;
                         break;
                     case 'bounce':
                         @($msg = $action['message']);
                         @($subject = 'Delivery failed: ' . self::fixQuotePrintableString($message->headers['subject']));
                         // [TODO] Follow the RFC spec on a true bounce
                         if (null != ($fromAddressInst = CerberusParser::getAddressFromHeaders($message->headers))) {
                             CerberusMail::quickSend($fromAddressInst->email, $subject, $msg);
                         }
                         return NULL;
                         break;
                     default:
                         // Plugin pre-parser filter actions
                         if (isset($ext_action_mfts[$action_key])) {
                             if (null != @($ext_action = $ext_action_mfts[$action_key]->createInstance())) {
                                 try {
                                     /* @var $ext_action Extension_MailFilterAction */
                                     $ext_action->run($pre_filter, $message);
                                 } catch (Exception $e) {
                                 }
                             }
                         }
                         break;
                 }
             }
         }
     }
     $headers =& $message->headers;
     // From
     if (null == ($fromAddressInst = CerberusParser::getAddressFromHeaders($headers))) {
         $logger->err("[Parser] 'From' address could not be created.");
         return NULL;
     }
     // To/Cc/Bcc
     $to = array();
     $sTo = @$headers['to'];
     $bIsNew = true;
     if (!empty($sTo)) {
         // [TODO] Do we still need this RFC address parser?
         $to = CerberusParser::parseRfcAddress($sTo);
     }
     // Subject
     // Fix quote printable subject (quoted blocks can appear anywhere in subject)
     $sSubject = "";
     if (isset($headers['subject']) && !empty($headers['subject'])) {
         $sSubject = $headers['subject'];
         if (is_array($sSubject)) {
             $sSubject = array_shift($sSubject);
         }
     }
     // The subject can still end up empty after QP decode
     if (empty($sSubject)) {
         $sSubject = "(no subject)";
     }
     // Date
     $iDate = @strtotime($headers['date']);
     // If blank, or in the future, set to the current date
     if (empty($iDate) || $iDate > time()) {
         $iDate = time();
     }
     // Is banned?
     if (1 == $fromAddressInst->is_banned) {
         $logger->info("[Parser] Ignoring ticket from banned address: " . $fromAddressInst->email);
         return NULL;
     }
     // Overloadable
     $enumSpamTraining = '';
     // Message Id / References / In-Reply-To
     @($sMessageId = $headers['message-id']);
     $body_append_text = array();
     $body_append_html = array();
     // [mdf]Check attached files before creating the ticket because we may need to overwrite the message-id
     // also store any contents of rfc822 files so we can include them after the body
     foreach ($message->files as $filename => $file) {
         /* @var $file ParserFile */
         switch ($file->mime_type) {
             case 'message/rfc822':
                 $full_filename = $file->tmpname;
                 $mail = mailparse_msg_parse_file($full_filename);
                 $struct = mailparse_msg_get_structure($mail);
                 $msginfo = mailparse_msg_get_part_data($mail);
                 $inline_headers = $msginfo['headers'];
                 if (isset($headers['from']) && (strtolower(substr($headers['from'], 0, 11)) == 'postmaster@' || strtolower(substr($headers['from'], 0, 14)) == 'mailer-daemon@')) {
                     $headers['in-reply-to'] = $inline_headers['message-id'];
                 }
                 break;
         }
     }
     // [JAS] [TODO] References header may contain multiple message-ids to find
     if (null != ($ids = self::findParentMessage($headers))) {
         $bIsNew = false;
         $id = $ids['ticket_id'];
         $msgid = $ids['message_id'];
         // Is it a worker reply from an external client?  If so, proxy
         if (null != ($worker_address = DAO_AddressToWorker::getByAddress($fromAddressInst->email))) {
             $logger->info("[Parser] Handling an external worker response from " . $fromAddressInst->email);
             if (!DAO_Ticket::isTicketRequester($worker_address->address, $id)) {
                 // Watcher Commands [TODO] Document on wiki/etc
                 if (0 != ($matches = preg_match_all("/\\[(.*?)\\]/i", $message->headers['subject'], $commands))) {
                     @($command = strtolower(array_pop($commands[1])));
                     $logger->info("[Parser] Worker command: " . $command);
                     switch ($command) {
                         case 'close':
                             DAO_Ticket::updateTicket($id, array(DAO_Ticket::IS_CLOSED => CerberusTicketStatus::CLOSED));
                             break;
                         case 'take':
                             DAO_Ticket::updateTicket($id, array(DAO_Ticket::NEXT_WORKER_ID => $worker_address->worker_id));
                             break;
                         case 'comment':
                             $comment_id = DAO_TicketComment::create(array(DAO_TicketComment::ADDRESS_ID => $fromAddressInst->id, DAO_TicketComment::CREATED => time(), DAO_TicketComment::TICKET_ID => $id, DAO_TicketComment::COMMENT => $message->body));
                             return $id;
                             break;
                         default:
                             // Typo?
                             break;
                     }
                 }
                 $attachment_files = array();
                 $attachment_files['name'] = array();
                 $attachment_files['type'] = array();
                 $attachment_files['tmp_name'] = array();
                 $attachment_files['size'] = array();
                 $i = 0;
                 foreach ($message->files as $filename => $file) {
                     $attachment_files['name'][$i] = $filename;
                     $attachment_files['type'][$i] = $file->mime_type;
                     $attachment_files['tmp_name'][$i] = $file->tmpname;
                     $attachment_files['size'][$i] = $file->file_size;
                     $i++;
                 }
                 CerberusMail::sendTicketMessage(array('message_id' => $msgid, 'content' => $message->body, 'files' => $attachment_files, 'agent_id' => $worker_address->worker_id));
                 return $id;
             } else {
                 // ... worker is a requester, treat as normal
                 $logger->info("[Parser] The external worker was a ticket requester, so we're not treating them as a watcher.");
             }
         } else {
             // Reply: Not sent by a worker
             /*
              * [TODO] check that this sender is a requester on the matched ticket
              * Otherwise blank out the $id
              */
         }
     }
     $group_id = 0;
     if (empty($id)) {
         // New Ticket
         $sMask = CerberusApplication::generateTicketMask();
         $groups = DAO_Group::getAll();
         // Routing new tickets
         if (null != ($routing_rules = Model_MailToGroupRule::getMatches($fromAddressInst, $message))) {
             if (is_array($routing_rules)) {
                 foreach ($routing_rules as $rule) {
                     // Only end up with the last 'move' action (ignore the previous)
                     if (isset($rule->actions['move'])) {
                         $group_id = intval($rule->actions['move']['group_id']);
                         // We don't need to move again when running rule actions
                         unset($rule->actions['move']);
                     }
                 }
             }
         }
         // Make sure the group exists
         if (!isset($groups[$group_id])) {
             $group_id = null;
         }
         // Last ditch effort to check for a default group to deliver to
         if (empty($group_id)) {
             if (null != ($default_team = DAO_Group::getDefaultGroup())) {
                 $group_id = $default_team->id;
             } else {
                 // Bounce
                 return null;
             }
         }
         // [JAS] It's important to not set the group_id on the ticket until the messages exist
         // or inbox filters will just abort.
         $fields = array(DAO_Ticket::MASK => $sMask, DAO_Ticket::SUBJECT => $sSubject, DAO_Ticket::IS_CLOSED => 0, DAO_Ticket::FIRST_WROTE_ID => intval($fromAddressInst->id), DAO_Ticket::LAST_WROTE_ID => intval($fromAddressInst->id), DAO_Ticket::CREATED_DATE => $iDate, DAO_Ticket::UPDATED_DATE => $iDate, DAO_Ticket::LAST_ACTION_CODE => CerberusTicketActionCode::TICKET_OPENED);
         $id = DAO_Ticket::createTicket($fields);
         // Apply routing actions to our new ticket ID
         if (isset($routing_rules) && is_array($routing_rules)) {
             foreach ($routing_rules as $rule) {
                 $rule->run($id);
             }
         }
     }
     // [JAS]: Add requesters to the ticket
     if (!empty($fromAddressInst->id) && !empty($id)) {
         // Don't add a requester if the sender is a helpdesk address
         if (isset($helpdesk_senders[$fromAddressInst->email])) {
             $logger->info("[Parser] Not adding ourselves as a requester: " . $fromAddressInst->email);
         } else {
             DAO_Ticket::createRequester($fromAddressInst->id, $id);
         }
     }
     // Add the other TO/CC addresses to the ticket
     // [TODO] This should be cleaned up and optimized
     if ($settings->get('cerberusweb.core', CerberusSettings::PARSER_AUTO_REQ, 0)) {
         @($autoreq_exclude_list = $settings->get('cerberusweb.core', CerberusSettings::PARSER_AUTO_REQ_EXCLUDE, ''));
         $destinations = self::getDestinations($headers);
         if (is_array($destinations) && !empty($destinations)) {
             // Filter out any excluded requesters
             if (!empty($autoreq_exclude_list)) {
                 @($autoreq_exclude = DevblocksPlatform::parseCrlfString($autoreq_exclude_list));
                 if (is_array($autoreq_exclude) && !empty($autoreq_exclude)) {
                     foreach ($autoreq_exclude as $excl_pattern) {
                         $excl_regexp = DevblocksPlatform::parseStringAsRegExp($excl_pattern);
                         // Check all destinations for this pattern
                         foreach ($destinations as $idx => $dest) {
                             if (@preg_match($excl_regexp, $dest)) {
                                 unset($destinations[$idx]);
                             }
                         }
                     }
                 }
             }
             foreach ($destinations as $dest) {
                 if (null != ($destInst = CerberusApplication::hashLookupAddress($dest, true))) {
                     // Skip if the destination is one of our senders or the matching TO
                     if (isset($helpdesk_senders[$destInst->email])) {
                         continue;
                     }
                     DAO_Ticket::createRequester($destInst->id, $id);
                 }
             }
         }
     }
     $attachment_path = APP_STORAGE_PATH . '/attachments/';
     // [TODO] This should allow external attachments (S3)
     $fields = array(DAO_Message::TICKET_ID => $id, DAO_Message::CREATED_DATE => $iDate, DAO_Message::ADDRESS_ID => $fromAddressInst->id);
     $email_id = DAO_Message::create($fields);
     // Content
     DAO_MessageContent::create($email_id, $message->body);
     // Headers
     foreach ($headers as $hk => $hv) {
         DAO_MessageHeader::create($email_id, $hk, $hv);
     }
     // [mdf] Loop through files to insert attachment records in the db, and move temporary files
     if (!empty($email_id)) {
         foreach ($message->files as $filename => $file) {
             /* @var $file ParserFile */
             //[mdf] skip rfc822 messages since we extracted their content above
             if ($file->mime_type == 'message/rfc822') {
                 continue;
             }
             $fields = array(DAO_Attachment::MESSAGE_ID => $email_id, DAO_Attachment::DISPLAY_NAME => $filename, DAO_Attachment::MIME_TYPE => $file->mime_type, DAO_Attachment::FILE_SIZE => intval($file->file_size));
             $file_id = DAO_Attachment::create($fields);
             if (empty($file_id)) {
                 @unlink($file->tmpname);
                 // remove our temp file
                 continue;
             }
             // Make file attachments use buckets so we have a max per directory
             $attachment_bucket = sprintf("%03d/", mt_rand(1, 100));
             $attachment_file = $file_id;
             if (!file_exists($attachment_path . $attachment_bucket)) {
                 @mkdir($attachment_path . $attachment_bucket, 0770, true);
                 // [TODO] Needs error checking
             }
             rename($file->getTempFile(), $attachment_path . $attachment_bucket . $attachment_file);
             // [TODO] Split off attachments into its own DAO
             DAO_Attachment::update($file_id, array(DAO_Attachment::FILEPATH => $attachment_bucket . $attachment_file));
         }
     }
     // Pre-load custom fields
     if (isset($message->custom_fields) && !empty($message->custom_fields)) {
         foreach ($message->custom_fields as $cf_id => $cf_val) {
             if (is_array($cf_val) && !empty($cf_val) || !is_array($cf_val) && 0 != strlen($cf_val)) {
                 DAO_CustomFieldValue::setFieldValue('cerberusweb.fields.source.ticket', $id, $cf_id, $cf_val);
             }
         }
     }
     // Finalize our new ticket details (post-message creation)
     if ($bIsNew && !empty($id) && !empty($email_id)) {
         // First thread (needed for anti-spam)
         DAO_Ticket::updateTicket($id, array(DAO_Ticket::FIRST_MESSAGE_ID => $email_id));
         // Prime the change fields (which a few things like anti-spam might change before we commit)
         $change_fields = array(DAO_Ticket::TEAM_ID => $group_id);
         $out = CerberusBayes::calculateTicketSpamProbability($id);
         if (!empty($group_id)) {
             @($spam_threshold = DAO_GroupSettings::get($group_id, DAO_GroupSettings::SETTING_SPAM_THRESHOLD, 80));
             @($spam_action = DAO_GroupSettings::get($group_id, DAO_GroupSettings::SETTING_SPAM_ACTION, ''));
             @($spam_action_param = DAO_GroupSettings::get($group_id, DAO_GroupSettings::SETTING_SPAM_ACTION_PARAM, ''));
             if ($out['probability'] * 100 >= $spam_threshold) {
                 $enumSpamTraining = CerberusTicketSpamTraining::SPAM;
                 switch ($spam_action) {
                     default:
                     case 0:
                         // do nothing
                         break;
                     case 1:
                         // delete
                         $change_fields[DAO_Ticket::IS_CLOSED] = 1;
                         $change_fields[DAO_Ticket::IS_DELETED] = 1;
                         break;
                     case 2:
                         // move
                         $buckets = DAO_Bucket::getAll();
                         // Verify bucket exists
                         if (!empty($spam_action_param) && isset($buckets[$spam_action_param])) {
                             $change_fields[DAO_Ticket::TEAM_ID] = $group_id;
                             $change_fields[DAO_Ticket::CATEGORY_ID] = $spam_action_param;
                         }
                         break;
                 }
             }
         }
         // end spam training
         // Save properties
         if (!empty($change_fields)) {
             DAO_Ticket::updateTicket($id, $change_fields);
         }
     }
     // Reply notifications (new messages are handled by 'move' listener)
     if (!$bIsNew) {
         // Inbound Reply Event
         $eventMgr = DevblocksPlatform::getEventService();
         $eventMgr->trigger(new Model_DevblocksEvent('ticket.reply.inbound', array('ticket_id' => $id)));
     }
     // New ticket processing
     if ($bIsNew) {
         // Auto reply
         @($autoreply_enabled = DAO_GroupSettings::get($group_id, DAO_GroupSettings::SETTING_AUTO_REPLY_ENABLED, 0));
         @($autoreply = DAO_GroupSettings::get($group_id, DAO_GroupSettings::SETTING_AUTO_REPLY, ''));
         /*
          * Send the group's autoreply if one exists, as long as this ticket isn't spam
          */
         if (!isset($options['no_autoreply']) && $autoreply_enabled && !empty($autoreply) && $enumSpamTraining != CerberusTicketSpamTraining::SPAM) {
             CerberusMail::sendTicketMessage(array('ticket_id' => $id, 'message_id' => $email_id, 'content' => str_replace(array('#ticket_id#', '#mask#', '#subject#', '#timestamp#', '#sender#', '#sender_first#', '#orig_body#'), array($id, $sMask, $sSubject, date('r'), $fromAddressInst->email, $fromAddressInst->first_name, ltrim($message->body)), $autoreply), 'is_autoreply' => true, 'dont_keep_copy' => true));
         }
     }
     // end bIsNew
     unset($message);
     // Re-open and update our date on new replies
     if (!$bIsNew) {
         DAO_Ticket::updateTicket($id, array(DAO_Ticket::UPDATED_DATE => time(), DAO_Ticket::IS_WAITING => 0, DAO_Ticket::IS_CLOSED => 0, DAO_Ticket::IS_DELETED => 0, DAO_Ticket::LAST_WROTE_ID => $fromAddressInst->id, DAO_Ticket::LAST_ACTION_CODE => CerberusTicketActionCode::TICKET_CUSTOMER_REPLY));
         // [TODO] The TICKET_CUSTOMER_REPLY should be sure of this message address not being a worker
     }
     @imap_errors();
     // Prevent errors from spilling out into STDOUT
     return $id;
 }
Exemple #11
0
    header('Location: ' . dirname($_SERVER['PHP_SELF']) . '/install/index.php');
    // [TODO] change this to a meta redirect
    exit;
}
require APP_PATH . '/api/Application.class.php';
DevblocksPlatform::init();
DevblocksPlatform::setExtensionDelegate('C4_DevblocksExtensionDelegate');
// Request
$request = DevblocksPlatform::readRequest();
// Patches (if not on the patch page)
if (@0 != strcasecmp(@$request->path[0], "update") && !DevblocksPlatform::versionConsistencyCheck()) {
    DevblocksPlatform::redirect(new DevblocksHttpResponse(array('update', 'locked')));
}
//DevblocksPlatform::readPlugins();
$session = DevblocksPlatform::getSessionService();
// Localization
DevblocksPlatform::setLocale(isset($_SESSION['locale']) && !empty($_SESSION['locale']) ? $_SESSION['locale'] : 'en_US');
if (isset($_SESSION['timezone'])) {
    @date_default_timezone_set($_SESSION['timezone']);
}
// Initialize Logging
if (method_exists('DevblocksPlatform', 'getConsoleLog')) {
    $timeout = ini_get('max_execution_time');
    $logger = DevblocksPlatform::getConsoleLog();
    $logger->info("[Devblocks] ** Platform starting (" . date("r") . ") **");
    $logger->info('[Devblocks] Time Limit: ' . ($timeout ? $timeout : 'unlimited') . " secs");
    $logger->info('[Devblocks] Memory Limit: ' . ini_get('memory_limit'));
}
// [JAS]: HTTP Request (App->Platform)
CerberusApplication::processRequest($request);
exit;
Exemple #12
0
 static function maint()
 {
     $db = DevblocksPlatform::getDatabaseService();
     $logger = DevblocksPlatform::getConsoleLog();
 }
Exemple #13
0
 function SendReport($full_filename, $filename)
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $from = '*****@*****.**';
     $personal = 'First Person';
     $subject = 'DR Metlife Report Generated on ' . date("n/j/y");
     $mail_headers = array();
     $mail_headers['X-CerberusCompose'] = '1';
     $toList = NULL;
     $abort = true;
     @($answernet_email01 = $this->getParam('answernet_email01', NULL));
     @($answernet_email02 = $this->getParam('answernet_email02', NULL));
     @($answernet_email03 = $this->getParam('answernet_email03', NULL));
     @($answernet_email04 = $this->getParam('answernet_email04', NULL));
     @($answernet_email05 = $this->getParam('answernet_email05', NULL));
     if ($answernet_email01 != '') {
         $logger->info("[Answernet.com] answernet_email01 = " . $answernet_email01);
         $toList = $answernet_email01;
         $abort = false;
     }
     if ($answernet_email02 != '') {
         $logger->info("[Answernet.com] answernet_email02 = " . $answernet_email02);
         if (!is_null($toList)) {
             $toList .= ",";
         }
         $toList .= $answernet_email02;
         $abort = false;
     }
     if ($answernet_email03 != '') {
         $logger->info("[Answernet.com] answernet_email03 = " . $answernet_email03);
         if (!is_null($toList)) {
             $toList .= ",";
         }
         $toList .= $answernet_email03;
         $abort = false;
     }
     if ($answernet_email04 != '') {
         $logger->info("[Answernet.com] answernet_email04 = " . $answernet_email04);
         if (!is_null($toList)) {
             $toList .= ",";
         }
         $toList .= $answernet_email04;
         $abort = false;
     }
     if ($answernet_email05 != '') {
         $logger->info("[Answernet.com] answernet_email05 = " . $answernet_email05);
         if (!is_null($toList)) {
             $toList .= ",";
         }
         $toList .= $answernet_email05;
         $abort = false;
     }
     if ($abort) {
         $logger->info("[Answernet.com] Aborting email send.");
         return;
     }
     $logger->info("[Answernet.com] toList = " . $toList);
     $files['name']['0'] = $filename;
     $files['type']['0'] = 'application/vnd.ms-excel';
     $files['tmp_name']['0'] = $full_filename;
     $properties = array('team_id' => 1771, 'content' => "Metlife DR report attached", 'subject' => $subject, 'closed' => 0, 'agent_id' => 0, 'to' => $toList, 'files' => $files);
     $ticket_id = CerberusMail::compose($properties);
     $logger->info("[Answernet.com] ticket_id = " . $ticket_id);
     return;
 }
Exemple #14
0
 static function maint()
 {
     $db = DevblocksPlatform::getDatabaseService();
     $logger = DevblocksPlatform::getConsoleLog();
     $sql = "DELETE QUICK category FROM category LEFT JOIN team ON category.team_id=team.id WHERE team.id IS NULL";
     $db->Execute($sql);
     $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' category records.');
     $sql = "DELETE QUICK group_setting FROM group_setting LEFT JOIN team ON group_setting.group_id=team.id WHERE team.id IS NULL";
     $db->Execute($sql);
     $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' group_setting records.');
     $sql = "DELETE QUICK custom_field FROM custom_field LEFT JOIN team ON custom_field.group_id=team.id WHERE custom_field.group_id > 0 AND team.id IS NULL";
     $db->Execute($sql);
     $logger->info('[Maint] Purged ' . $db->Affected_Rows() . ' custom_field records.');
 }
Exemple #15
0
 function ExportSnpp(Model_ExportType $export_type)
 {
     $logger = DevblocksPlatform::getConsoleLog();
     $db = DevblocksPlatform::getDatabaseService();
     @($snpp_current_hour = 0);
     @($snpp_sent_today = 0);
     $memory_limit = ini_get('memory_limit');
     if (substr($memory_limit, 0, -1) < 128) {
         @ini_set('memory_limit', '128M');
     }
     @set_time_limit(0);
     // Unlimited (if possible)
     $logger->info("[SNPP Exporter] Overloaded memory_limit to: " . ini_get('memory_limit'));
     $logger->info("[SNPP Exporter] Overloaded max_execution_time to: " . ini_get('max_execution_time'));
     $timeout = ini_get('max_execution_time');
     $runtime = microtime(true);
     $sql = sprintf("SELECT mr.id " . "FROM message_recipient mr " . "inner join customer_recipient cr on mr.recipient_id = cr.id " . "WHERE mr.send_status in (0,3,4) " . "AND cr.is_disabled = 0 " . "AND cr.export_type = %d " . "AND cr.type = 2 ", $export_type->id);
     $rs = $db->Execute($sql);
     // Loop though pending outbound emails.
     while ($row = mysql_fetch_assoc($rs)) {
         $id = $row['id'];
         $logger->info("[SNPP Exporter] Procing MR ID: " . $id);
         $message_recipient = DAO_MessageRecipient::get($id);
         $message = DAO_Message::get($message_recipient->message_id);
         $message_lines = explode('\\n', substr($message->message, 1, -1));
         $recipient = DAO_CustomerRecipient::get($message_recipient->recipient_id);
         $message_str = substr(implode("", $message_lines), 0, 160);
         // FIXME - Need to add in filter for now everything is unfiltered.
         // sendSnpp($phone_number, $message, $snpp_server="ann100sms01.answernet.com", $port=444)
         $send_status = FegSnpp::sendSnpp($recipient->address, $message_str);
         $logger->info("[SNPP Exporter] Send Status: " . ($send_status ? "Successful" : "Failure"));
         // Give plugins a chance to run export
         $eventMgr = DevblocksPlatform::getEventService();
         $eventMgr->trigger(new Model_DevblocksEvent('cron.send.snpp', array('recipient' => $recipient, 'message' => $message, 'message_lines' => $message_lines, 'message_recipient' => $message_recipient, 'send_status' => $send_status)));
         if ($send_status) {
             $snpp_current_hour++;
             $snpp_sent_today++;
         }
         $fields = array(DAO_MessageRecipient::SEND_STATUS => $send_status ? 2 : 1, DAO_MessageRecipient::CLOSED_DATE => $send_status ? time() : 0);
         DAO_MessageRecipient::update($id, $fields);
     }
     mysql_free_result($rs);
     if ($snpp_current_hour) {
         $current_fields = DAO_Stats::get(0);
         $fields = array(DAO_Stats::SNPP_CURRENT_HOUR => $current_fields->snpp_current_hour + $snpp_current_hour, DAO_Stats::SNPP_SENT_TODAY => $current_fields->snpp_sent_today + $snpp_sent_today);
         DAO_Stats::update(0, $fields);
     }
     return NULL;
 }
Exemple #16
0
	function run() {
		$logger = DevblocksPlatform::getConsoleLog();

		$logger->info("[] Syncing  Repositories");

		if (!extension_loaded("oauth")) {
			$logger->err("[] The 'oauth' extension is not loaded.  Aborting!");
			return false;
		}

		$timeout = ini_get('max_execution_time');
		$runtime = microtime(true);

		$issue = Wgm_API::getInstance();

		// get config
		$token = DevblocksPlatform::getPluginSetting('wgm.issues', 'access_token', '');
		$issue->setCredentials($token);

		// get last sync repo
		$last_sync_repo = $this->getParam('repos.last_repo', '');

		// max repos to sync
		$max_repos = $this->getParam('max_repos', 100);

		// get repos
		$repos = $issue->get('user/repos');

		$synced = 0;

		if($last_sync_repo !== '' && array_key_exists($last_sync_repo, $repos))
			$logger->info(sprintf("[] Starting sync from %s/%s", $repos[$last_sync_repo]['user'], $repos[$last_sync_repo]['name']));
		
		foreach($repos as $repo) {
			if($last_sync_repo !== '' && $repo['id'] != $last_sync_repo) {
				$logger->info(sprintf("[] Skipping repository %s!", $repository));
				continue;
			}
			// does the owner of the repository exist in the DB?
			if(null === $user = DAO_User::getByLogin($repo['owner']['login'])) {
				$user = $issue->get(sprintf('users/%s', $repo['owner']['login']));

				$fields = array(
					DAO_User::NUMBER => $user['id'],
					DAO_User::LOGIN => $user['login'],
					DAO_User::NAME => $user['name'],
					DAO_User::EMAIL => $user['email']
				);
				$user = DAO_User::create($fields);
			}
			$fields = array(
				DAO_Repository::NUMBER => $repo['id'],
				DAO_Repository::NAME => $repo['name'],
				DAO_Repository::DESCRIPTION => $repo['description'],
				DAO_Repository::USER_ID => $user->id,
				DAO_Repository::ENABLED => true
			);
				
			// does the repo exist in the DB?
			if(null === $repository = DAO_Repository::getByNumber($repo['id'])) {
				DAO_Repository::create($fields);
			} else {
				DAO_Repository::update($repository->id, $fields);
			}
			$synced++;
			// check amount of repos synced
			if($synced == $max_repos) {
				$this->setParam('repos.last_repo', $repo_id);
				break 2;
					
			}
		}
		foreach($repos as $repo) {
			// is the repo enabled?
			$user = DAO_User::get($repo->user_id);
			$repository = sprintf("%s/%s", $user->login, $repo->name);
			if($last_sync_repo !== '' && $repo_id != $last_sync_repo) {
				$logger->info(sprintf("[] Skipping repository %s!", $repository));
				continue;
			} elseif(!$repo->enabled) {
				$logger->info(sprintf("[] Skipping repository %s since it isn't enabled!", $repository));
				continue;
			}

		}

		$logger->info("[] Total Runtime: ".number_format((microtime(true)-$runtime)*1000,2)." ms");
	}