Ejemplo n.º 1
0
 /**
  * Close tickets in a pending state for a specific amount of time
  *
  * @param   object   $job  \Components\Cron\Models\Job
  * @return  boolean
  */
 public function onClosePending(\Components\Cron\Models\Job $job)
 {
     $params = $job->get('params');
     $database = App::get('db');
     $sconfig = Component::params('com_support');
     $slc = "SELECT id, login, email, name FROM `#__support_tickets` AS t";
     $upd = "UPDATE `#__support_tickets` AS t SET t.`open`=0, t.`status`=0, t.`closed`=" . $database->quote(Date::toSql());
     $where = array();
     $where[] = "t.`type`=0";
     $where[] = "t.`open`=1";
     if (is_object($params)) {
         $statuses = array();
         if (is_numeric($params->get('support_ticketpending_status1'))) {
             $statuses[] = $params->get('support_ticketpending_status1');
         }
         if (is_numeric($params->get('support_ticketpending_status2'))) {
             $statuses[] = $params->get('support_ticketpending_status2');
         }
         if (is_numeric($params->get('support_ticketpending_status3'))) {
             $statuses[] = $params->get('support_ticketpending_status3');
         }
         if (count($statuses)) {
             $where[] = "t.`status` IN (" . implode(',', $statuses) . ")";
         }
         if ($group = $params->get('support_ticketpending_group')) {
             $where[] = "t.`group`=" . $database->quote($group);
         }
         if ($owners = $params->get('support_ticketpending_owners')) {
             $usernames = explode(',', $owners);
             $usernames = array_map('trim', $usernames);
             foreach ($usernames as $k => $username) {
                 $user = User::getInstance($username);
                 $usernames[$k] = $database->quote($user->get('id'));
             }
             $where[] = "t.`owner` IN (" . implode(", ", $usernames) . ")";
         }
         if ($severity = $params->get('support_ticketpending_severity')) {
             if ($severity != 'all') {
                 $severities = explode(',', $severity);
                 $severities = array_map('trim', $severities);
                 foreach ($severities as $k => $severity) {
                     $severities[$k] = $database->quote($severity);
                 }
                 $where[] = "t.`severity` IN (" . implode(", ", $severities) . ")";
             }
         }
         if ($owned = intval($params->get('support_ticketpending_owned', 0))) {
             if ($owned == 1) {
                 $where[] = "(t.`owner` IS NULL OR `owner`='')";
             } else {
                 if ($owned == 2) {
                     $where[] = "(t.`owner` IS NOT NULL AND `owner` !='')";
                 }
             }
         }
         if ($submitters = $params->get('support_ticketpending_submitters')) {
             $usernames = explode(',', $submitters);
             $usernames = array_map('trim', $usernames);
             foreach ($usernames as $k => $username) {
                 $usernames[$k] = $database->quote($username);
             }
             $where[] = "t.`login` IN (" . implode(", ", $usernames) . ")";
         }
         if ($tags = $params->get('support_ticketpending_excludeTags', '')) {
             $tags = explode(',', $tags);
             $tags = array_map('trim', $tags);
             foreach ($tags as $k => $tag) {
                 $tags[$k] = $database->quote($tag);
             }
             $where[] = "t.`id` NOT IN (\n\t\t\t\t\t\t\tSELECT jto.`objectid` FROM `#__tags_object` AS jto\n\t\t\t\t\t\t\tJOIN `#__tags` AS jt ON jto.`tagid`=jt.`id`\n\t\t\t\t\t\t\tWHERE jto.`tbl`='support'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tjt.`tag` IN (" . implode(", ", $tags) . ") OR jt.`raw_tag` IN (" . implode(", ", $tags) . ")\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)";
         }
         if ($tags = $params->get('support_ticketpending_includeTags', '')) {
             $tags = explode(',', $tags);
             $tags = array_map('trim', $tags);
             foreach ($tags as $k => $tag) {
                 $tags[$k] = $database->quote($tag);
             }
             $where[] = "t.`id` IN (\n\t\t\t\t\t\t\tSELECT jto.`objectid` FROM `#__tags_object` AS jto\n\t\t\t\t\t\t\tJOIN `#__tags` AS jt ON jto.`tagid`=jt.`id`\n\t\t\t\t\t\t\tWHERE jto.`tbl`='support'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tjt.`tag` IN (" . implode(", ", $tags) . ") OR jt.`raw_tag` IN (" . implode(", ", $tags) . ")\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)";
         }
         if ($created = $params->get('support_ticketpending_activity', '-2week')) {
             $op = '';
             switch ($created) {
                 // Created before (older than)
                 case '-day':
                     $op = '<=';
                     $timestamp = Date::modify('-1 day');
                     break;
                 case '-week':
                     $op = '<=';
                     $timestamp = Date::modify('-1 week');
                     break;
                 case '-2week':
                     $op = '<=';
                     $timestamp = Date::modify('-2 week');
                     break;
                 case '-3week':
                     $op = '<=';
                     $timestamp = Date::modify('-3 week');
                     break;
                 case '-month':
                     $op = '<=';
                     $timestamp = Date::modify('-1 month');
                     break;
                 case '-6month':
                     $op = '<=';
                     $timestamp = Date::modify('-6 month');
                     break;
                 case '-year':
                     $op = '<=';
                     $timestamp = Date::modify('-1 year');
                     break;
                 case '--':
                     $op = '';
                     break;
             }
             if ($op) {
                 $where[] = "(SELECT MAX(c.`created`) FROM `#__support_comments` AS c WHERE c.`ticket`=t.`id`) " . $op . $database->quote($timestamp->toSql());
             }
         }
     } else {
         $timestamp = Date::modify('-2 week');
         $where[] = "t.`created` <= " . $database->quote($timestamp->toSql());
     }
     if (count($where) > 0) {
         $slc .= " WHERE " . implode(" AND ", $where);
         $upd .= " WHERE " . implode(" AND ", $where);
     }
     $message_id = $params->get('support_ticketpending_message');
     // Get a list of tickets before we update them
     $tickets = array();
     if ($message_id) {
         $database->setQuery($slc);
         $tickets = $database->loadObjectList();
     }
     // Update the tickets
     $database->setQuery($upd);
     if (!$database->query()) {
         Log::error('CRON query failed: ' . $database->getErrorMsg());
     } else {
         if ($message_id && !empty($tickets)) {
             Lang::load('com_support') || Lang::load('com_support', PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'site');
             include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'tables' . DS . 'message.php';
             include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'models' . DS . 'ticket.php';
             $message = new \Components\Support\Tables\Message($database);
             $message->load($message_id);
             // Make sure we have a message to send
             if ($message->message) {
                 $from = array('name' => Config::get('sitename') . ' ' . Lang::txt('COM_SUPPORT'), 'email' => Config::get('mailfrom'), 'multipart' => md5(date('U')));
                 // Set mail additional args (mail return path - used for bounces)
                 if ($host = Request::getVar('HTTP_HOST', '', 'server')) {
                     $args = '-f hubmail-bounces@' . $host;
                 }
                 $subject = Lang::txt('COM_SUPPORT') . ': ' . Lang::txt('COM_SUPPORT_TICKETS');
                 $mailed = array();
                 $message->message = str_replace('{sitename}', Config::get('sitename'), $message->message);
                 $message->message = str_replace('{siteemail}', Config::get('mailfrom'), $message->message);
                 $comment = new \Components\Support\Models\Comment();
                 $comment->set('created', Date::toSql());
                 $comment->set('created_by', 0);
                 $comment->set('access', 0);
                 $comment->set('comment', $message->message);
                 foreach ($tickets as $submitter) {
                     $name = null;
                     $email = null;
                     if ($submitter->login) {
                         // Get the user's account
                         $user = User::getInstance($submitter->login);
                         if (is_object($user) && $user->get('id')) {
                             $name = $user->get('name');
                             $email = $user->get('email');
                         }
                     }
                     $email = $email ?: $submitter->email;
                     $name = $name ?: $submitter->name;
                     $name = $name ?: $email;
                     if (!$email) {
                         continue;
                     }
                     // Try to ensure no duplicates
                     if (in_array($email, $mailed)) {
                         continue;
                     }
                     $old = new \Components\Support\Models\Ticket($submitter->id);
                     $old->set('open', 1);
                     $row = clone $old;
                     $row->set('open', 0);
                     $comment->set('comment', str_replace('#XXX', '#' . $row->get('id'), $comment->get('comment')));
                     $comment->set('comment', str_replace('{ticket#}', $row->get('id'), $comment->get('comment')));
                     // Compare fields to find out what has changed for this ticket and build a changelog
                     $comment->changelog()->diff($old, $row);
                     $comment->set('ticket', $row->get('id'));
                     $eview = new \Hubzero\Mail\View(array('base_path' => PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'site', 'name' => 'emails', 'layout' => 'comment_plain'));
                     $eview->option = 'com_support';
                     $eview->controller = 'tickets';
                     $eview->delimiter = '~!~!~!~!~!~!~!~!~!~!';
                     $eview->boundary = $from['multipart'];
                     $eview->comment = $comment;
                     $eview->config = $sconfig;
                     $eview->ticket = $row;
                     $plain = $eview->loadTemplate(false);
                     $plain = str_replace("\n", "\r\n", $plain);
                     // HTML
                     $eview->setLayout('comment_html');
                     $html = $eview->loadTemplate();
                     $html = str_replace("\n", "\r\n", $html);
                     // Build message
                     $message = new \Hubzero\Mail\Message();
                     $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($email, $name)->addHeader('X-Component', 'com_support')->addHeader('X-Component-Object', 'support_ticket_comment');
                     $message->addPart($plain, 'text/plain');
                     $message->addPart($html, 'text/html');
                     // Send mail
                     if (!$message->send()) {
                         echo 'CRON email failed: ' . Lang::txt('Failed to mail %s', $email);
                         //$this->setError(Lang::txt('Failed to mail %s', $fullEmailAddress));
                         Log::error('CRON email failed: ' . Lang::txt('Failed to mail %s', $email));
                     }
                     $mailed[] = $email;
                 }
             }
         }
     }
     return true;
 }
