/** * Displays a question response for editing * * @param mixed $post * @return void */ public function editTask($post = null) { Request::setVar('hidemainmenu', 1); if (!User::authorise('core.edit', $this->_option) && !User::authorise('core.create', $this->_option)) { App::abort(403, Lang::txt('JERROR_ALERTNOAUTHOR')); } // Incoming $parent = Request::getInt('parent', 0); if (!is_object($post)) { $id = Request::getVar('id', array(0)); if (is_array($id)) { $id = intval($id[0]); } $post = Post::oneOrNew($id); } if ($post->isNew()) { $post->set('parent', $parent); $post->set('created_by', User::get('id')); } if ($post->get('parent')) { $threads = Post::all()->whereEquals('category_id', $post->get('category_id'))->whereEquals('parent', 0)->ordered()->rows(); } // Get the category $category = Category::oneOrNew($post->get('category_id')); $categories = array(); foreach (Category::all()->rows() as $c) { if (!isset($categories[$c->section_id])) { $categories[$c->section_id] = array(); } $categories[$c->section_id][] = $c; asort($categories[$c->section_id]); } // Get the section $section = Section::oneOrNew($category->get('section_id')); // Get the sections for this group $sections = array(); foreach (Section::all()->rows() as $s) { $ky = $s->scope . ' (' . $s->scope_id . ')'; if ($s->scope == 'site') { $ky = '[ site ]'; } if (!isset($sections[$ky])) { $sections[$ky] = array(); } $s->categories = isset($categories[$s->id]) ? $categories[$s->id] : array(); $sections[$ky][] = $s; asort($sections[$ky]); } User::setState('com_forum.edit.thread.data', array('id' => $post->get('id'), 'asset_id' => $post->get('asset_id'))); $m = new AdminThread(); $form = $m->getForm(); // Get tags on this article $this->view->set('row', $post)->set('sections', $sections)->set('categories', $categories)->set('form', $form)->setLayout('edit')->display(); }
/** * Sets the state of one or more entries * * @return void */ public function accessTask() { // Check for request forgeries Request::checkToken(['get', 'post']); if (!User::authorise('core.edit.state', $this->_option)) { App::abort(403, Lang::txt('JERROR_ALERTNOAUTHOR')); } // Incoming $state = Request::getInt('access', 0); $ids = Request::getVar('id', array()); $ids = !is_array($ids) ? array($ids) : $ids; // Check for an ID if (count($ids) < 1) { Notify::warning(Lang::txt('COM_FORUM_SELECT_ENTRY_TO_CHANGE_ACCESS')); return $this->cancelTask(); } $i = 0; foreach ($ids as $id) { // Update record(s) $row = Category::oneOrFail(intval($id)); $row->set('access', $state); if (!$row->save()) { Notify::error($row->getError()); continue; } $i++; } // set message if ($i) { Notify::success(Lang::txt('COM_FORUM_ITEMS_ACCESS_CHANGED', $i)); } $this->cancelTask(); }
/** * Get the adapter * * @return object */ public function adapter() { if (!$this->_adapter) { $this->_adapter = $this->_adapter(); $this->_adapter->set('thread', $this->get('thread')); $this->_adapter->set('parent', $this->get('parent')); $this->_adapter->set('post', $this->get('id')); if (!$this->get('category')) { $category = Category::getInstance($this->get('category_id')); $this->set('category', $category->get('alias')); } $this->_adapter->set('category', $this->get('category')); if (!$this->get('section')) { $category = Category::getInstance($this->get('category_id')); $this->set('section', Section::getInstance($category->get('section_id'))->get('alias')); } $this->_adapter->set('section', $this->get('section')); } return $this->_adapter; }
/** * Save an entry * * @return void */ public function saveTask() { if (User::isGuest()) { App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url('index.php?option=' . $this->_option)))); 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); $assetType = 'thread'; if ($fields['parent']) { $assetType = 'post'; } if ($fields['id']) { $old = new Post(intval($fields['id'])); if ($old->get('created_by') == User::get('id')) { $this->config->set('access-edit-' . $assetType, true); } } $this->_authorize($assetType, intval($fields['id'])); if (!$this->config->get('access-edit-' . $assetType) && !$this->config->get('access-create-' . $assetType)) { App::redirect(Route::url('index.php?option=' . $this->_option)); return; } $fields['sticky'] = isset($fields['sticky']) ? $fields['sticky'] : 0; $fields['closed'] = isset($fields['closed']) ? $fields['closed'] : 0; $fields['anonymous'] = isset($fields['anonymous']) ? $fields['anonymous'] : 0; // Bind data $model = new Post($fields['id']); if ($model->get('parent')) { $fields['thread'] = isset($fields['thread']) ? $fields['thread'] : $model->get('parent'); $thread = new Thread($fields['thread']); if (!$thread->exists() || $thread->get('closed')) { Notify::error(Lang::txt('COM_FORUM_ERROR_THREAD_CLOSED'), 'forum'); $this->editTask($model); return; } } if (!$model->bind($fields)) { Notify::error($model->getError(), 'forum'); $this->editTask($model); return; } // Store new content if (!$model->store(true)) { Notify::error($model->getError(), 'forum'); $this->editTask($model); return; } $parent = $model->get('thread', $model->get('id')); // Upload files $this->uploadTask($parent, $model->get('id')); // Save tags $model->tag(Request::getVar('tags', '', 'post'), User::get('id')); // Determine message if (!$fields['id']) { if (!$fields['parent']) { $message = Lang::txt('COM_FORUM_THREAD_STARTED'); } else { $message = Lang::txt('COM_FORUM_POST_ADDED'); } } else { $message = $model->get('modified_by') ? Lang::txt('COM_FORUM_POST_EDITED') : Lang::txt('COM_FORUM_POST_ADDED'); } $category = new Category($model->get('category_id')); // Set the redirect App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category->get('alias') . '&thread=' . $parent . '#c' . $model->get('id')), $message, 'message'); }
/** * Set and get a specific category * * @param mixed $id Integer or string (ID or alias) for a category * @return object */ public function category($id = null) { if (!isset($this->_cache['category']) || $id !== null && (int) $this->_cache['category']->get('id') != $id && (string) $this->_cache['category']->get('alias') != $id) { $this->_cache['category'] = null; if ($this->_cache['categories'] instanceof ItemList) { foreach ($this->_cache['categories'] as $key => $category) { if ((int) $category->get('id') == $id || (string) $category->get('alias') == $id) { $this->_cache['category'] = $category; break; } } } if (!$this->_cache['category']) { } $this->_cache['category'] = Category::getInstance($id, $this->get('id')); //, $this->get('scope'), $this->get('scope_id')); if (!$this->_cache['category']->exists()) { $this->_cache['category']->set('scope', $this->get('scope')); $this->_cache['category']->set('scope_id', $this->get('scope_id')); } $this->_cache['category']->set('section_alias', $this->get('alias')); } return $this->_cache['category']; }
/** * Get categories for this forum * * @param array $filters Filters to apply to the query * @return object */ public function categories($filters = array()) { if (!isset($filters['scope'])) { $filters['scope'] = (string) $this->get('scope'); } if (!isset($filters['scope_id'])) { $filters['scope_id'] = (int) $this->get('scope_id'); } $model = Category::all(); if ($filters['scope']) { $model->whereEquals('scope', $filters['scope']); } if ($filters['scope_id'] >= 0) { $model->whereEquals('scope_id', $filters['scope_id']); } if (isset($filters['state'])) { $model->whereEquals('state', $filters['state']); } if (isset($filters['access'])) { if (!is_array($filters['access'])) { $filters['access'] = array($filters['access']); } $model->whereIn('access', $filters['access']); } return $model; }
/** * Populate the forum with defaulta section and category * * @return boolean */ public function setup() { // Create a default section $section = new Section(0, $this->get('scope'), $this->get('scope_id')); $section->bind(array('title' => Lang::txt('COM_FORUM_SECTION_DEFAULT'), 'scope' => $this->get('scope'), 'scope_id' => $this->get('scope_id'), 'state' => 1)); if (!$section->store(true)) { $this->setError($section->getError()); return false; } // Create a default category $category = new Category(0); $category->bind(array('title' => Lang::txt('COM_FORUM_CATEGORY_DEFAULT'), 'description' => Lang::txt('COM_FORUM_CATEGORY_DEFAULT_DESCRIPTION'), 'section_id' => $section->get('id'), 'scope' => $this->get('scope'), 'scope_id' => $this->get('scope_id'), 'state' => 1)); if (!$category->store(true)) { $this->setError($category->getError()); return false; } $this->_cache['sections'] = new ItemList(array($section)); return true; }
/** * Save an entry * * @return void */ public function saveTask() { // Check for request forgeries Request::checkToken(); $fields = Request::getVar('fields', array(), 'post'); $fields = array_map('trim', $fields); $model = new Category($fields['id']); if (!$model->bind($fields)) { Notify::error($model->getError()); $this->editTask($model); return; } $this->_authorize('category', $model->get('id')); if (!$this->config->get('access-edit-category')) { // Set the redirect App::redirect(Route::url('index.php?option=' . $this->_option)); } $model->set('closed', isset($fields['closed']) && $fields['closed'] ? 1 : 0); // Store new content if (!$model->store(true)) { Notify::error($model->getError()); $this->editTask($model); return; } // Set the redirect App::redirect(Route::url('index.php?option=' . $this->_option)); }
/** * Save an entry * * @return void */ public function saveTask() { if (User::isGuest()) { $return = Route::url('index.php?option=' . $this->_option, false, true); App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode($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']); // Set authorization if the current user is the creator // of an existing post. $assetType = $fields['parent'] ? 'post' : 'thread'; if ($post->get('id')) { if ($post->get('created_by') == User::get('id')) { $this->config->set('access-edit-' . $assetType, true); } $fields['modified'] = \Date::toSql(); $fields['modified_by'] = User::get('id'); } // Authorization check $this->_authorize($assetType, intval($fields['id'])); if (!$this->config->get('access-edit-' . $assetType) && !$this->config->get('access-create-' . $assetType)) { App::redirect(Route::url('index.php?option=' . $this->_option)); } // 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('COM_FORUM_ERROR_THREAD_CLOSED')); return $this->editTask($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('COM_FORUM_ERROR_CATEGORY_CLOSED')); return $this->editTask($post); } // Store new content if (!$post->save()) { Notify::error($post->getError()); return $this->editTask($post); } // Upload files if (!$this->uploadTask($post->get('thread', $post->get('id')), $post->get('id'))) { Notify::error($this->getError()); return $this->editTask($post); } // Save tags $post->tag(Request::getVar('tags', '', 'post'), User::get('id')); // Determine message if (!$fields['id']) { $message = Lang::txt('COM_FORUM_POST_ADDED'); if (!$fields['parent']) { $message = Lang::txt('COM_FORUM_THREAD_STARTED'); } } else { $message = $post->get('modified_by') ? Lang::txt('COM_FORUM_POST_EDITED') : Lang::txt('COM_FORUM_POST_ADDED'); } $url = 'index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category->get('alias') . '&thread=' . $post->get('thread') . '#c' . $post->get('id'); // Record the activity $recipients = array(['forum.site', 1], ['forum.section', $category->get('section_id')], ['user', $post->get('created_by')]); $type = 'thread'; $desc = Lang::txt('COM_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('COM_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, 'message'); }
/** * Saves posted data for a new/edited forum thread post * * @return void */ public function savethread() { // Check for request forgeries Request::checkToken(); // Must be logged in if (User::isGuest()) { App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($this->base, false, true)))); return; } // Incoming $section = Request::getVar('section', ''); $no_html = Request::getInt('no_html', 0); $fields = Request::getVar('fields', array(), 'post', 'none', 2); $fields = array_map('trim', $fields); // Check permissions $this->_authorize('thread', intval($fields['id'])); $asset = 'thread'; if ($fields['id'] && !$this->params->get('access-edit-thread') || !$fields['id'] && !$this->params->get('access-create-thread')) { App::redirect(Route::url($this->base), Lang::txt('You are not authorized to perform this action.'), 'warning'); return; } // Bind data $post = Post::oneOrNew($fields['id']); // Double comment? $double = Post::all()->whereEquals('object_id', $post->get('object_id'))->whereEquals('scope', $post->get('scope'))->whereEquals('scope_id', $post->get('scope_id'))->whereEquals('created_by', $post->get('created_by'))->whereEquals('comment', $post->get('comment'))->row(); if ($double->get('id')) { $post->set($double->toArray()); } $post->set($fields); // Load the category $category = Category::oneOrFail($post->get('category_id')); if (!$post->get('object_id') && $category->get('object_id')) { $post->set('object_id', $category->get('object_id')); } // Store new content if (!$post->save()) { Notify::error($post->getError()); return $this->editthread($post); } // Upload file 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')); $thread = $post->get('thread'); // Being called through AJAX? if ($no_html) { // Set the thread Request::setVar('thread', $thread); // Is this a new post in a thread or new thread entirely? if (!$post->get('parent')) { // New thread // Update the thread list and get the contents of the thread Request::setVar('action', 'both'); } else { // Get a list of new posts in the thread Request::setVar('action', 'posts'); } // If we have a lecture set, push through to the lecture view if (Request::getVar('group', '')) { $unit = $this->course->offering()->unit($category->get('alias')); $lecture = new \Components\Courses\Models\Assetgroup($post->get('object_id')); return $this->onCourseAfterLecture($this->course, $unit, $lecture); } else { // Display main panel return $this->panel(); } } $rtrn = base64_decode(Request::getVar('return', '', 'post')); if (!$rtrn) { $rtrn = Route::url($this->base . '&thread=' . $thread); } // Set the redirect App::redirect($rtrn, Lang::txt('Post successfully saved'), 'passed'); }
/** * Create a thread or post in a thread * * @apiMethod POST * @apiUri /forum * @apiParameter { * "name": "category_id", * "description": "Category ID", * "type": "integer", * "required": true, * "default": 0 * } * @apiParameter { * "name": "scope", * "description": "Scope type (site, group, etc.)", * "type": "string", * "required": true, * "default": "site" * } * @apiParameter { * "name": "scope_id", * "description": "Scope object ID", * "type": "integer", * "required": true, * "default": "0" * } * @apiParameter { * "name": "title", * "description": "Entry title", * "type": "string", * "required": false, * "default": null * } * @apiParameter { * "name": "comment", * "description": "Entry content", * "type": "string", * "required": true, * "default": null * } * @apiParameter { * "name": "created", * "description": "Created timestamp (YYYY-MM-DD HH:mm:ss)", * "type": "string", * "required": false, * "default": "now" * } * @apiParameter { * "name": "created_by", * "description": "User ID of entry creator", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "state", * "description": "Published state (0 = unpublished, 1 = published)", * "type": "integer", * "required": false, * "default": 1 * } * @apiParameter { * "name": "access", * "description": "Access level (1 = public, 2 = registered users, 5 = private)", * "type": "integer", * "required": false, * "default": 1 * } * @apiParameter { * "name": "anonymous", * "description": "Commentor is anonymous?", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "parent", * "description": "ID of the parent post this post is in reply to.", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "thread", * "description": "ID of the forum thread the post belongs to. 0 if new thread.", * "type": "string", * "required": false, * "default": 0 * } * @apiParameter { * "name": "sticky", * "description": "If the thread is sticky or not. Only applies to thread starter posts.", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "closed", * "description": "If the thread is closed (no more new posts) or not. Only applies to thread starter posts.", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "tags", * "description": "Comma-separated list of tags", * "type": "string", * "required": false, * "default": null * } * @return void */ public function createTask() { $this->requiresAuthentication(); $fields = array('category_id' => Request::getInt('category_id', 0, 'post'), 'title' => Request::getVar('title', null, 'post', 'none', 2), 'comment' => Request::getVar('comment', null, 'post', 'none', 2), 'created' => Request::getVar('created', new Date('now'), 'post'), 'created_by' => Request::getInt('created_by', 0, 'post'), 'state' => Request::getInt('state', Post::STATE_PUBLISHED, 'post'), 'sticky' => Request::getInt('sticky', 0, 'post'), 'parent' => Request::getInt('parent', 0, 'post'), 'scope' => Request::getVar('scope', 'site', 'post'), 'scope_id' => Request::getInt('scope_id', 0, 'post'), 'access' => Request::getInt('access', Post::ACCESS_PUBLIC, 'post'), 'anonymous' => Request::getInt('anonymous', 0, 'post'), 'thread' => Request::getInt('thread', 0, 'post'), 'closed' => Request::getInt('closed', 0, 'post'), 'hits' => Request::getInt('hits', 0, 'post')); if (!$fields['category_id']) { throw new Exception(Lang::txt('COM_FORUM_ERROR_CATEGORY_ID_MISSING'), 400); } $row = Post::blank(); if (!$row->set($fields)) { throw new Exception(Lang::txt('COM_FORUM_ERROR_BINDING_DATA'), 500); } $row->set('anonymous', $fields['anonymous'] ? 1 : 0); $category = Category::all()->whereEquals('id', $row->get('category_id'))->whereEquals('scope', $row->get('scope'))->whereEquals('scope_id', $row->get('scope_id'))->where('state', '!=', Category::STATE_DELETED)->row(); if (!$category->get('id')) { throw new Exception(Lang::txt('COM_FORUM_ERROR_CATEGORY_NOT_FOUND'), 400); } if (!$row->save()) { throw new Exception(Lang::txt('COM_FORUM_ERROR_SAVING_DATA'), 500); } if ($fields['created_by']) { $row->set('created_by', (int) $fields['created_by']); $row->save(); } if ($tags = Request::getVar('tags', null, 'post')) { if (!$row->tag($tags, User::get('id'))) { throw new Exception(Lang::txt('COM_FORUM_ERROR_SAVING_TAGS'), 500); } } // Record the activity $base = rtrim(Request::base(), '/'); $url = str_replace('/api', '', $base . '/' . ltrim(Route::url($row->link()), '/')); $recipients = array(['forum.site', 1], ['forum.section', $category->get('section_id')], ['user', $row->get('created_by')]); $type = 'thread'; $desc = Lang::txt('COM_FORUM_ACTIVITY_' . strtoupper($type) . '_CREATED', '<a href="' . $url . '">' . $row->get('title') . '</a>'); // If this is a post in a thread and not the thread starter... if ($row->get('parent')) { $thread = Post::oneOrFail($row->get('thread')); $thread->set('last_activity', $fields['id'] ? $row->get('modified') : $row->get('created')); $thread->save(); $type = 'post'; $desc = Lang::txt('COM_FORUM_ACTIVITY_' . strtoupper($type) . '_CREATED', $row->get('id'), '<a href="' . $url . '">' . $thread->get('title') . '</a>'); // If the parent post is not the same as the // thread starter (i.e., this is a reply) if ($row->get('parent') != $row->get('thread')) { $parent = Post::oneOrFail($row->get('parent')); $recipients[] = ['user', $parent->get('created_by')]; } } Event::trigger('system.logActivity', ['activity' => ['action' => 'created', 'scope' => 'forum.' . $type, 'scope_id' => $row->get('id'), 'anonymous' => $row->get('anonymous', 0), 'description' => $desc, 'details' => array('thread' => $row->get('thread'), 'url' => $url)], 'recipients' => $recipients]); $obj = $row->toObject(); $obj->creator = new stdClass(); $obj->creator->id = 0; $obj->creator->name = Lang::txt('COM_FORUM_ANONYMOUS'); if (!$row->get('anonymous')) { $obj->creator->id = $row->get('created_by'); $obj->creator->name = $row->creator->get('name'); } $this->send($obj); }
/** * Delete a category * * @return void */ public function deleteTask() { $url = 'index.php?option=' . $this->_option; // Is the user logged in? if (User::isGuest()) { App::redirect(Route::url('index.php?option=com_users&view=login&return=' . base64_encode(Route::url($url, false, true))), Lang::txt('COM_FORUM_LOGIN_NOTICE'), 'warning'); } // Load the category $category = Category::all()->whereEquals('alias', Request::getVar('category', ''))->whereEquals('scope', $this->forum->get('scope'))->whereEquals('scope_id', $this->forum->get('scope_id'))->where('state', '!=', Category::STATE_DELETED)->row(); // Make the sure the category exist if (!$category->get('id')) { App::redirect(Route::url($url), Lang::txt('COM_FORUM_MISSING_ID'), 'error'); } // Check if user is authorized to delete entries $this->_authorize('category', $category->get('id')); if (!$this->config->get('access-delete-category')) { App::redirect(Route::url($url), Lang::txt('COM_FORUM_NOT_AUTHORIZED'), 'warning'); } // Set the category to "deleted" $category->set('state', $category::STATE_DELETED); if (!$category->save()) { App::redirect(Route::url($url), $category->getError(), 'error'); } // Log activity Event::trigger('system.logActivity', ['activity' => ['action' => 'deleted', 'scope' => 'forum.category', 'scope_id' => $category->get('id'), 'description' => Lang::txt('COM_FORUM_ACTIVITY_CATEGORY_DELETED', '<a href="' . Route::url($url) . '">' . $category->get('title') . '</a>'), 'details' => array('title' => $category->get('title'), 'url' => Route::url($url))], 'recipients' => array(['forum.site', 1], ['forum.section', $category->get('section_id')], ['user', $category->get('created_by')])]); // Redirect to main listing App::redirect(Route::url($url), Lang::txt('COM_FORUM_CATEGORY_DELETED'), 'message'); }
/** * 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'); }