Beispiel #1
0
 /**
  * Saves posted data for a new/edited forum thread post
  *
  * @return     void
  */
 public function savethread()
 {
     if (User::isGuest()) {
         App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($this->base))));
         return;
     }
     // Incoming
     $section = Request::getVar('section', '');
     $fields = Request::getVar('fields', array(), 'post', 'none', 2);
     $fields = array_map('trim', $fields);
     $this->_authorize('thread', intval($fields['id']));
     $asset = 'thread';
     if ($fields['parent']) {
         //$asset = 'post';
     }
     if ($fields['id']) {
         $old = new \Components\Forum\Tables\Post($this->database);
         $old->load(intval($fields['id']));
         if ($old->created_by == User::get('id')) {
             $this->params->set('access-edit-thread', true);
         }
     }
     if ($fields['id'] && !$this->params->get('access-edit-thread') || !$fields['id'] && !$this->params->get('access-create-thread')) {
         App::redirect(Route::url('index.php?option=' . $this->option . '&cn=' . $this->group->get('cn') . '&active=forum'), Lang::txt('PLG_GROUPS_FORUM_NOT_AUTHORIZED'), 'warning');
         return;
     }
     $fields['sticky'] = isset($fields['sticky']) ? $fields['sticky'] : 0;
     $fields['closed'] = isset($fields['closed']) ? $fields['closed'] : 0;
     // Bind data
     $model = new \Components\Forum\Tables\Post($this->database);
     if (!$model->bind($fields)) {
         $this->addPluginMessage($model->getError(), 'error');
         return $this->editthread($model);
     }
     if (!$model->anonymous) {
         $model->anonymous = 0;
     }
     // Check content
     if (!$model->check()) {
         $this->addPluginMessage($model->getError(), 'error');
         return $this->editthread($model);
     }
     // Store new content
     if (!$model->store()) {
         $this->addPluginMessage($model->getError(), 'error');
         return $this->editthread($model);
     }
     $parent = $model->parent ? $model->parent : $model->id;
     //update
     $this->upload($parent, $model->id);
     if ($fields['id']) {
         if ($old->category_id != $fields['category_id']) {
             $model->updateReplies(array('category_id' => $fields['category_id']), $model->id);
         }
     }
     $category = new \Components\Forum\Tables\Category($this->database);
     $category->load(intval($model->category_id));
     $sectionTbl = new \Components\Forum\Tables\Section($this->database);
     $sectionTbl->load(intval($category->section_id));
     $tags = Request::getVar('tags', '', 'post');
     $tagger = new \Components\Forum\Models\Tags($model->id);
     $tagger->setTags($tags, User::get('id'));
     // Determine post save message
     // Also, get subject of post for outgoing email, either the title of parent post (for replies), or title of current post (for new threads)
     if (!$fields['parent']) {
         $message = Lang::txt('PLG_GROUPS_FORUM_THREAD_STARTED');
         $posttitle = $model->title;
     } else {
         $message = Lang::txt('PLG_GROUPS_FORUM_POST_ADDED');
         $parentForumTablePost = new \Components\Forum\Tables\Post($this->database);
         $parentForumTablePost->load(intval($fields['parent']));
         $posttitle = $parentForumTablePost->title;
     }
     if ($fields['id']) {
         $message = $model->modified_by ? Lang::txt('PLG_GROUPS_FORUM_POST_EDITED') : Lang::txt('PLG_GROUPS_FORUM_POST_ADDED');
     }
     // Determine route
     if ($model->parent) {
         $thread = $model->thread;
     } else {
         $thread = $model->id;
     }
     $params = Component::params('com_groups');
     // Email the group and insert email tokens to allow them to respond to group posts via email
     if ($params->get('email_comment_processing')) {
         $esection = new \Components\Forum\Models\Section($sectionTbl);
         $ecategory = new \Components\Forum\Models\Category($category);
         $ecategory->set('section_alias', $esection->get('alias'));
         $ethread = new \Components\Forum\Models\Thread(intval($thread));
         $ethread->set('section', $esection->get('alias'));
         $ethread->set('category', $ecategory->get('alias'));
         $epost = new \Components\Forum\Models\Thread($model);
         $epost->set('section', $esection->get('alias'));
         $epost->set('category', $ecategory->get('alias'));
         // Figure out who should be notified about this comment (all group members for now)
         $userIDsToEmail = array();
         foreach ($this->members as $mbr) {
             //Look up user info
             $user = User::getInstance($mbr);
             if ($user->get('id')) {
                 include_once PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'memberoption.class.php';
                 // Find the user's group settings, do they want to get email (0 or 1)?
                 $groupMemberOption = new GroupsTableMemberoption($this->database);
                 $groupMemberOption->loadRecord($this->group->get('gidNumber'), $user->get('id'), GROUPS_MEMBEROPTION_TYPE_DISCUSSION_NOTIFICIATION);
                 $sendEmail = 0;
                 if ($groupMemberOption->id) {
                     $sendEmail = $groupMemberOption->optionvalue;
                 }
                 if ($sendEmail == 1) {
                     $userIDsToEmail[] = $user->get('id');
                 }
             }
         }
         $encryptor = new \Hubzero\Mail\Token();
         $from = array('name' => Config::get('sitename'), 'email' => Config::get('mailfrom'));
         // Email each group member separately, each needs a user specific token
         foreach ($userIDsToEmail as $userID) {
             // Construct User specific Email ThreadToken
             // Version, type, userid, xforumid
             $token = $encryptor->buildEmailToken(1, 2, $userID, $parent);
             // add unsubscribe link
             $unsubscribeToken = $encryptor->buildEmailToken(1, 3, $userID, $this->group->get('gidNumber'));
             $unsubscribeLink = rtrim(Request::base(), '/') . '/' . ltrim(Route::url('index.php?option=com_groups&cn=' . $this->group->get('cn') . '&active=forum&action=unsubscribe&t=' . $unsubscribeToken), DS);
             $msg = array();
             // create view object
             $eview = new \Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'email', 'layout' => 'comment_plain'));
             // plain text
             $eview->set('delimiter', '~!~!~!~!~!~!~!~!~!~!')->set('unsubscribe', $unsubscribeLink)->set('group', $this->group)->set('section', $esection)->set('category', $ecategory)->set('thread', $ethread)->set('post', $epost);
             $plain = $eview->loadTemplate(false);
             $msg['plaintext'] = str_replace("\n", "\r\n", $plain);
             // HTML
             $eview->setLayout('comment_html');
             $html = $eview->loadTemplate();
             $msg['multipart'] = str_replace("\n", "\r\n", $html);
             $subject = ' - ' . $this->group->get('cn') . ' - ' . $posttitle;
             $from['replytoemail'] = 'hgm-' . $token . '@' . $_SERVER['HTTP_HOST'];
             if (!Event::trigger('xmessage.onSendMessage', array('group_message', $subject, $msg, $from, array($userID), $this->option, null, '', $this->group->get('gidNumber')))) {
                 $this->setError(Lang::txt('GROUPS_ERROR_EMAIL_MEMBERS_FAILED'));
             }
         }
     }
     // Set the redirect
     App::redirect(Route::url($this->base . '&scope=' . $section . '/' . $category->alias . '/' . $thread), $message, 'passed');
 }
