/** * Retrieves a row from the database * * @param string $refid ID of the database table row * @param string $category Element type (determines table to look in) * @param string $parent If the element has a parent element * @return array */ public function transferItem($from_type, $from_id, $to_type, $rid = 0, $deactivate = 1) { $upconfig = Component::params('com_members'); $this->banking = $upconfig->get('bankAccounts'); $database = App::get('db'); if ($from_type == NULL or $from_id == NULL or $to_type == NULL) { $this->setError(Lang::txt('PLG_SUPPORT_TRANSFER_ERROR_MISSING_INFO')); return false; } if ($from_type == $to_type) { $this->setError(Lang::txt('PLG_SUPPORT_TRANSFER_ERROR_CATEGORIES_MUST_BE_DIFFERENT')); return false; } // collectors $author = ''; $subject = ''; $body = ''; $tags = ''; $owner = ''; // name of group owning the item $anonymous = 0; // get needed scripts include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'models' . DS . 'ticket.php'; include_once PATH_CORE . DS . 'components' . DS . 'com_answers' . DS . 'models' . DS . 'question.php'; include_once PATH_CORE . DS . 'components' . DS . 'com_wishlist' . DS . 'models' . DS . 'wishlist.php'; $wconfig = Component::params('com_wishlist'); $admingroup = $wconfig->get('group') ? $wconfig->get('group') : 'hubadmin'; // Get needed scripts & initial data switch ($from_type) { // Transfer from a Support Ticket case 'ticket': $row = new \Components\Support\Models\Ticket($from_id); if ($row->exists()) { $author = $row->get('login'); $subject = $row->content('raw', 200); // max 200 characters $body = $row->get('summary'); $owner = $row->get('group'); // If we are de-activating original item if ($deactivate) { $row->set('status', 2); $row->set('resolved', 'transfered'); } $tags = $row->tags('string'); } else { $this->setError(Lang::txt('PLG_SUPPORT_TRANSFER_ERROR_ITEM_NOT_FOUND')); return false; } break; // Transfer from a Question // Transfer from a Question case 'question': $row = new \Components\Answers\Models\Question($from_id); if ($row->exists()) { $author = $row->get('created_by'); $subject = $row->subject('raw', 200); // max 200 characters $body = $row->get('question'); $anonymous = $row->get('anonymous'); // If we are de-activating original item if ($deactivate) { $row->set('state', 2); $row->set('reward', 0); } $tags = $row->tags('string'); } else { $this->setError(Lang::txt('PLG_SUPPORT_TRANSFER_ERROR_ITEM_NOT_FOUND')); return false; } break; // Transfer from a Wish // Transfer from a Wish case 'wish': $row = new \Components\Wishlist\Tables\Wish($database); $row->load($from_id); if ($row->id) { $author = $row->proposed_by; $subject = \Hubzero\Utility\String::truncate($row->subject, 200); // max 200 characters $body = $row->about; $anonymous = $row->anonymous; // If we are de-activating original item if ($deactivate) { $row->status = 2; $row->ranking = 0; // also delete all previous votes for this wish $objR = new \Components\Wishlist\Tables\Rank($database); $objR->remove_vote($from_id); } // get owner $objG = new \Components\Wishlist\Tables\OwnerGroup($database); $nativegroups = $objG->get_owner_groups($row->wishlist, $admingroup, '', 1); $owner = count($nativegroups) > 0 && $nativegroups[0] != $admingroup ? $nativegroups[0] : ''; // tool group $objWishlist = new \Components\Wishlist\Tables\Wishlist($database); $wishlist = $objWishlist->get_wishlist($row->wishlist); if (isset($wishlist->resource) && isset($wishlist->resource->alias)) { $tags = $wishlist->resource->type == 7 ? 'tool:' : 'resource:'; $tags .= $wishlist->resource->alias ? $wishlist->resource->alias : $wishlist->referenceid; } } else { $this->setError(Lang::txt('PLG_SUPPORT_TRANSFER_ERROR_ITEM_NOT_FOUND')); return false; } break; } // if no author can be found, use current administrator $author = User::getInstance($author); if (!is_object($author)) { $author = User::getInstance(User::get('id')); } $today = Date::toSql(); // Where do we transfer? switch ($to_type) { // Transfer to a Support Ticket case 'ticket': $newrow = new \Components\Support\Models\Ticket(); $newrow->set('open', 1); $newrow->set('status', 0); $newrow->set('created', $today); $newrow->set('login', $author->get('username')); $newrow->set('severity', 'normal'); $newrow->set('summary', $subject); $newrow->set('report', $body ? $body : $subject); $newrow->set('section', 1); $newrow->set('type', 0); $newrow->set('instances', 1); $newrow->set('email', $author->get('email')); $newrow->set('name', $author->get('name')); // do we have an owner group? $newrow->set('group', $owner ? $owner : ''); break; case 'question': $newrow = new \Components\Answers\Models\Question(); $newrow->set('subject', $subject); $newrow->set('question', $body); $newrow->set('created', $today); $newrow->set('created_by', $author->get('id')); $newrow->set('state', 0); $newrow->set('anonymous', $anonymous); break; case 'wish': $newrow = new \Components\Wishlist\Models\Wish(); $newrow->set('subject', $subject); $newrow->set('about', $body); $newrow->set('proposed', $today); $newrow->set('proposed_by', $author->get('id')); $newrow->set('status', 0); $newrow->set('anonymous', $anonymous); // which wishlist? $objWishlist = new \Components\Wishlist\Tables\Wishlist($database); $mainlist = $objWishlist->get_wishlistID(1, 'general'); $listid = 0; if (!$rid && $owner) { $rid = $this->getResourceIdFromGroup($owner); } if ($rid) { $listid = $objWishlist->get_wishlistID($rid); } $newrow->set('wishlist', $listid ? $listid : $mainlist); break; } // Save new information if (!$newrow->store()) { $this->setError($newrow->getError()); return; } else { // Checkin ticket //$newrow->checkin(); // Extras if ($newrow->exists()) { switch ($to_type) { case 'ticket': // Tag new ticket if ($tags) { $newrow->tag($tags, User::get('id'), 0); } break; case 'question': // Tag new question if ($tags) { $newrow->tag($tags, User::get('id'), 0); } break; } } } // If we are de-activating original item if ($deactivate) { // overwrite old entry if (!$row->store()) { $this->setError($row->getError()); exit; } // Clean up rewards if banking if ($this->banking) { switch ($from_type) { case 'ticket': // no banking yet break; case 'question': $reward = \Hubzero\Bank\Transaction::getAmount('answers', 'hold', $from_id, $author->get('id')); // Remove hold if ($reward) { \Hubzero\Bank\Transaction::deleteRecords('answers', 'hold', $from_id); // Make credit adjustment $BTL_Q = new \Hubzero\Bank\Teller($author->get('id')); $credit = $BTL_Q->credit_summary(); $adjusted = $credit - $reward; $BTL_Q->credit_adjustment($adjusted); } break; case 'wish': include_once PATH_CORE . DS . 'components' . DS . 'com_wishlist' . DS . 'helpers' . DS . 'economy.php'; $WE = new \Components\Wishlist\Helpers\Economy($database); $WE->cleanupBonus($from_id); break; } } } return $newrow->get('id'); }
/** * Create a new ticket * * @apiMethod POST * @apiUri /support * @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() { //get the userid and attempt to load user profile $userid = User::get('id'); $result = User::getInstance($userid); //make sure we have a user if (!$result || !$result->get('id')) { throw new Exception(Lang::txt('User not found.'), 500); } // Initiate class and bind data to database fields $ticket = new \Components\Support\Models\Ticket(); // Set the created date $ticket->set('created', Date::toSql()); // Incoming $ticket->set('report', Request::getVar('report', '', 'post', 'none', 2)); if (!$ticket->get('report')) { throw new Exception(Lang::txt('Error: Report contains no text.'), 500); } $ticket->set('os', Request::getVar('os', 'unknown', 'post')); $ticket->set('browser', Request::getVar('browser', 'unknown', 'post')); $ticket->set('severity', Request::getVar('severity', 'normal', 'post')); // Cut suggestion at 70 characters $summary = substr($ticket->get('report'), 0, 70); if (strlen($summary) >= 70) { $summary .= '...'; } $ticket->set('summary', $summary); // Get user data $ticket->set('name', $result->get('name')); $ticket->set('email', $result->get('email')); $ticket->set('login', $result->get('username')); // Set some helpful info $ticket->set('instances', 1); $ticket->set('section', 1); $ticket->set('open', 1); $ticket->set('status', 0); $ticket->set('ip', Request::ip()); $ticket->set('hostname', gethostbyaddr(Request::getVar('REMOTE_ADDR', '', 'server'))); // Save the data if (!$ticket->store()) { throw new Exception($ticket->getErrors(), 500); } // Any tags? if ($tags = trim(Request::getVar('tags', '', 'post'))) { $ticket->tag($tags, $result->get('id')); } // Set the response $msg = new stdClass(); $msg->submitted = $ticket->get('created'); $msg->ticket = $ticket->get('id'); $this->send($msg); }
/** * Creates a support ticket for a tool * * @param integer $toolid Tool ID * @param array $tool Array of tool info * @return mixed False if errors, integer on success */ private function _createTicket($toolid, $tool) { $row = new \Components\Support\Models\Ticket(); $row->set('open', 1); $row->set('status', 0); $row->set('created', Date::toSql()); $row->set('login', User::get('username')); $row->set('severity', 'normal'); $row->set('summary', Lang::txt('COM_TOOLS_NEW_TOOL_SUBMISSION') . ': ' . $tool['toolname']); $row->set('report', $tool['toolname']); $row->set('section', 2); $row->set('type', 3); // Attach tool group to a ticket for access $row->set('group', $this->config->get('group_prefix', 'app-') . $tool['toolname']); $row->set('email', User::get('email')); $row->set('name', User::get('name')); if (!$row->store()) { $this->setError($row->getError()); return false; } else { if ($row->exists()) { // save tag $row->tag('tool:' . $tool['toolname'], User::get('id')); // store ticket id $obj = new \Components\Tools\Tables\Tool($this->database); $obj->saveTicketId($toolid, $row->get('id')); // make a record $this->_updateTicket($toolid, '', '', Lang::txt('COM_TOOLS_NOTICE_TOOL_REGISTERED'), 0, 1, 4, $tool); } } return $row->get('id'); }
/** * 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; }
/** * 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'); }