Ejemplo n.º 2
0
 /**
  * Create a new comment
  *
  * @apiMethod POST
  * @apiUri    /support/{ticket}/comments
  * @apiParameter {
  * 		"name":        "scope",
  * 		"description": "Scope type (group, member, etc.)",
  * 		"type":        "string",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @apiParameter {
  * 		"name":        "scope_id",
  * 		"description": "Scope object ID",
  * 		"type":        "integer",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @apiParameter {
  * 		"name":        "title",
  * 		"description": "Entry title",
  * 		"type":        "string",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @apiParameter {
  * 		"name":        "alias",
  * 		"description": "Entry alias",
  * 		"type":        "string",
  * 		"required":    false,
  * 		"default":     null
  * }
  * @return     void
  */
 public function createTask()
 {
     $this->requiresAuthentication();
     if (!$this->acl->check('create', 'comments')) {
         throw new Exception(Lang::txt('Not authorized'), 403);
     }
     $ticket_id = Request::getInt('ticket', 0, 'post');
     // Load the old ticket so we can compare for the changelog
     $old = new \Components\Support\Models\Ticket($ticket_id);
     $old->set('tags', $old->tags('string'));
     if (!$old->exists()) {
         $this->errorMessage(500, Lang::txt('Ticket "%s" does not exist.', $ticket_id));
         return;
     }
     // Initiate class and bind posted items to database fields
     $ticket = new \Components\Support\Models\Ticket($ticket_id);
     $ticket->set('status', Request::getInt('status', $ticket->get('status'), 'post'));
     $ticket->set('open', Request::getInt('open', $ticket->get('open'), 'post'));
     $ticket->set('category', Request::getInt('category', $ticket->get('category'), 'post'));
     $ticket->set('severity', Request::getVar('severity', $ticket->get('severity'), 'post'));
     $ticket->set('owner', Request::getVar('owner', $ticket->get('owner'), 'post'));
     $ticket->set('group', Request::getVar('group', $ticket->get('group'), 'post'));
     // If an existing ticket AND closed AND previously open
     if ($ticket_id && !$ticket->get('open') && $ticket->get('open') != $old->get('open')) {
         // Record the closing time
         $ticket->set('closed', Date::toSql());
     }
     // Any tags?
     if ($tags = trim(Request::getVar('tags', '', 'post'))) {
         $ticket->tag($tags, $user->get('uidNumber'));
         $ticket->set('tags', $ticket->tags('string'));
     }
     // Store new content
     if (!$ticket->store()) {
         $this->errorMessage(500, $ticket->getError());
         return;
     }
     // Create a new comment
     $comment = new \Components\Support\Models\Comment();
     $comment->set('ticket', $ticket->get('id'));
     $comment->set('comment', nl2br(Request::getVar('comment', '', 'post', 'none', 2)));
     if ($comment->get('comment')) {
         // If a comment was posted by the ticket submitter to a "waiting user response" ticket, change status.
         if ($ticket->isWaiting() && $user->get('username') == $ticket->get('login')) {
             $ticket->open();
         }
     }
     $comment->set('created', Date::toSql());
     $comment->set('created_by', $user->get('uidNumber'));
     $comment->set('access', Request::getInt('access', 0, 'post'));
     // Compare fields to find out what has changed for this ticket and build a changelog
     $comment->changelog()->diff($old, $ticket);
     $comment->changelog()->cced(Request::getVar('cc', '', 'post'));
     // Store new content
     if (!$comment->store()) {
         $this->errorMessage(500, $comment->getError());
         return;
     }
     if ($ticket->get('owner')) {
         $comment->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_OWNER'), 'name' => $ticket->owner('name'), 'email' => $ticket->owner('email'), 'id' => $ticket->owner('id')));
     }
     // Add any CCs to the e-mail list
     foreach ($comment->changelog()->get('cc') as $cc) {
         $comment->addTo($cc, Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_CC'));
     }
     // Check if the notify list has eny entries
     if (count($comment->to())) {
         include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'helpers' . DS . 'utilities.php';
         $allowEmailResponses = $ticket->config('email_processing');
         if ($allowEmailResponses) {
             try {
                 $encryptor = new \Hubzero\Mail\Token();
             } catch (Exception $e) {
                 $allowEmailResponses = false;
             }
         }
         $subject = Lang::txt('COM_SUPPORT_EMAIL_SUBJECT_TICKET_COMMENT', $ticket->get('id'));
         $from = array('name' => Lang::txt('COM_SUPPORT_EMAIL_FROM', Config::get('sitename')), 'email' => Config::get('mailfrom'), 'multipart' => md5(date('U')));
         $message = array();
         // Plain text email
         $eview = new \Hubzero\Mail\View(array('base_path' => PATH_CORE . '/components/com_support/site', 'name' => 'emails', 'layout' => 'comment_plain'));
         $eview->option = 'com_support';
         $eview->controller = 'tickets';
         $eview->comment = $comment;
         $eview->ticket = $ticket;
         $eview->delimiter = $allowEmailResponses ? '~!~!~!~!~!~!~!~!~!~!' : '';
         $message['plaintext'] = $eview->loadTemplate(false);
         $message['plaintext'] = str_replace("\n", "\r\n", $message['plaintext']);
         // HTML email
         $eview->setLayout('comment_html');
         $message['multipart'] = $eview->loadTemplate();
         // Send e-mail to admin?
         foreach ($comment->to('ids') as $to) {
             if ($allowEmailResponses) {
                 // The reply-to address contains the token
                 $token = $encryptor->buildEmailToken(1, 1, $to['id'], $ticket->get('id'));
                 $from['replytoemail'] = 'htc-' . $token . strstr(Config::get('mailfrom'), '@');
             }
             // Get the user's email address
             if (!Event::trigger('xmessage.onSendMessage', array('support_reply_submitted', $subject, $message, $from, array($to['id']), 'com_support'))) {
                 $this->setError(Lang::txt('COM_SUPPORT_ERROR_FAILED_TO_MESSAGE', $to['name'] . '(' . $to['role'] . ')'));
             }
             $comment->changelog()->notified($to['role'], $to['name'], $to['email']);
         }
         foreach ($comment->to('emails') as $to) {
             if ($allowEmailResponses) {
                 $token = $encryptor->buildEmailToken(1, 1, -9999, $ticket->get('id'));
                 $email = array($to['email'], 'htc-' . $token . strstr(Config::get('mailfrom'), '@'));
                 // In this case each item in email in an array, 1- To, 2:reply to address
                 \Components\Support\Helpers\Utilities::sendEmail($email[0], $subject, $message, $from, $email[1]);
             } else {
                 // email is just a plain 'ol string
                 \Components\Support\Helpers\Utilities::sendEmail($to['email'], $subject, $message, $from);
             }
             $comment->changelog()->notified($to['role'], $to['name'], $to['email']);
         }
     }
     // Were there any changes?
     if (count($comment->changelog()->get('notifications')) > 0 || count($comment->changelog()->get('cc')) > 0 || count($comment->changelog()->get('changes')) > 0) {
         // Save the data
         if (!$comment->store()) {
             $this->errorMessage(500, $comment->getError());
             return;
         }
     }
     $msg = new stdClass();
     $msg->ticket = $ticket->get('id');
     $msg->comment = $comment->get('id');
     $msg->notified = $comment->changelog()->get('notifications');
     $this->setMessageType(Request::getVar('format', 'json'));
     $this->send($msg, 200, 'OK');
 }