Beispiel #2
0
 /**
  * Saves changes to a ticket, adds a new comment/changelog,
  * notifies any relevant parties
  *
  * @return void
  */
 public function saveTask($redirect = 1)
 {
     // Check for request forgeries
     Request::checkToken();
     // Incoming
     $isNew = true;
     $id = Request::getInt('id', 0);
     if ($id) {
         $isNew = false;
     }
     // Load the old ticket so we can compare for the changelog
     $old = new Ticket($id);
     $old->set('tags', $old->tags('string'));
     // Initiate class and bind posted items to database fields
     $row = new Ticket($id);
     if (!$row->bind($_POST)) {
         throw new Exception($row->getError(), 500);
     }
     if ($row->get('target_date') && $row->get('target_date') != '0000-00-00 00:00:00') {
         $row->set('target_date', Date::of($row->get('target_date'), Config::get('offset'))->toSql());
     } else {
         $row->set('target_date', '0000-00-00 00:00:00');
     }
     $comment = Request::getVar('comment', '', 'post', 'none', 2);
     $rowc = new Comment();
     $rowc->set('ticket', $id);
     // Check if changes were made inbetween the time the comment was started and posted
     if ($id) {
         $started = Request::getVar('started', Date::toSql(), 'post');
         $lastcomment = $row->comments('list', array('sort' => 'created', 'sort_Dir' => 'DESC', 'limit' => 1, 'start' => 0, 'ticket' => $id))->first();
         if (isset($lastcomment) && $lastcomment->created() >= $started) {
             $rowc->set('comment', $comment);
             \Notify::error(Lang::txt('Changes were made to this ticket in the time since you began commenting/making changes. Please review your changes before submitting.'));
             return $this->editTask($rowc);
         }
     }
     if ($id && isset($_POST['status']) && $_POST['status'] == 0) {
         $row->set('open', 0);
         $row->set('resolved', Lang::txt('COM_SUPPORT_TICKET_COMMENT_OPT_CLOSED'));
     }
     $row->set('open', $row->status('open'));
     // If an existing ticket AND closed AND previously open
     if ($id && !$row->get('open') && $row->get('open') != $old->get('open')) {
         // Record the closing time
         $row->set('closed', Date::toSql());
     }
     // Check content
     if (!$row->check()) {
         throw new Exception($row->getError(), 500);
     }
     // Store new content
     if (!$row->store()) {
         throw new Exception($row->getError(), 500);
     }
     // Save the tags
     $row->tag(Request::getVar('tags', '', 'post'), User::get('id'), 1);
     $row->set('tags', $row->tags('string'));
     $base = Request::base();
     if (substr($base, -14) == 'administrator/') {
         $base = substr($base, 0, strlen($base) - 14);
     }
     $webpath = trim($this->config->get('webpath'), '/');
     $allowEmailResponses = $this->config->get('email_processing');
     $this->config->set('email_terse', Request::getInt('email_terse', 0));
     if ($this->config->get('email_terse')) {
         $allowEmailResponses = false;
     }
     if ($allowEmailResponses) {
         try {
             $encryptor = new \Hubzero\Mail\Token();
         } catch (Exception $e) {
             $allowEmailResponses = false;
         }
     }
     // If a new ticket...
     if ($isNew) {
         // Get any set emails that should be notified of ticket submission
         $defs = explode(',', $this->config->get('emails', '{config.mailfrom}'));
         if ($defs) {
             // Get some email settings
             $msg = new \Hubzero\Mail\Message();
             $msg->setSubject(Config::get('sitename') . ' ' . Lang::txt('COM_SUPPORT') . ', ' . Lang::txt('COM_SUPPORT_TICKET_NUMBER', $row->get('id')));
             $msg->addFrom(Config::get('mailfrom'), Config::get('sitename') . ' ' . Lang::txt(strtoupper($this->_option)));
             // Plain text email
             $eview = new \Hubzero\Mail\View(array('base_path' => PATH_CORE . DS . 'components' . DS . $this->_option . DS . 'site', 'name' => 'emails', 'layout' => 'ticket_plain'));
             $eview->option = $this->_option;
             $eview->controller = $this->_controller;
             $eview->ticket = $row;
             $eview->config = $this->config;
             $eview->delimiter = '';
             $plain = $eview->loadTemplate(false);
             $plain = str_replace("\n", "\r\n", $plain);
             $msg->addPart($plain, 'text/plain');
             // HTML email
             $eview->setLayout('ticket_html');
             $html = $eview->loadTemplate();
             $html = str_replace("\n", "\r\n", $html);
             if (!$this->config->get('email_terse')) {
                 foreach ($row->attachments() as $attachment) {
                     if ($attachment->size() < 2097152) {
                         if ($attachment->isImage()) {
                             $file = basename($attachment->link('filepath'));
                             $html = preg_replace('/<a class="img" data\\-filename="' . str_replace('.', '\\.', $file) . '" href="(.*?)"\\>(.*?)<\\/a>/i', '<img src="' . $message->getEmbed($attachment->link('filepath')) . '" alt="" />', $html);
                         } else {
                             $message->addAttachment($attachment->link('filepath'));
                         }
                     }
                 }
             }
             $msg->addPart($html, 'text/html');
             // Loop through the addresses
             foreach ($defs as $def) {
                 $def = trim($def);
                 // Check if the address should come from Joomla config
                 if ($def == '{config.mailfrom}') {
                     $def = Config::get('mailfrom');
                 }
                 // Check for a valid address
                 if (Validate::email($def)) {
                     // Send e-mail
                     $msg->setTo(array($def));
                     $msg->send();
                 }
             }
         }
     }
     // Incoming comment
     if ($comment) {
         // If a comment was posted by the ticket submitter to a "waiting user response" ticket, change status.
         if ($row->isWaiting() && User::get('username') == $row->get('login')) {
             $row->open();
         }
     }
     // Create a new support comment object and populate it
     $access = Request::getInt('access', 0);
     //$rowc = new Comment();
     $rowc->set('ticket', $row->get('id'));
     $rowc->set('comment', nl2br($comment));
     $rowc->set('created', Date::toSql());
     $rowc->set('created_by', User::get('id'));
     $rowc->set('access', $access);
     // Compare fields to find out what has changed for this ticket and build a changelog
     $rowc->changelog()->diff($old, $row);
     $rowc->changelog()->cced(Request::getVar('cc', ''));
     // Save the data
     if (!$rowc->store()) {
         throw new Exception($rowc->getError(), 500);
     }
     Event::trigger('support.onTicketUpdate', array($row, $rowc));
     if ($tmp = Request::getInt('tmp_dir')) {
         $attach = new Tables\Attachment($this->database);
         $attach->updateCommentId($tmp, $rowc->get('id'));
     }
     if (!$isNew) {
         $attachment = $this->uploadTask($row->get('id'), $rowc->get('id'));
     }
     // Only do the following if a comment was posted or ticket was reassigned
     // otherwise, we're only recording a changelog
     if ($rowc->get('comment') || $row->get('owner') != $old->get('owner') || $row->get('group') != $old->get('group') || $rowc->attachments()->total() > 0) {
         // Send e-mail to ticket submitter?
         if (Request::getInt('email_submitter', 0) == 1) {
             // Is the comment private? If so, we do NOT send e-mail to the
             // submitter regardless of the above setting
             if (!$rowc->isPrivate()) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_SUBMITTER'), 'name' => $row->submitter('name'), 'email' => $row->submitter('email'), 'id' => $row->submitter('id')));
             }
         }
         // Send e-mail to ticket owner?
         if (Request::getInt('email_owner', 0) == 1) {
             if ($old->get('owner') && $row->get('owner') != $old->get('owner')) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_PRIOR_OWNER'), 'name' => $old->owner('name'), 'email' => $old->owner('email'), 'id' => $old->owner('id')));
             }
             if ($row->get('owner')) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_OWNER'), 'name' => $row->owner('name'), 'email' => $row->owner('email'), 'id' => $row->owner('id')));
             } elseif ($row->get('group')) {
                 $group = \Hubzero\User\Group::getInstance($row->get('group'));
                 if ($group) {
                     foreach ($group->get('managers') as $manager) {
                         $manager = User::getInstance($manager);
                         if (!$manager || !$manager->get('id')) {
                             continue;
                         }
                         $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_GROUPMANAGER'), 'name' => $manager->get('name'), 'email' => $manager->get('email'), 'id' => $manager->get('id')));
                     }
                 }
             }
         }
         // Add any CCs to the e-mail list
         foreach ($rowc->changelog()->get('cc') as $cc) {
             $rowc->addTo($cc, Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_CC'));
         }
         // Message people watching this ticket,
         // but ONLY if the comment was NOT marked private
         $this->acl = ACL::getACL();
         foreach ($row->watchers() as $watcher) {
             $this->acl->setUser($watcher->user_id);
             if (!$rowc->isPrivate() || $rowc->isPrivate() && $this->acl->check('read', 'private_comments')) {
                 $rowc->addTo($watcher->user_id, 'watcher');
             }
         }
         $this->acl->setUser(User::get('id'));
         if (count($rowc->to())) {
             // Build e-mail components
             $subject = Lang::txt('COM_SUPPORT_EMAIL_SUBJECT_TICKET_COMMENT', $row->get('id'));
             $from = array('name' => Lang::txt('COM_SUPPORT_EMAIL_FROM', Config::get('sitename')), 'email' => Config::get('mailfrom'), 'multipart' => md5(date('U')));
             // Plain text email
             $eview = new \Hubzero\Mail\View(array('base_path' => PATH_CORE . DS . 'components' . DS . $this->_option . DS . 'site', 'name' => 'emails', 'layout' => 'comment_plain'));
             $eview->option = $this->_option;
             $eview->controller = $this->_controller;
             $eview->comment = $rowc;
             $eview->ticket = $row;
             $eview->config = $this->config;
             $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();
             $message['multipart'] = str_replace("\n", "\r\n", $message['multipart']);
             $message['attachments'] = array();
             if (!$this->config->get('email_terse')) {
                 foreach ($rowc->attachments() as $attachment) {
                     if ($attachment->size() < 2097152) {
                         $message['attachments'][] = $attachment->link('filepath');
                     }
                 }
             }
             // Send e-mail to admin?
             foreach ($rowc->to('ids') as $to) {
                 if ($allowEmailResponses) {
                     // The reply-to address contains the token
                     $token = $encryptor->buildEmailToken(1, 1, $to['id'], $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']), $this->_option))) {
                     $this->setError(Lang::txt('COM_SUPPORT_ERROR_FAILED_TO_MESSAGE', $to['name'] . '(' . $to['role'] . ')'));
                 }
                 // Watching should be anonymous
                 if ($to['role'] == 'watcher') {
                     continue;
                 }
                 $rowc->changelog()->notified($to['role'], $to['name'], $to['email']);
             }
             foreach ($rowc->to('emails') as $to) {
                 if ($allowEmailResponses) {
                     $token = $encryptor->buildEmailToken(1, 1, -9999, $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
                     Utilities::sendEmail($email[0], $subject, $message, $from, $email[1]);
                 } else {
                     // Email is just a plain 'ol string
                     Utilities::sendEmail($to['email'], $subject, $message, $from);
                 }
                 // Watching should be anonymous
                 if ($to['role'] == 'watcher') {
                     continue;
                 }
                 $rowc->changelog()->notified($to['role'], $to['name'], $to['email']);
             }
         } else {
             // Force entry to private if no comment or attachment was made
             if (!$rowc->get('comment') && $rowc->attachments()->total() <= 0) {
                 $rowc->set('access', 1);
             }
         }
         // Were there any changes?
         if (count($rowc->changelog()->get('notifications')) > 0 || $access != $rowc->get('access')) {
             // Save the data
             if (!$rowc->store()) {
                 throw new Exception($rowc->getError(), 500);
             }
         }
     }
     // output messsage and redirect
     if ($redirect) {
         $filters = Request::getVar('filters', '');
         $filters = str_replace('&amp;', '&', $filters);
         // Redirect
         App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . ($filters ? '&' . $filters : ''), false), Lang::txt('COM_SUPPORT_TICKET_SUCCESSFULLY_SAVED', $row->get('id')));
         return;
     }
     $this->view->setLayout('edit');
     $this->editTask();
 }
 /**
  * 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');
 }
Beispiel #4
0
 /**
  * Updates a ticket with any changes and adds a new comment
  *
  * @return     void
  */
 public function updateTask()
 {
     // Make sure we are still logged in
     if (User::isGuest()) {
         $return = base64_encode(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&task=' . $this->_task, false, true));
         App::redirect(Route::url('index.php?option=com_users&view=login&return=' . $return, false));
         return;
     }
     // Check for request forgeries
     Request::checkToken();
     // Incoming
     $id = Request::getInt('id', 0, 'post');
     if (!$id) {
         throw new Exception(Lang::txt('COM_SUPPORT_ERROR_MISSING_TICKET_ID'), 500);
     }
     $comment = Request::getVar('comment', '', 'post', 'none', 2);
     $incoming = Request::getVar('ticket', array(), 'post');
     $incoming = array_map('trim', $incoming);
     if (isset($incoming['target_date'])) {
         if (!$incoming['target_date']) {
             $incoming['target_date'] = '0000-00-00 00:00:00';
         } else {
             $incoming['target_date'] = Date::of($incoming['target_date'], Config::get('offset'))->toSql();
         }
     }
     // Load the old ticket so we can compare for the changelog
     $old = new Ticket($id);
     $old->set('tags', $old->tags('string'));
     // Initiate class and bind posted items to database fields
     $row = new Ticket($id);
     if (!$row->bind($incoming)) {
         throw new Exception($row->getError(), 500);
     }
     $rowc = new Comment();
     $rowc->set('ticket', $id);
     // Check if changes were made inbetween the time the comment was started and posted
     $started = Request::getVar('started', Date::toSql(), 'post');
     $lastcomment = $row->comments('list', array('sort' => 'created', 'sort_Dir' => 'DESC', 'limit' => 1, 'start' => 0, 'ticket' => $id))->first();
     if ($lastcomment && $lastcomment->created() > $started) {
         $rowc->set('comment', $comment);
         $this->setError(Lang::txt('Changes were made to this ticket in the time since you began commenting/making changes. Please review your changes before submitting.'));
         return $this->ticketTask($rowc);
     }
     // Update ticket status if necessary
     if ($id && isset($incoming['status']) && $incoming['status'] == 0) {
         $row->set('open', 0);
         $row->set('resolved', Lang::txt('COM_SUPPORT_COMMENT_OPT_CLOSED'));
     }
     $row->set('open', $row->status('open'));
     // Check content
     if (!$row->check()) {
         throw new Exception($row->getError(), 500);
     }
     // If an existing ticket AND closed AND previously open
     if ($id && !$row->get('open') && $row->get('open') != $old->get('open')) {
         // Record the closing time
         $row->set('closed', Date::toSql());
     }
     // Incoming comment
     if ($comment) {
         // If a comment was posted by the ticket submitter to a "waiting user response" ticket, change status.
         if ($row->isWaiting() && User::get('username') == $row->get('login')) {
             $row->open();
         }
     }
     // Store new content
     if (!$row->store()) {
         throw new Exception($row->getError(), 500);
     }
     // Save the tags
     $row->tag(Request::getVar('tags', '', 'post'), User::get('id'), 1);
     $row->set('tags', $row->tags('string'));
     // Create a new support comment object and populate it
     $access = Request::getInt('access', 0);
     $rowc->set('ticket', $id);
     $rowc->set('comment', nl2br($comment));
     $rowc->set('created', Date::toSql());
     $rowc->set('created_by', User::get('id'));
     $rowc->set('access', $access);
     // Compare fields to find out what has changed for this ticket and build a changelog
     $rowc->changelog()->diff($old, $row);
     $rowc->changelog()->cced(Request::getVar('cc', ''));
     // Save the data
     if (!$rowc->store()) {
         throw new Exception($rowc->getError(), 500);
     }
     Event::trigger('support.onTicketUpdate', array($row, $rowc));
     $attach = new Tables\Attachment($this->database);
     if ($tmp = Request::getInt('tmp_dir')) {
         $attach->updateCommentId($tmp, $rowc->get('id'));
     }
     $attachment = $this->uploadTask($row->get('id'), $rowc->get('id'));
     // Only do the following if a comment was posted
     // otherwise, we're only recording a changelog
     if ($rowc->get('comment') || $row->get('owner') != $old->get('owner') || $row->get('group') != $old->get('group') || $rowc->attachments()->total() > 0) {
         // Send e-mail to ticket submitter?
         if (Request::getInt('email_submitter', 0) == 1) {
             // Is the comment private? If so, we do NOT send e-mail to the
             // submitter regardless of the above setting
             if (!$rowc->isPrivate()) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_SUBMITTER'), 'name' => $row->submitter('name'), 'email' => $row->submitter('email'), 'id' => $row->submitter('id')));
             }
         }
         // Send e-mail to ticket owner?
         if (Request::getInt('email_owner', 0) == 1) {
             if ($old->get('owner') && $row->get('owner') != $old->get('owner')) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_PRIOR_OWNER'), 'name' => $old->owner('name'), 'email' => $old->owner('email'), 'id' => $old->owner('id')));
             }
             if ($row->get('owner')) {
                 $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_OWNER'), 'name' => $row->owner('name'), 'email' => $row->owner('email'), 'id' => $row->owner('id')));
             } elseif ($row->get('group')) {
                 $group = \Hubzero\User\Group::getInstance($row->get('group'));
                 if ($group) {
                     foreach ($group->get('managers') as $manager) {
                         $manager = User::getInstance($manager);
                         if (!$manager || !$manager->get('id')) {
                             continue;
                         }
                         $rowc->addTo(array('role' => Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_GROUPMANAGER'), 'name' => $manager->get('name'), 'email' => $manager->get('email'), 'id' => $manager->get('id')));
                     }
                 }
             }
         }
         // Add any CCs to the e-mail list
         foreach ($rowc->changelog()->get('cc') as $cc) {
             $rowc->addTo($cc, Lang::txt('COM_SUPPORT_COMMENT_SEND_EMAIL_CC'));
         }
         // Message people watching this ticket,
         // but ONLY if the comment was NOT marked private
         foreach ($row->watchers() as $watcher) {
             $this->acl->setUser($watcher->user_id);
             if (!$rowc->isPrivate() || $rowc->isPrivate() && $this->acl->check('read', 'private_comments')) {
                 $rowc->addTo($watcher->user_id, 'watcher');
             }
         }
         $this->acl->setUser(User::get('id'));
         $recipients = array(['support.tickets', 1]);
         if (count($rowc->to())) {
             $this->config->set('email_terse', Request::getInt('email_terse', 0));
             $allowEmailResponses = $this->config->get('email_processing');
             if ($this->config->get('email_terse')) {
                 $allowEmailResponses = false;
             }
             if ($allowEmailResponses) {
                 try {
                     $encryptor = new \Hubzero\Mail\Token();
                 } catch (Exception $e) {
                     $allowEmailResponses = false;
                 }
             }
             // Build e-mail components
             $subject = Lang::txt('COM_SUPPORT_EMAIL_SUBJECT_TICKET_COMMENT', $row->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('name' => 'emails', 'layout' => 'comment_plain'));
             $eview->option = $this->_option;
             $eview->controller = $this->_controller;
             $eview->comment = $rowc;
             $eview->ticket = $row;
             $eview->config = $this->config;
             $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();
             $message['multipart'] = str_replace("\n", "\r\n", $message['multipart']);
             $message['attachments'] = array();
             if (!$this->config->get('email_terse')) {
                 foreach ($rowc->attachments() as $attachment) {
                     if ($attachment->size() < 2097152) {
                         $message['attachments'][] = $attachment->link('filepath');
                     }
                 }
             }
             foreach ($rowc->to('ids') as $to) {
                 $recipients[] = ['user', $to['id']];
                 if ($allowEmailResponses) {
                     // The reply-to address contains the token
                     $token = $encryptor->buildEmailToken(1, 1, $to['id'], $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']), $this->_option))) {
                     $this->setError(Lang::txt('COM_SUPPORT_ERROR_FAILED_TO_MESSAGE', $to['name'] . '(' . $to['role'] . ')'));
                 }
                 // Watching should be anonymous
                 if ($to['role'] == 'watcher') {
                     continue;
                 }
                 $rowc->changelog()->notified($to['role'], $to['name'], $to['email']);
             }
             foreach ($rowc->to('emails') as $to) {
                 if ($allowEmailResponses) {
                     $token = $encryptor->buildEmailToken(1, 1, -9999, $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
                     Utilities::sendEmail($email[0], $subject, $message, $from, $email[1]);
                 } else {
                     // email is just a plain 'ol string
                     Utilities::sendEmail($to['email'], $subject, $message, $from);
                 }
                 // Watching should be anonymous
                 if ($to['role'] == 'watcher') {
                     continue;
                 }
                 $rowc->changelog()->notified($to['role'], $to['name'], $to['email']);
             }
         } else {
             // Force entry to private if no comment or attachment was made
             if (!$rowc->get('comment') && $rowc->attachments()->total() <= 0) {
                 $rowc->set('access', 1);
             }
         }
         // Were there any changes?
         if (count($rowc->changelog()->get('notifications')) > 0 || $access != $rowc->get('access')) {
             if (!$rowc->store()) {
                 throw new Exception($rowc->getError(), 500);
             }
         }
         $desc = Lang::txt('COM_SUPPORT_ACTIVITY_TICKET_UPDATED', '<a href="' . Route::url($row->link()) . '">#' . $row->get('id') . ' - ' . $row->get('summary') . '</a>');
         if ($rowc->get('comment')) {
             $desc = Lang::txt('COM_SUPPORT_ACTIVITY_COMMENT_CREATED', $rowc->get('id'), '<a href="' . Route::url($row->link()) . '">#' . $row->get('id') . ' - ' . $row->get('summary') . '</a>');
         }
         Event::trigger('system.logActivity', ['activity' => ['action' => 'created', 'scope' => 'support.ticket.comment', 'scope_id' => $rowc->get('id'), 'description' => $desc, 'details' => array('id' => $row->get('id'), 'summary' => $row->get('summary'), 'url' => Route::url($row->link()), 'comment' => $rowc->get('id'))], 'recipients' => $recipients]);
     }
     // Display the ticket with changes, new comment
     App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&task=ticket&id=' . $id), $this->getError() ? $this->getError() : null, $this->getError() ? 'error' : null);
 }
Beispiel #5
0
 /**
  * Saves posted data for a new/edited forum thread post
  *
  * @return  void
  */
 public function savethread()
 {
     // Login check is handled in the onGroup() method
     /*if (User::isGuest())
     		{
     			App::redirect(
     				Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($this->base, false, true)))
     			);
     			return;
     		}*/
     // Check for request forgeries
     Request::checkToken();
     // Incoming
     $section = Request::getVar('section', '');
     $fields = Request::getVar('fields', array(), 'post', 'none', 2);
     $fields = array_map('trim', $fields);
     $fields['sticky'] = isset($fields['sticky']) ? $fields['sticky'] : 0;
     $fields['closed'] = isset($fields['closed']) ? $fields['closed'] : 0;
     $fields['anonymous'] = isset($fields['anonymous']) ? $fields['anonymous'] : 0;
     // Instantiate a Post record
     $post = Post::oneOrNew($fields['id']);
     $this->_authorize('thread', intval($fields['id']));
     $asset = 'thread';
     if ($fields['parent']) {
         //$asset = 'post';
     }
     $moving = false;
     // Already present
     if ($fields['id']) {
         if ($post->get('created_by') == User::get('id')) {
             $this->params->set('access-edit-' . $asset, true);
         }
         // Determine if we are moving the category for email suppression
         if ($post->get('category_id') != $fields['category_id']) {
             $moving = true;
         }
         $fields['modified'] = \Date::toSql();
         $fields['modified_by'] = User::get('id');
     }
     if (!$this->params->get('access-edit-thread') && !$this->params->get('access-create-thread')) {
         App::redirect(Route::url('index.php?option=' . $this->option . '&cn=' . $this->group->get('cn') . '&active=forum'), Lang::txt('PLG_GROUPS_FORUM_NOT_AUTHORIZED'), 'warning');
     }
     // Bind data
     $post->set($fields);
     // Make sure the thread exists and is accepting new posts
     if ($post->get('parent') && isset($fields['thread'])) {
         $thread = Post::oneOrFail($fields['thread']);
         if (!$thread->get('id') || $thread->get('closed')) {
             Notify::error(Lang::txt('PLG_GROUPS_FORUM_ERROR_THREAD_CLOSED'));
             return $this->editthread($post);
         }
     }
     if (!$post->get('category_id')) {
         Notify::error(Lang::txt('PLG_GROUPS_FORUM_ERROR_MISSING_CATEGORY'));
         return $this->editthread($post);
     }
     // Make sure the category exists and is accepting new posts
     $category = Category::oneOrFail($post->get('category_id'));
     if ($category->get('closed')) {
         Notify::error(Lang::txt('PLG_GROUPS_ERROR_CATEGORY_CLOSED'));
         return $this->editthread($post);
     }
     // Store new content
     if (!$post->save()) {
         Notify::error($post->getError());
         return $this->editthread($post);
     }
     // Upload
     if (!$this->upload($post->get('thread', $post->get('id')), $post->get('id'))) {
         Notify::error($this->getError());
         return $this->editthread($post);
     }
     // Save tags
     $post->tag(Request::getVar('tags', '', 'post'), User::get('id'));
     // Set message
     if (!$fields['id']) {
         $message = Lang::txt('PLG_GROUPS_FORUM_POST_ADDED');
         if (!$fields['parent']) {
             $message = Lang::txt('PLG_GROUPS_FORUM_THREAD_STARTED');
         }
     } else {
         $message = $post->get('modified_by') ? Lang::txt('PLG_GROUPS_FORUM_POST_EDITED') : Lang::txt('PLG_GROUPS_FORUM_POST_ADDED');
     }
     $section = $category->section();
     $thread = Post::oneOrNew($post->get('thread'));
     // Disable notifications
     if ($fields['id'] && !Request::getInt('notify', 0)) {
         $moving = true;
     }
     // Email the group and insert email tokens to allow them to respond to group posts via email
     $params = Component::params('com_groups');
     if ($params->get('email_comment_processing') && (isset($moving) && $moving == false)) {
         $thread->set('section', $section->get('alias'));
         $thread->set('category', $category->get('alias'));
         $post->set('section', $section->get('alias'));
         $post->set('category', $category->get('alias'));
         // Figure out who should be notified about this comment (all group members for now)
         $userIDsToEmail = array();
         $memberoptions = false;
         if (file_exists(PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'models' . DS . 'memberoption.php')) {
             include_once PATH_CORE . DS . 'plugins' . DS . 'groups' . DS . 'memberoptions' . DS . 'models' . DS . 'memberoption.php';
             $memberoptions = true;
         }
         foreach ($this->members as $mbr) {
             //Look up user info
             $user = User::getInstance($mbr);
             if ($user->get('id') && $memberoptions) {
                 // Find the user's group settings, do they want to get email (0 or 1)?
                 $groupMemberOption = Plugins\Groups\Memberoptions\Models\Memberoption::oneByUserAndOption($this->group->get('gidNumber'), $user->get('id'), 'receive-forum-email');
                 $sendEmail = $groupMemberOption->get('optionvalue', 0);
                 if ($sendEmail == 1) {
                     $userIDsToEmail[] = $user->get('id');
                 }
             }
         }
         $allowEmailResponses = true;
         try {
             $encryptor = new \Hubzero\Mail\Token();
         } catch (Exception $e) {
             $allowEmailResponses = false;
         }
         $from = array('name' => (!$post->get('anonymous') ? $post->creator->get('name', Lang::txt('PLG_GROUPS_FORUM_UNKNOWN')) : Lang::txt('PLG_GROUPS_FORUM_ANONYMOUS')) . ' @ ' . Config::get('sitename'), 'email' => Config::get('mailfrom'), 'replytoname' => Config::get('sitename'), 'replytoemail' => Config::get('mailfrom'));
         // Email each group member separately, each needs a user specific token
         foreach ($userIDsToEmail as $userID) {
             $unsubscribeLink = '';
             $delimiter = '';
             if ($allowEmailResponses) {
                 $delimiter = '~!~!~!~!~!~!~!~!~!~!';
                 // Construct User specific Email ThreadToken
                 // Version, type, userid, xforumid
                 $token = $encryptor->buildEmailToken(1, 2, $userID, $post->get('thread', $post->get('id')));
                 // add unsubscribe link
                 $unsubscribeToken = $encryptor->buildEmailToken(1, 3, $userID, $this->group->get('gidNumber'));
                 $unsubscribeLink = rtrim(Request::base(), '/') . '/' . ltrim(Route::url('index.php?option=com_groups&cn=' . $this->group->get('cn') . '&active=forum&action=unsubscribe&t=' . $unsubscribeToken), DS);
                 $from['replytoname'] = Lang::txt('PLG_GROUPS_FORUM_REPLYTO') . ' @ ' . Config::get('sitename');
                 $from['replytoemail'] = 'hgm-' . $token . '@' . $_SERVER['HTTP_HOST'];
             }
             $msg = array();
             // create view object
             $eview = new \Hubzero\Mail\View(array('base_path' => __DIR__, 'name' => 'email', 'layout' => 'comment_plain'));
             // plain text
             $eview->set('delimiter', $delimiter)->set('unsubscribe', $unsubscribeLink)->set('group', $this->group)->set('section', $section)->set('category', $category)->set('thread', $thread)->set('post', $post);
             $plain = $eview->loadTemplate(false);
             $msg['plaintext'] = str_replace("\n", "\r\n", $plain);
             // HTML
             $eview->setLayout('comment_html');
             $html = $eview->loadTemplate();
             $msg['multipart'] = str_replace("\n", "\r\n", $html);
             $subject = Lang::txt('PLG_GROUPS_FORUM') . ': ' . $this->group->get('cn') . ' - ' . $thread->get('title');
             if (!Event::trigger('xmessage.onSendMessage', array('group_message', $subject, $msg, $from, array($userID), $this->option, null, '', $this->group->get('gidNumber')))) {
                 $this->setError(Lang::txt('GROUPS_ERROR_EMAIL_MEMBERS_FAILED'));
             }
         }
     }
     $url = $this->base . '&scope=' . $section->get('alias') . '/' . $category->get('alias') . '/' . $thread->get('id');
     // Record the activity
     $recipients = array(['group', $this->group->get('gidNumber')], ['forum.' . $this->forum->get('scope'), $this->forum->get('scope_id')], ['user', $post->get('created_by')]);
     foreach ($this->group->get('managers') as $recipient) {
         $recipients[] = ['user', $recipient];
     }
     $type = 'thread';
     $desc = Lang::txt('PLG_GROUPS_FORUM_ACTIVITY_' . strtoupper($type) . '_' . ($fields['id'] ? 'UPDATED' : 'CREATED'), '<a href="' . Route::url($url) . '">' . $post->get('title') . '</a>');
     // If this is a post in a thread and not the thread starter...
     if ($post->get('parent')) {
         $thread = isset($thread) ? $thread : Post::oneOrFail($post->get('thread'));
         $thread->set('last_activity', $fields['id'] ? $post->get('modified') : $post->get('created'));
         $thread->save();
         $type = 'post';
         $desc = Lang::txt('PLG_GROUPS_FORUM_ACTIVITY_' . strtoupper($type) . '_' . ($fields['id'] ? 'UPDATED' : 'CREATED'), $post->get('id'), '<a href="' . Route::url($url) . '">' . $thread->get('title') . '</a>');
         // If the parent post is not the same as the
         // thread starter (i.e., this is a reply)
         if ($post->get('parent') != $post->get('thread')) {
             $parent = Post::oneOrFail($post->get('parent'));
             $recipients[] = ['user', $parent->get('created_by')];
         }
     }
     Event::trigger('system.logActivity', ['activity' => ['action' => $fields['id'] ? 'updated' : 'created', 'scope' => 'forum.' . $type, 'scope_id' => $post->get('id'), 'anonymous' => $post->get('anonymous', 0), 'description' => $desc, 'details' => array('thread' => $post->get('thread'), 'url' => Route::url($url))], 'recipients' => $recipients]);
     // Set the redirect
     App::redirect(Route::url($url), $message, 'passed');
 }