private function _handleImportComment($xml) { $mask = (string) $xml->mask; $author_email = (string) $xml->author_email; $note = trim((string) $xml->note); $created = intval((string) $xml->created_date); $author_address = CerberusApplication::hashLookupAddress($author_email, true); // Bad file if (empty($note) || empty($author_address) || empty($mask)) { return false; } // echo "MASK: ",$mask,"<BR>"; // echo " -- Author: ",$author_address->email,"<BR>"; // echo " -- Note: ",$note,"<BR>"; if (null !== ($ticket = DAO_Ticket::getTicketByMask($mask))) { $fields = array(DAO_TicketComment::CREATED => $created, DAO_TicketComment::TICKET_ID => $ticket->id, DAO_TicketComment::COMMENT => $note, DAO_TicketComment::ADDRESS_ID => $author_address->id); if (null !== ($comment_id = DAO_TicketComment::create($fields))) { return true; } } return false; }
function handleRequest(DevblocksHttpRequest $request) { $worker = CerberusApplication::getActiveWorker(); if (empty($worker)) { return; } $stack = $request->path; array_shift($stack); // print @($object = strtolower(array_shift($stack))); // ticket|message|etc $tpl = DevblocksPlatform::getTemplateService(); $tpl->assign('path', $this->_TPL_PATH); $settings = DevblocksPlatform::getPluginSettingsService(); $tpl->assign('settings', $settings); $translate = DevblocksPlatform::getTranslationService(); $tpl->assign('translate', $translate); $teams = DAO_Group::getAll(); $tpl->assign('teams', $teams); $buckets = DAO_Bucket::getAll(); $tpl->assign('buckets', $buckets); $workers = DAO_Worker::getAll(); $tpl->assign('workers', $workers); // Security $active_worker = CerberusApplication::getActiveWorker(); $active_worker_memberships = $active_worker->getMemberships(); // [TODO] Make this pluggable // Subcontroller switch ($object) { case 'ticket': @($id = array_shift($stack)); @($ticket = is_numeric($id) ? DAO_Ticket::getTicket($id) : DAO_Ticket::getTicketByMask($id)); $convo_timeline = array(); $messages = $ticket->getMessages(); 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); } @($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($ticket->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); } } ksort($convo_timeline); $tpl->assign('convo_timeline', $convo_timeline); // Comment parent addresses $comment_addresses = array(); foreach ($comments as $comment) { /* @var $comment Model_TicketComment */ $address_id = intval($comment->address_id); if (!isset($comment_addresses[$address_id])) { $address = DAO_Address::get($address_id); $comment_addresses[$address_id] = $address; } } $tpl->assign('comment_addresses', $comment_addresses); // Message Notes $notes = DAO_MessageNote::getByTicketId($ticket->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); // Make sure we're allowed to view this ticket or message if (!isset($active_worker_memberships[$ticket->team_id])) { echo "<H1>" . $translate->_('common.access_denied') . "</H1>"; return; } $tpl->assign('ticket', $ticket); $tpl->display('file:' . $this->_TPL_PATH . 'print/ticket.tpl'); break; case 'message': @($id = array_shift($stack)); @($message = DAO_Ticket::getMessage($id)); @($ticket = DAO_Ticket::getTicket($message->ticket_id)); // Make sure we're allowed to view this ticket or message if (!isset($active_worker_memberships[$ticket->team_id])) { echo "<H1>" . $translate->_('common.access_denied') . "</H1>"; return; } // Message Notes $notes = DAO_MessageNote::getByTicketId($ticket->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); $tpl->assign('message', $message); $tpl->assign('ticket', $ticket); $tpl->display('file:' . $this->_TPL_PATH . 'print/message.tpl'); break; } }
/** * First we check the references and in-reply-to headers to find a * historical match in the database. If those don't match we check * the subject line for a mask (if one exists). If none of those * options match we return null. * * @param array $headers * @return array */ private static function findParentMessage($headers) { @($aSubject = $headers['subject']); @($sMessageId = trim($headers['message-id'])); @($sInReplyTo = trim($headers['in-reply-to'])); @($sReferences = trim($headers['references'])); @($sThreadTopic = trim($headers['thread-topic'])); // [TODO] Could turn string comparisons into hashes here for simple equality checks $aReferences = array(); // Add all References if (!empty($sReferences)) { if (preg_match("/(\\<.*?\\@.*?\\>)/", $sReferences, $matches)) { unset($matches[0]); // who cares about the pattern foreach ($matches as $ref) { $ref = trim($ref); if (!empty($ref) && 0 != strcasecmp($ref, $sMessageId)) { $aReferences[$ref] = 1; } } } } unset($matches); // Append first <*> from In-Reply-To if (!empty($sInReplyTo)) { if (preg_match("/(\\<.*?\\@.*?\\>)/", $sInReplyTo, $matches)) { if (isset($matches[1])) { // only use the first In-Reply-To $ref = trim($matches[1]); if (!empty($ref) && 0 != strcasecmp($ref, $sMessageId)) { $aReferences[$ref] = 1; } } } } // Try matching our references or in-reply-to if (is_array($aReferences) && !empty($aReferences)) { foreach (array_keys($aReferences) as $ref) { if (empty($ref)) { continue; } if (null != ($ids = DAO_Ticket::getTicketByMessageId($ref))) { return $ids; } } } // Try matching the subject line // [TODO] This should only happen if the destination has subject masks enabled if (!is_array($aSubject)) { $aSubject = array($aSubject); } foreach ($aSubject as $sSubject) { if (preg_match("/.*\\[.*?\\#(.*?)\\].*/", $sSubject, $matches)) { if (isset($matches[1])) { $mask = $matches[1]; if (null != ($ticket = DAO_Ticket::getTicketByMask($mask))) { return array('ticket_id' => intval($ticket->id), 'message_id' => intval($ticket->first_message_id)); } } } } return NULL; }
protected function getWorkerAction($path) { $worker = parent::getActiveWorker(); /* @var $worker CerberusWorker */ $memberships = $worker->getMemberships(); // Single GET if (1 == count($path) && is_numeric($path[0])) { if (($ticket = DAO_Ticket::getTicket($path[0])) != null && isset($memberships[$ticket->team_id])) { $this->_getIdAction($path); } } // Actions $value = array_shift($path); switch ($value) { case 'list': $this->_getListAction($path, array(SearchFields_Ticket::TEAM_ID => new DevblocksSearchCriteria(SearchFields_Ticket::TEAM_ID, 'in', array_keys($memberships)))); break; default: if (($ticket = DAO_Ticket::getTicketByMask($value)) != null && isset($memberships[$ticket->team_id])) { $this->_getIdAction(array($ticket->id)); } break; } }