function run() { $logger = DevblocksPlatform::getConsoleLog(); $logger->info("[Sensors] Starting..."); // Only pull enabled sensors with an extension_id $sensors = DAO_Sensor::getWhere(sprintf("%s=%d", DAO_Sensor::IS_DISABLED, 0)); $sensor_types = DevblocksPlatform::getExtensions('portsensor.sensor', true); if (is_array($sensors)) { foreach ($sensors as $sensor) { if (!empty($sensor->extension_id) && isset($sensor_types[$sensor->extension_id])) { // Skip external sensors if ('sensor.external' == $sensor->extension_id) { continue; } $runner = $sensor_types[$sensor->extension_id]; $output = sprintf("%s (%s)", $sensor->name, $sensor->extension_id); if (method_exists($runner, 'run')) { $fields = array(); $success = $runner->run($sensor, $fields); $fields[DAO_Sensor::UPDATED_DATE] = time(); $fields[DAO_Sensor::FAIL_COUNT] = $success ? 0 : intval($sensor->fail_count) + 1; DAO_Sensor::update($sensor->id, $fields); } $logger->info("[Sensors] Running {$output}... {$result}"); } } } // Sensor Runner Event $eventMgr = DevblocksPlatform::getEventService(); $eventMgr->trigger(new Model_DevblocksEvent('cron.sensors.post', array())); $logger->info("[Sensors] Finished!"); }
private function newTicketComment($event) { DevblocksPlatform::getExtensions('cerberusweb.ticket.tab', true); // ticket_comment.id @($comment_id = $event->params['comment_id']); // ticket.id @($ticket_id = $event->params['ticket_id']); // address.id @($address_id = $event->params['address_id']); // text of actual comment. @($comment_text = $event->params['comment']); if (empty($ticket_id) || empty($address_id) || empty($comment_text)) { return; } $setting_manifest = DevblocksPlatform::getExtension(AnswernetLastActionAndAuditLogConfigTab::ID); $setting = $setting_manifest->createInstance(); /* @var $job CerberusCronPageExtension */ $al_comment_enabled = intval($setting->getParam(AnswernetLastActionAndAuditLogConfigTab::AL_COMMENT_ENABLED, 0)); $uf_comment_enabled = intval($setting->getParam(AnswernetLastActionAndAuditLogConfigTab::UF_COMMENT_ENABLED, 0)); if (class_exists('DAO_TicketAuditLog', true)) { if ($al_comment_enabled) { @($address = DAO_Address::get($address_id)); @($worker_id = DAO_Worker::lookupAgentEmail($address->email)); $fields = array(DAO_TicketAuditLog::TICKET_ID => $ticket_id, DAO_TicketAuditLog::WORKER_ID => $worker_id, DAO_TicketAuditLog::CHANGE_DATE => time(), DAO_TicketAuditLog::CHANGE_FIELD => "answernet.last_action_and_audit_log.type.comment", DAO_TicketAuditLog::CHANGE_VALUE => substr($comment_text, 0, 128)); $log_id = DAO_TicketAuditLog::create($fields); unset($fields); } } if ($uf_comment_enabled) { $change_fields[DAO_Ticket::UPDATED_DATE] = time(); DAO_Ticket::updateTicket($ticket_id, $change_fields); unset($change_fields); } }
function render() { $active_worker = UsermeetApplication::getActiveWorker(); $visit = UsermeetApplication::getVisit(); $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $response = DevblocksPlatform::getHttpResponse(); $tpl->assign('request_path', implode('/', $response->path)); // Remember the last tab/URL if (null == ($selected_tab = @$response->path[1])) { $selected_tab = $visit->get(UsermeetVisit::KEY_HOME_SELECTED_TAB, 'notifications'); } $tpl->assign('selected_tab', $selected_tab); $tab_manifests = DevblocksPlatform::getExtensions('usermeet.home.tab', false); $tpl->assign('tab_manifests', $tab_manifests); // Custom workspaces // $workspaces = DAO_WorkerWorkspaceList::getWorkspaces($active_worker->id); // $tpl->assign('workspaces', $workspaces); // ====== Who's Online $whos_online = DAO_Worker::getAllOnline(); if (!empty($whos_online)) { $tpl->assign('whos_online', $whos_online); $tpl->assign('whos_online_count', count($whos_online)); } $tpl->display('file:' . $this->_TPL_PATH . 'home/index.tpl'); }
private function _getModules() { if (empty($this->_modules)) { // [TODO] Load sub-controller plugins $module_manifests = DevblocksPlatform::getExtensions('usermeet.sc.controller', false, true); foreach ($module_manifests as $module_manifest) { /* @var $module_manifest DevblocksExtensionManifest */ if (null != ($mods = $module_manifest->params['modules'])) { foreach ($mods as $mod) { $mod['extension_id'] = $module_manifest->id; $this->_modules[$mod['uri']] = $mod; } } } } return $this->_modules; }
function render() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->cache_lifetime = "0"; $tpl->assign('path', $this->_TPL_PATH); $response = DevblocksPlatform::getHttpResponse(); $stack = $response->path; array_shift($stack); // activity $tab_manifests = DevblocksPlatform::getExtensions('cerberusweb.activity.tab', false); uasort($tab_manifests, create_function('$a, $b', "return strcasecmp(\$a->name,\$b->name);\n")); $tpl->assign('tab_manifests', $tab_manifests); @($tab_selected = array_shift($stack)); if (empty($tab_selected)) { $tab_selected = 'tasks'; } $tpl->assign('tab_selected', $tab_selected); $tpl->display('file:' . $this->_TPL_PATH . 'activity/index.tpl'); }
function render() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $visit = CerberusApplication::getVisit(); $translate = DevblocksPlatform::getTranslationService(); $response = DevblocksPlatform::getHttpResponse(); $tpl->assign('request_path', implode('/', $response->path)); $stack = $response->path; array_shift($stack); // research $tab_manifests = DevblocksPlatform::getExtensions('cerberusweb.research.tab', false); uasort($tab_manifests, create_function('$a, $b', "return strcasecmp(\$a->name,\$b->name);\n")); $tpl->assign('tab_manifests', $tab_manifests); @($tab_selected = array_shift($stack)); if (empty($tab_selected)) { $tab_selected = ''; } $tpl->assign('tab_selected', $tab_selected); $tpl->display('file:' . $this->_TPL_PATH . 'research/index.tpl'); }
function render() { $translate = DevblocksPlatform::getTranslationService(); $tpl = DevblocksPlatform::getTemplateService(); $tpl_path = $this->_TPL_PATH; $tpl->assign('path', $tpl_path); $response = DevblocksPlatform::getHttpResponse(); $path = $response->path; array_shift($path); // preferences $tab_manifests = DevblocksPlatform::getExtensions('feg.preferences.tab', false); $tpl->assign('tab_manifests', $tab_manifests); @($section = array_shift($path)); // section switch ($section) { default: $tpl->assign('tab', $section); $tpl->display('file:' . $tpl_path . 'preferences/index.tpl'); break; } }
function render() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $active_worker = FegApplication::getActiveWorker(); $visit = FegApplication::getVisit(); $response = DevblocksPlatform::getHttpResponse(); $translate = DevblocksPlatform::getTranslationService(); $url = DevblocksPlatform::getUrlService(); $stack = $response->path; @array_shift($stack); // customer @($customer_id = array_shift($stack)); @($customer = DAO_CustomerAccount::get($customer_id)); if (empty($customer)) { echo "<H1>" . $translate->_('customer.display.invalid_customer') . "</H1>"; return; } $tpl->assign('customer_id', $customer_id); // Tabs $tab_manifests = DevblocksPlatform::getExtensions('feg.customer.tab', false); $tpl->assign('tab_manifests', $tab_manifests); @($tab_selected = array_shift($stack)); if (empty($tab_selected)) { $tab_selected = 'property'; } $tpl->assign('tab_selected', $tab_selected); switch ($tab_selected) { case 'property': @($tab_parm = array_shift($stack)); break; } // ====== Who's Online $whos_online = DAO_Worker::getAllOnline(); if (!empty($whos_online)) { $tpl->assign('whos_online', $whos_online); $tpl->assign('whos_online_count', count($whos_online)); } $tpl->display('file:' . $this->_TPL_PATH . 'customer/index.tpl'); }
function handleRequest(DevblocksHttpRequest $request) { $translate = DevblocksPlatform::getTranslationService(); // [TODO] Do we want any concept of authentication here? $stack = $request->path; array_shift($stack); // rss $hash = array_shift($stack); $feed = DAO_ViewRss::getByHash($hash); if (empty($feed)) { die($translate->_('rss.bad_feed')); } // Sources $rss_sources = DevblocksPlatform::getExtensions('cerberusweb.rss.source', true); if (isset($rss_sources[$feed->source_extension])) { $rss_source =& $rss_sources[$feed->source_extension]; /* @var $rss_source Extension_RssSource */ header("Content-Type: text/xml"); echo $rss_source->getFeedAsRss($feed); } exit; }
function render() { $translate = DevblocksPlatform::getTranslationService(); $tpl = DevblocksPlatform::getTemplateService(); $tpl_path = $this->_TPL_PATH; $tpl->assign('path', $tpl_path); $tpl->cache_lifetime = "0"; $response = DevblocksPlatform::getHttpResponse(); $path = $response->path; array_shift($path); // preferences $tab_manifests = DevblocksPlatform::getExtensions('cerberusweb.preferences.tab', false); $tpl->assign('tab_manifests', $tab_manifests); @($section = array_shift($path)); // section switch ($section) { case 'confirm_email': @($code = array_shift($path)); $active_worker = CerberusApplication::getActiveWorker(); $worker_addresses = DAO_AddressToWorker::getWhere(sprintf("%s = '%s' AND %s = %d", DAO_AddressToWorker::CODE, addslashes(str_replace(' ', '', $code)), DAO_AddressToWorker::WORKER_ID, $active_worker->id)); @($worker_address = array_shift($worker_addresses)); if (!empty($code) && null != $worker_address && $worker_address->code == $code && $worker_address->code_expire > time()) { DAO_AddressToWorker::update($worker_address->address, array(DAO_AddressToWorker::CODE => '', DAO_AddressToWorker::IS_CONFIRMED => 1, DAO_AddressToWorker::CODE_EXPIRE => 0)); $output = array(vsprintf($translate->_('prefs.address.confirm.tip'), $worker_address->address)); $tpl->assign('pref_success', $output); } else { $errors = array($translate->_('prefs.address.confirm.invalid_code')); $tpl->assign('pref_errors', $errors); } $tpl->display('file:' . $tpl_path . 'preferences/index.tpl'); break; default: $tpl->assign('tab', $section); $tpl->display('file:' . $tpl_path . 'preferences/index.tpl'); break; } }
private function newTicketComment($event) { DevblocksPlatform::getExtensions('cerberusweb.ticket.tab', true); // ticket_comment.id @($comment_id = $event->params['comment_id']); // Event context @($context = $event->params['context']); // ticket.id if context == ticket. @(${$ticket_id} = $event->params['context_id']); @($address_id = $event->params['address_id']); // text of actual comment. @($comment_text = $event->params['comment']); if (CerberusContexts::CONTEXT_TICKET != $context) { return; } if (empty($ticket_id) || empty($address_id) || empty($comment_text)) { return; } $settings = DevblocksPlatform::getPluginSettingsService(); $al_merge_enabled = intval($settings->get('cerb5blog.last_action_and_audit_log', 'al_merge_enabled', 0)); if (class_exists('DAO_TicketAuditLog', true)) { $al_comment_enabled = intval($settings->get('cerb5blog.last_action_and_audit_log', 'al_comment_enabled', 0)); if ($al_comment_enabled) { @($address = DAO_Address::get($address_id)); @($worker_id = DAO_Worker::lookupAgentEmail($address->email)); $fields = array(DAO_TicketAuditLog::TICKET_ID => $ticket_id, DAO_TicketAuditLog::WORKER_ID => $worker_id, DAO_TicketAuditLog::CHANGE_DATE => time(), DAO_TicketAuditLog::CHANGE_FIELD => "cerb5blog.last_action_and_audit_log.type.comment", DAO_TicketAuditLog::CHANGE_VALUE => substr($comment_text, 0, 128)); $log_id = DAO_TicketAuditLog::create($fields); unset($fields); } } $uf_comment_enabled = intval($settings->get('cerb5blog.last_action_and_audit_log', 'uf_comment_enabled', 0)); if ($uf_comment_enabled) { $change_fields[DAO_Ticket::UPDATED_DATE] = time(); DAO_Ticket::update($ticket_id, $change_fields); unset($change_fields); } }
/** * 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; }
function getCommunityAction() { @($id = DevblocksPlatform::importGPC($_REQUEST['id'], 'integer', 0)); $tpl = DevblocksPlatform::getTemplateService(); $tpl->cache_lifetime = "0"; $tpl_path = dirname(__FILE__) . '/templates/'; $tpl->assign('path', $tpl_path); if (!empty($id)) { $community = DAO_Community::get($id); $tpl->assign('community', $community); } // Tool Manifests $tools = DevblocksPlatform::getExtensions('usermeet.tool', false, true); $tpl->assign('tool_manifests', $tools); $tpl->display('file:' . $tpl_path . 'community/config/tab/community_config.tpl'); }
public function writeResponse(DevblocksHttpResponse $response) { $path = $response->path; // [JAS]: Ajax? // [TODO] Explore outputting whitespace here for Safari // if(empty($path)) // return; $tpl = DevblocksPlatform::getTemplateService(); $session = DevblocksPlatform::getSessionService(); $settings = DevblocksPlatform::getPluginSettingsService(); $translate = DevblocksPlatform::getTranslationService(); $active_worker = FegApplication::getActiveWorker(); $visit = $session->getVisit(); $page_manifests = $this->_getAllowedPages(); $controller = array_shift($path); // Default page [TODO] This is supposed to come from framework.config.php if (empty($controller)) { $controller = 'preferences'; } // [JAS]: Require us to always be logged in for Feg pages if (empty($visit) && 0 != strcasecmp($controller, 'login')) { $query = array(); if (!empty($response->path)) { $query = array('url' => urlencode(implode('/', $response->path))); } DevblocksPlatform::redirect(new DevblocksHttpRequest(array('login'), $query)); } $page_id = $this->_getPageIdByUri($controller); @($page = DevblocksPlatform::getExtension($page_id, true)); /* @var $page FegPageExtension */ if (empty($page)) { header("Status: 404"); return; // [TODO] 404 } // [JAS]: Listeners (Step-by-step guided tour, etc.) $listenerManifests = DevblocksPlatform::getExtensions('devblocks.listener.http'); foreach ($listenerManifests as $listenerManifest) { /* @var $listenerManifest DevblocksExtensionManifest */ $inst = $listenerManifest->createInstance(); /* @var $inst DevblocksHttpRequestListenerExtension */ $inst->run($response, $tpl); } $tpl->assign('active_worker', $active_worker); $tour_enabled = false; if (!empty($visit) && !is_null($active_worker)) { $tour_enabled = intval(DAO_WorkerPref::get($active_worker->id, 'assist_mode', 1)); $keyboard_shortcuts = intval(DAO_WorkerPref::get($active_worker->id, 'keyboard_shortcuts', 1)); $tpl->assign('pref_keyboard_shortcuts', $keyboard_shortcuts); // $active_worker_memberships = $active_worker->getMemberships(); // $tpl->assign('active_worker_memberships', $active_worker_memberships); $unread_notifications = DAO_WorkerEvent::getUnreadCountByWorker($active_worker->id); $tpl->assign('active_worker_notify_count', $unread_notifications); DAO_Worker::logActivity($active_worker->id, $page->getActivity()); } $tpl->assign('tour_enabled', $tour_enabled); // [JAS]: Variables provided to all page templates $tpl->assign('settings', $settings); $tpl->assign('session', $_SESSION); $tpl->assign('translate', $translate); $tpl->assign('visit', $visit); $tpl->assign('license', FegLicense::getInstance()); $tpl->assign('page_manifests', $page_manifests); $tpl->assign('page', $page); $tpl->assign('response_uri', implode('/', $response->path)); $core_tpl = APP_PATH . '/features/feg.core/templates/'; $tpl->assign('core_tpl', $core_tpl); // Prebody Renderers $preBodyRenderers = DevblocksPlatform::getExtensions('feg.renderer.prebody', true); if (!empty($preBodyRenderers)) { $tpl->assign('prebody_renderers', $preBodyRenderers); } // Postbody Renderers $postBodyRenderers = DevblocksPlatform::getExtensions('feg.renderer.postbody', true); if (!empty($postBodyRenderers)) { $tpl->assign('postbody_renderers', $postBodyRenderers); } // Timings $tpl->assign('render_time', microtime(true) - DevblocksPlatform::getStartTime()); if (function_exists('memory_get_usage') && function_exists('memory_get_peak_usage')) { $tpl->assign('render_memory', memory_get_usage() - DevblocksPlatform::getStartMemory()); $tpl->assign('render_peak_memory', memory_get_peak_usage() - DevblocksPlatform::getStartPeakMemory()); } $tpl->display($core_tpl . 'border.tpl'); // $cache = DevblocksPlatform::getCacheService(); // $cache->printStatistics(); }
function showConversationAction() { @($id = DevblocksPlatform::importGPC($_REQUEST['ticket_id'], 'integer')); @($expand_all = DevblocksPlatform::importGPC($_REQUEST['expand_all'], 'integer', '0')); @($active_worker = CerberusApplication::getActiveWorker()); $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $tpl->assign('expand_all', $expand_all); $ticket = DAO_Ticket::getTicket($id); $tpl->assign('ticket', $ticket); $tpl->assign('requesters', $ticket->getRequesters()); $messages = $ticket->getMessages(); arsort($messages); $tpl->assign('latest_message_id', key($messages)); $tpl->assign('messages', $messages); // Thread comments and messages on the same level $convo_timeline = array(); // Track senders and their orgs $message_senders = array(); $message_sender_orgs = array(); // Loop messages foreach ($messages as $message_id => $message) { /* @var $message CerberusMessage */ $key = $message->created_date . '_m' . $message_id; // build a chrono index of messages $convo_timeline[$key] = array('m', $message_id); // If we haven't cached this sender address yet if (!isset($message_senders[$message->address_id])) { if (null != ($sender_addy = DAO_Address::get($message->address_id))) { $message_senders[$sender_addy->id] = $sender_addy; // If we haven't cached this sender org yet if (!isset($message_sender_orgs[$sender_addy->contact_org_id])) { if (null != ($sender_org = DAO_ContactOrg::get($sender_addy->contact_org_id))) { $message_sender_orgs[$sender_org->id] = $sender_org; } } } } } $tpl->assign('message_senders', $message_senders); $tpl->assign('message_sender_orgs', $message_sender_orgs); @($mail_inline_comments = DAO_WorkerPref::get($active_worker->id, 'mail_inline_comments', 1)); if ($mail_inline_comments) { // if inline comments are enabled $comments = DAO_TicketComment::getByTicketId($id); arsort($comments); $tpl->assign('comments', $comments); // build a chrono index of comments foreach ($comments as $comment_id => $comment) { /* @var $comment Model_TicketComment */ $key = $comment->created . '_c' . $comment_id; $convo_timeline[$key] = array('c', $comment_id); } } // sort the timeline if (!$expand_all) { krsort($convo_timeline); } else { ksort($convo_timeline); } $tpl->assign('convo_timeline', $convo_timeline); // Message Notes $notes = DAO_MessageNote::getByTicketId($id); $message_notes = array(); // Index notes by message id if (is_array($notes)) { foreach ($notes as $note) { if (!isset($message_notes[$note->message_id])) { $message_notes[$note->message_id] = array(); } $message_notes[$note->message_id][$note->id] = $note; } } $tpl->assign('message_notes', $message_notes); // Message toolbar items $messageToolbarItems = DevblocksPlatform::getExtensions('cerberusweb.message.toolbaritem', true); if (!empty($messageToolbarItems)) { $tpl->assign('message_toolbaritems', $messageToolbarItems); } // Workers $workers = DAO_Worker::getAll(); $tpl->assign('workers', $workers); $tpl->register_modifier('makehrefs', array('CerberusUtils', 'smarty_modifier_makehrefs')); $tpl->display('file:' . $this->_TPL_PATH . 'display/modules/conversation/index.tpl'); }
function render() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $visit = CerberusApplication::getVisit(); $response = DevblocksPlatform::getHttpResponse(); $stack = $response->path; @array_shift($stack); // contacts @($selected_tab = array_shift($stack)); // orgs|addresses|* $tpl->assign('selected_tab', $selected_tab); // Allow a non-tab renderer switch ($selected_tab) { case 'import': switch (@array_shift($stack)) { case 'step2': $type = $visit->get('import.last.type', ''); switch ($type) { case 'orgs': $fields = DAO_ContactOrg::getFields(); $tpl->assign('fields', $fields); $custom_fields = DAO_CustomField::getBySource(ChCustomFieldSource_Org::ID); $tpl->assign('custom_fields', $custom_fields); break; case 'addys': $fields = DAO_Address::getFields(); $tpl->assign('fields', $fields); $custom_fields = DAO_CustomField::getBySource(ChCustomFieldSource_Address::ID); $tpl->assign('custom_fields', $custom_fields); break; } $tpl->display('file:' . $this->_TPL_PATH . 'contacts/import/mapping.tpl'); return; break; } break; // [TODO] The org display page should probably move to its own controller // [TODO] The org display page should probably move to its own controller case 'orgs': switch (@array_shift($stack)) { case 'display': $tab_manifests = DevblocksPlatform::getExtensions('cerberusweb.org.tab', false); $tpl->assign('tab_manifests', $tab_manifests); $id = array_shift($stack); $contact = DAO_ContactOrg::get($id); $tpl->assign('contact', $contact); $task_count = DAO_Task::getCountBySourceObjectId('cerberusweb.tasks.org', $contact->id); $tpl->assign('tasks_total', $task_count); $people_count = DAO_Address::getCountByOrgId($contact->id); $tpl->assign('people_total', $people_count); // Does a series exist? // [TODO] This is highly redundant if (null != ($series_info = $visit->get('ch_org_series', null))) { @($series = $series_info['series']); // Is this ID part of the series? If not, invalidate if (!isset($series[$contact->id])) { $visit->set('ch_org_series', null); } else { $series_stats = array('title' => $series_info['title'], 'total' => $series_info['total'], 'count' => count($series)); reset($series); $cur = 1; while ($pos = key($series)) { if (intval($pos) == intval($contact->id)) { $series_stats['cur'] = $cur; if (false !== prev($series)) { @($series_stats['prev'] = key($series)); next($series); // skip to current } else { reset($series); } next($series); // next @($series_stats['next'] = key($series)); break; } next($series); $cur++; } $tpl->assign('series_stats', $series_stats); } } $tpl->display('file:' . $this->_TPL_PATH . 'contacts/orgs/display.tpl'); return; break; // case 'orgs/display' } // switch (action) break; } // switch (tab) $tpl->display('file:' . $this->_TPL_PATH . 'contacts/index.tpl'); return; // case 'people': // $view = C4_AbstractViewLoader::getView('addybook_people'); // C4_AddressView::DEFAULT_ID // // if(null == $view) { // $view = new C4_AddressView(); // $view->id = 'addybook_people'; // $view->name = 'People'; // $view->params = array( // new DevblocksSearchCriteria(SearchFields_Address::CONTACT_ORG_ID,'!=',0), // ); // // C4_AbstractViewLoader::setView('addybook_people', $view); // } // // $tpl->assign('view', $view); // $tpl->assign('contacts_page', 'people'); // $tpl->assign('view_fields', C4_AddressView::getFields()); // $tpl->assign('view_searchable_fields', C4_AddressView::getSearchFields()); // $tpl->display('file:' . $this->_TPL_PATH . 'contacts/people/index.tpl'); // break; }
function getFeedAsRss($feed) { $xmlstr = <<<XML \t\t<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'> \t\t</rss> XML; $xml = new SimpleXMLElement($xmlstr); $translate = DevblocksPlatform::getTranslationService(); $url = DevblocksPlatform::getUrlService(); // Channel $channel = $xml->addChild('channel'); $channel->addChild('title', $feed->title); $channel->addChild('link', $url->write('', true)); $channel->addChild('description', ''); // View $view = new C4_TaskView(); $view->name = $feed->title; $view->params = $feed->params['params']; $view->renderLimit = 100; $view->renderSortBy = $feed->params['sort_by']; $view->renderSortAsc = $feed->params['sort_asc']; // Results list($results, $count) = $view->getData(); $task_sources = DevblocksPlatform::getExtensions('cerberusweb.task.source', true); // [TODO] We should probably be building this feed with Zend Framework for compliance foreach ($results as $task) { $created = intval($task[SearchFields_Task::UPDATED_DATE]); if (empty($created)) { $created = time(); } $eItem = $channel->addChild('item'); $escapedSubject = htmlspecialchars($task[SearchFields_Task::TITLE], null, LANG_CHARSET_CODE); //filter out a couple non-UTF-8 characters (0xC and ESC) $escapedSubject = preg_replace("/[\f]/", '', $escapedSubject); $eTitle = $eItem->addChild('title', $escapedSubject); //$eDesc = $eItem->addChild('description', htmlspecialchars($task[SearchFields_Task::CONTENT],null,LANG_CHARSET_CODE)); $eDesc = $eItem->addChild('description', ''); if (isset($task_sources[$task[SearchFields_Task::SOURCE_EXTENSION]]) && isset($task[SearchFields_Task::SOURCE_ID])) { $source_ext =& $task_sources[$task[SearchFields_Task::SOURCE_EXTENSION]]; /* @var $source_ext Extension_TaskSource */ $source_ext_info = $source_ext->getSourceInfo($task[SearchFields_Task::SOURCE_ID]); $link = $source_ext_info['url']; $eLink = $eItem->addChild('link', $link); } else { $link = $url->write('c=activity&tab=tasks', true); $eLink = $eItem->addChild('link', $link); } $eDate = $eItem->addChild('pubDate', gmdate('D, d M Y H:i:s T', $created)); $eGuid = $eItem->addChild('guid', md5($escapedSubject . $link . $created)); $eGuid->addAttribute('isPermaLink', "false"); } return $xml->asXML(); }
/** * @return DevblocksTourCallout[] */ static function getTourCallouts() { static $callouts = null; if (!is_null($callouts)) { return $callouts; } $callouts = array(); $listenerManifests = DevblocksPlatform::getExtensions('devblocks.listener.http'); foreach ($listenerManifests as $listenerManifest) { /* @var $listenerManifest DevblocksExtensionManifest */ $inst = $listenerManifest->createInstance(); /* @var $inst IDevblocksTourListener */ if ($inst instanceof IDevblocksTourListener) { $callouts += $inst->registerCallouts(); } } return $callouts; }
function showTabInboxAction() { @($group_id = DevblocksPlatform::importGPC($_REQUEST['id'], 'integer', 0)); $tpl = DevblocksPlatform::getTemplateService(); $tpl_path = $this->_TPL_PATH; $tpl->assign('path', $tpl_path); $tpl->assign('group_id', $group_id); $active_worker = CerberusApplication::getActiveWorker(); if (!$active_worker->isTeamManager($group_id) && !$active_worker->is_superuser) { return; } $team_rules = DAO_GroupInboxFilter::getByGroupId($group_id); $tpl->assign('team_rules', $team_rules); $groups = DAO_Group::getAll(); $tpl->assign('groups', $groups); $buckets = DAO_Bucket::getAll(); $tpl->assign('buckets', $buckets); $workers = DAO_Worker::getAll(); $tpl->assign('workers', $workers); // Custom Field Sources $source_manifests = DevblocksPlatform::getExtensions('cerberusweb.fields.source', false); $tpl->assign('source_manifests', $source_manifests); // Custom Fields $custom_fields = DAO_CustomField::getAll(); $tpl->assign('custom_fields', $custom_fields); $tpl->display('file:' . $tpl_path . 'groups/manage/filters/index.tpl'); }
if (is_array($plugins)) { foreach ($plugins as $plugin_manifest) { /* @var $plugin_manifest DevblocksPluginManifest */ switch ($plugin_manifest->id) { case "app.core": $plugin_manifest->setEnabled(true); break; default: $plugin_manifest->setEnabled(false); break; } } } DevblocksPlatform::clearCache(); // Run enabled plugin patches $patches = DevblocksPlatform::getExtensions("devblocks.patch.container"); if (is_array($patches)) { foreach ($patches as $patch_manifest) { /* @var $patch_manifest DevblocksExtensionManifest */ $container = $patch_manifest->createInstance(); /* @var $container DevblocksPatchContainerExtension */ $patchMgr->registerPatchContainer($container); } } if (!$patchMgr->run()) { // fail $tpl->assign('template', 'steps/step_init_db.tpl.php'); } else { // success $tpl->assign('step', STEP_FINISHED); $tpl->display('steps/redirect.tpl.php');
public function writeResponse(DevblocksHttpResponse $response) { /* @var $response DevblocksHttpResponse */ $path = $response->path; $uri_prefix = array_shift($path); // should be mobile // [JAS]: Ajax? // [TODO] Explore outputting whitespace here for Safari // if(empty($path)) // return; $tpl = DevblocksPlatform::getTemplateService(); $session = DevblocksPlatform::getSessionService(); $settings = CerberusSettings::getInstance(); $translate = DevblocksPlatform::getTranslationService(); $visit = $session->getVisit(); $controller = array_shift($path); $pages = DevblocksPlatform::getExtensions('cerberusweb.mobile.page', true); // Default page [TODO] This is supposed to come from framework.config.php if (empty($controller)) { $controller = 'tickets'; } // [JAS]: Require us to always be logged in for Cerberus pages // [TODO] This should probably consult with the page itself for ::authenticated() if (empty($visit)) { $controller = 'login'; } $page_id = $this->_getPageIdByUri($controller); /* @var $page CerberusPageExtension */ @($page = $pages[$page_id]); if (empty($page)) { return; } // 404 // [TODO] Reimplement if (!empty($visit) && !is_null($visit->getWorker())) { DAO_Worker::logActivity($visit->getWorker()->id, $page->getActivity()); } // [JAS]: Listeners (Step-by-step guided tour, etc.) $listenerManifests = DevblocksPlatform::getExtensions('devblocks.listener.http'); foreach ($listenerManifests as $listenerManifest) { /* @var $listenerManifest DevblocksExtensionManifest */ $inst = $listenerManifest->createInstance(); /* @var $inst DevblocksHttpRequestListenerExtension */ $inst->run($response, $tpl); } // [JAS]: Pre-translate any dynamic strings $common_translated = array(); if (!empty($visit) && !is_null($visit->getWorker())) { $common_translated['header_signed_in'] = vsprintf($translate->_('header.signed_in'), array('<b>' . $visit->getWorker()->getName() . '</b>')); } $tpl->assign('common_translated', $common_translated); // $tour_enabled = false; // if(!empty($visit) && !is_null($visit->getWorker())) { // $worker = $visit->getWorker(); // $tour_enabled = DAO_WorkerPref::get($worker->id, 'assist_mode'); // $tour_enabled = ($tour_enabled===false) ? 1 : $tour_enabled; // if(DEMO_MODE) $tour_enabled = 1; // override for DEMO // } // $tpl->assign('tour_enabled', $tour_enabled); // [JAS]: Variables provided to all page templates $tpl->assign('settings', $settings); $tpl->assign('session', $_SESSION); $tpl->assign('translate', $translate); $tpl->assign('visit', $visit); $tpl->assign('license', CerberusLicense::getInstance()); $active_worker = CerberusApplication::getActiveWorker(); $tpl->assign('active_worker', $active_worker); if (!empty($active_worker)) { $active_worker_memberships = $active_worker->getMemberships(); $tpl->assign('active_worker_memberships', $active_worker_memberships); } $tpl->assign('pages', $pages); $tpl->assign('page', $page); $tpl->assign('response_uri', implode('/', $response->path)); $tpl_path = DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.mobile/templates/'; $tpl->assign('core_tpl', DEVBLOCKS_PLUGIN_PATH . 'cerberusweb.core/templates/'); // Timings $tpl->assign('render_time', microtime(true) - DevblocksPlatform::getStartTime()); if (function_exists('memory_get_usage') && function_exists('memory_get_peak_usage')) { $tpl->assign('render_memory', memory_get_usage() - DevblocksPlatform::getStartMemory()); $tpl->assign('render_peak_memory', memory_get_peak_usage() - DevblocksPlatform::getStartPeakMemory()); } $tpl->display($tpl_path . 'border.tpl'); }
function saveTaskPeekAction() { @($id = DevblocksPlatform::importGPC($_REQUEST['id'], 'integer', '')); @($view_id = DevblocksPlatform::importGPC($_REQUEST['view_id'], 'string', '')); @($link_namespace = DevblocksPlatform::importGPC($_REQUEST['link_namespace'], 'string', '')); @($link_object_id = DevblocksPlatform::importGPC($_REQUEST['link_object_id'], 'integer', 0)); @($do_delete = DevblocksPlatform::importGPC($_REQUEST['do_delete'], 'integer', 0)); $active_worker = CerberusApplication::getActiveWorker(); if (!empty($id) && !empty($do_delete)) { // delete $task = DAO_Task::get($id); // Check privs if ($active_worker->hasPriv('core.tasks.actions.create') && $active_worker->id == $task->worker_id || $active_worker->hasPriv('core.tasks.actions.update_nobody') && empty($task->worker_id) || $active_worker->hasPriv('core.tasks.actions.update_all')) { DAO_Task::delete($id); } } else { // create|update $fields = array(); // Title @($title = DevblocksPlatform::importGPC($_REQUEST['title'], 'string', '')); if (!empty($title)) { $fields[DAO_Task::TITLE] = $title; } // Completed @($completed = DevblocksPlatform::importGPC($_REQUEST['completed'], 'integer', 0)); $fields[DAO_Task::IS_COMPLETED] = intval($completed); // [TODO] This shouldn't constantly update the completed date (it should compare) if ($completed) { $fields[DAO_Task::COMPLETED_DATE] = time(); } else { $fields[DAO_Task::COMPLETED_DATE] = 0; } // Due Date @($due_date = DevblocksPlatform::importGPC($_REQUEST['due_date'], 'string', '')); @($fields[DAO_Task::DUE_DATE] = empty($due_date) ? 0 : intval(strtotime($due_date))); // Worker @($worker_id = DevblocksPlatform::importGPC($_REQUEST['worker_id'], 'integer', 0)); @($fields[DAO_Task::WORKER_ID] = intval($worker_id)); // Content @($content = DevblocksPlatform::importGPC($_REQUEST['content'], 'string', '')); @($fields[DAO_Task::CONTENT] = $content); // Link to object (optional) if (!empty($link_namespace) && !empty($link_object_id)) { @($fields[DAO_Task::SOURCE_EXTENSION] = $link_namespace); @($fields[DAO_Task::SOURCE_ID] = $link_object_id); } // Save if (!empty($id)) { DAO_Task::update($id, $fields); } else { $id = DAO_Task::create($fields); // Write a notification (if not assigned to ourselves) // $url_writer = DevblocksPlatform::getUrlService(); $source_extensions = DevblocksPlatform::getExtensions('cerberusweb.task.source', true); if (!empty($worker_id)) { // && $active_worker->id != $worker_id (Temporarily allow self notifications) if (null != @($source_renderer = $source_extensions[$link_namespace])) { /* @var $source_renderer Extension_TaskSource */ $source_info = $source_renderer->getSourceInfo($link_object_id); $source_name = $source_info['name']; $source_url = $source_info['url']; if (empty($source_name) || empty($source_url)) { break; } $fields = array(DAO_WorkerEvent::CREATED_DATE => time(), DAO_WorkerEvent::WORKER_ID => $worker_id, DAO_WorkerEvent::URL => $source_url, DAO_WorkerEvent::TITLE => 'New Task Assignment', DAO_WorkerEvent::CONTENT => sprintf("%s\n%s says: %s", $source_name, $active_worker->getName(), $title), DAO_WorkerEvent::IS_READ => 0); DAO_WorkerEvent::create($fields); } } } // Custom field saves @($field_ids = DevblocksPlatform::importGPC($_POST['field_ids'], 'array', array())); DAO_CustomFieldValue::handleFormPost(ChCustomFieldSource_Task::ID, $id, $field_ids); } if (!empty($view_id) && null != ($view = C4_AbstractViewLoader::getView('', $view_id))) { $view->render(); } exit; }
function showTabFieldsAction() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); // Alphabetize $source_manifests = DevblocksPlatform::getExtensions('feg.fields.source', false); uasort($source_manifests, create_function('$a, $b', "return strcasecmp(\$a->name,\$b->name);\n")); $tpl->assign('source_manifests', $source_manifests); $tpl->display('file:' . $this->_TPL_PATH . 'setup/tabs/fields/index.tpl'); }
function showWorkspaceTabAction() { $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $visit = PortSensorApplication::getVisit(); $db = DevblocksPlatform::getDatabaseService(); $active_worker = PortSensorApplication::getActiveWorker(); $current_workspace = DevblocksPlatform::importGPC($_REQUEST['workspace'], 'string', ''); $workspaces = DAO_Worklist::getWorkspaces($active_worker->id); // Fix a bad/old cache if (!empty($current_workspace) && false === array_search($current_workspace, $workspaces)) { $current_workspace = ''; } $views = array(); if (empty($current_workspace) && !empty($workspaces)) { // custom dashboards $current_workspace = reset($workspaces); } if (!empty($current_workspace)) { // Remember the tab $visit->set(PortSensorVisit::KEY_HOME_SELECTED_TAB, 'w_' . $current_workspace); $lists = DAO_Worklist::getWhere(sprintf("%s = %d AND %s = %s", DAO_Worklist::WORKER_ID, $active_worker->id, DAO_Worklist::WORKSPACE, $db->qstr($current_workspace))); // Load the workspace sources to map to view renderer $source_manifests = DevblocksPlatform::getExtensions(Extension_WorklistSource::EXTENSION_POINT, false); // Loop through list schemas if (is_array($lists) && !empty($lists)) { foreach ($lists as $list) { /* @var $list Model_Worklist */ $view_id = 'cust_' . $list->id; if (null == ($view = Ps_AbstractViewLoader::getView($view_id))) { $list_view = $list->view; // Make sure we can find the workspace source (plugin not disabled) if (!isset($source_manifests[$list->source_extension]) || null == ($workspace_source = $source_manifests[$list->source_extension]) || !isset($workspace_source->params['view_class'])) { continue; } // Make sure our workspace source has a valid renderer class $view_class = $workspace_source->params['view_class']; if (!class_exists($view_class)) { continue; } $view = new $view_class(); $view->id = $view_id; $view->name = $list_view->title; $view->renderLimit = $list_view->num_rows; $view->renderPage = 0; $view->view_columns = $list_view->columns; $view->params = $list_view->params; $view->renderSortBy = $list_view->sort_by; $view->renderSortAsc = $list_view->sort_asc; Ps_AbstractViewLoader::setView($view_id, $view); } if (!empty($view)) { $views[] = $view; } } } $tpl->assign('current_workspace', $current_workspace); $tpl->assign('views', $views); } // Log activity DAO_Worker::logActivity($active_worker->id, new Model_Activity('activity.mail.workspaces', array('<i>' . $current_workspace . '</i>'))); $tpl->display('file:' . $this->_TPL_PATH . 'home/workspaces/index.tpl'); }
/** * Processes the HTTP request. * * @param DevblocksHttpRequest $request * @param boolean $is_ajax */ static function processRequest(DevblocksHttpRequest $request, $is_ajax = false) { $path = $request->path; $controller_uri = array_shift($path); // [JAS]: Offer the platform a chance to intercept. switch ($controller_uri) { // [JAS]: Plugin-supplied URIs default: $routing = array(); $controllers = DevblocksPlatform::getExtensions('devblocks.controller', false); // Add any controllers which have definitive routing if (is_array($controllers)) { foreach ($controllers as $controller_mft) { if (isset($controller_mft->params['uri'])) { $routing[$controller_mft->params['uri']] = $controller_mft->id; } } } // [TODO] Ask the platform to look at any routing maps (extension manifest) or // controller objects // print_r($routing); // [TODO] Pages like 'tickets' currently work because APP_DEFAULT_CONTROLLER // is the ChPageController which looks up those URIs in manifests if (empty($controllers)) { die("No controllers are available!"); } // Set our controller based on the results $controller_mft = isset($routing[$controller_uri]) ? $controllers[$routing[$controller_uri]] : $controllers[APP_DEFAULT_CONTROLLER]; // Instance our manifest if (!empty($controller_mft)) { $controller = $controller_mft->createInstance(); } if ($controller instanceof DevblocksHttpRequestHandler) { $controller->handleRequest($request); // [JAS]: If we didn't write a new response, repeat the request if (null == ($response = DevblocksPlatform::getHttpResponse())) { $response = new DevblocksHttpResponse($request->path); DevblocksPlatform::setHttpResponse($response); } // [JAS]: An Ajax request doesn't need the full Http cycle if (!$is_ajax) { $controller->writeResponse($response); } } else { header("Status: 404"); die; // [TODO] Improve } break; } return; }
function handleRequest(DevblocksHttpRequest $request) { @($path = $request->path); if (empty($path) || !is_array($path)) { return; } $uri = array_shift($path); $rss_controllers = DevblocksPlatform::getExtensions('usermeet.sc.rss.controller'); foreach ($rss_controllers as $extension_id => $rss_controller) { if (0 == strcasecmp($rss_controller->params['uri'], $uri)) { $controller = DevblocksPlatform::getExtension($extension_id, true); $controller->handleRequest(new DevblocksHttpRequest($path)); return; } } // [TOOD] subcontroller not found }
function savePluginsAction() { $translate = DevblocksPlatform::getTranslationService(); $worker = CerberusApplication::getActiveWorker(); if (!$worker || !$worker->is_superuser) { echo $translate->_('common.access_denied'); return; } if (DEMO_MODE) { DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('config', 'plugins'))); return; } @($plugins_enabled = DevblocksPlatform::importGPC($_REQUEST['plugins_enabled'], 'array')); $pluginStack = DevblocksPlatform::getPluginRegistry(); if (is_array($plugins_enabled)) { foreach ($plugins_enabled as $plugin_id) { $plugin = $pluginStack[$plugin_id]; $plugin->setEnabled(true); unset($pluginStack[$plugin_id]); } } // [JAS]: Clear unchecked plugins foreach ($pluginStack as $plugin) { // [JAS]: We can't force disable core here [TODO] Improve if ($plugin->id == 'cerberusweb.core') { continue; } $plugin->setEnabled(false); } DevblocksPlatform::clearCache(); // Run any enabled plugin patches // [TODO] Should the platform do this automatically on enable in order? $patchMgr = DevblocksPlatform::getPatchService(); $patches = DevblocksPlatform::getExtensions("devblocks.patch.container", false, true); if (is_array($patches)) { foreach ($patches as $patch_manifest) { /* @var $patch_manifest DevblocksExtensionManifest */ $container = $patch_manifest->createInstance(); /* @var $container DevblocksPatchContainerExtension */ $patchMgr->registerPatchContainer($container); } } if (!$patchMgr->run()) { // fail die("Failed updating plugins."); // [TODO] Make this more graceful } // Reload plugin translations DAO_Translation::reloadPluginStrings(); DevblocksPlatform::redirect(new DevblocksHttpResponse(array('config', 'plugins'))); }
/** * @return Zend_Translate */ static function getTranslationService() { $cache = self::getCacheService(); $locale = DevblocksPlatform::getLocaleService(); if (false === ($translate = $cache->load(self::CACHE_TRANSLATIONS))) { $translate = new Zend_Translate('tmx', DEVBLOCKS_PATH . 'resources/strings.xml', $locale); // [JAS]: Read in translations from the extension point if (!self::isDatabaseEmpty()) { $translations = DevblocksPlatform::getExtensions("devblocks.i18n.strings"); if (is_array($translations)) { foreach ($translations as $translationManifest) { /* @var $translationManifest DevblocksExtensionManifest */ $translation = $translationManifest->createInstance(); /* @var $translation DevblocksTranslationsExtension */ $file = $translation->getTmxFile(); if (@is_readable($file)) { $translate->addTranslation($file, $locale); } } } $cache->save($translate, self::CACHE_TRANSLATIONS); } } return $translate; }
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; }
function viewDoCopyAction() { $translate = DevblocksPlatform::getTranslationService(); $active_worker = CerberusApplication::getActiveWorker(); $visit = CerberusApplication::getVisit(); @($view_id = DevblocksPlatform::importGPC($_POST['view_id'], 'string')); $view = C4_AbstractViewLoader::getView($view_id); @($list_title = DevblocksPlatform::importGPC($_POST['list_title'], 'string', '')); @($workspace = DevblocksPlatform::importGPC($_POST['workspace'], 'string', '')); @($new_workspace = DevblocksPlatform::importGPC($_POST['new_workspace'], 'string', '')); if (empty($workspace) && empty($new_workspace)) { $new_workspace = $translate->_('mail.workspaces.new'); } if (empty($list_title)) { $list_title = $translate->_('mail.workspaces.new_list'); } $workspace_name = !empty($new_workspace) ? $new_workspace : $workspace; // Find the proper workspace source based on the class of the view $source_manifests = DevblocksPlatform::getExtensions(Extension_WorkspaceSource::EXTENSION_POINT, false); $source_manifest = null; if (is_array($source_manifests)) { foreach ($source_manifests as $mft) { if (is_a($view, $mft->params['view_class'])) { $source_manifest = $mft; break; } } } if (!is_null($source_manifest)) { // View params inside the list for quick render overload $list_view = new Model_WorkerWorkspaceListView(); $list_view->title = $list_title; $list_view->num_rows = $view->renderLimit; $list_view->columns = $view->view_columns; $list_view->params = $view->params; $list_view->sort_by = $view->renderSortBy; $list_view->sort_asc = $view->renderSortAsc; // Save the new worklist $fields = array(DAO_WorkerWorkspaceList::WORKER_ID => $active_worker->id, DAO_WorkerWorkspaceList::WORKSPACE => $workspace_name, DAO_WorkerWorkspaceList::SOURCE_EXTENSION => $source_manifest->id, DAO_WorkerWorkspaceList::LIST_VIEW => serialize($list_view), DAO_WorkerWorkspaceList::LIST_POS => 99); $list_id = DAO_WorkerWorkspaceList::create($fields); } // Select the workspace tab $visit->set(CerberusVisit::KEY_HOME_SELECTED_TAB, 'w_' . $workspace_name); DevblocksPlatform::redirect(new DevblocksHttpResponse(array('home'))); }