/** * 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 $access = Request::getInt('access', 0); $ids = Request::getVar('id', array()); $ids = !is_array($ids) ? array($ids) : $ids; // Loop through each record $i = 0; foreach ($ids as $id) { // Update record(s) $post = Post::oneOrFail(intval($id)); $post->set('access', $access); if (!$post->save()) { Notify::error($post->getError()); continue; } $i++; } // Set message if ($i) { Notify::success(Lang::txt('COM_FORUM_ITEMS_ACCESS_CHANGED', $i)); } $this->cancelTask(); }
/** * Retrieves a row from the database * * @param string $refid ID of the database table row * @param string $parent If the element has a parent element * @param string $category Element type (determines table to look in) * @param string $message If the element has a parent element * @return array */ public function deleteReportedItem($refid, $parent, $category, $message) { if ($category != 'forum') { return null; } require_once PATH_CORE . DS . 'components' . DS . 'com_forum' . DS . 'models' . DS . 'post.php'; $comment = \Components\Forum\Models\Post::oneOrFail($refid); $comment->set('state', $comment::STATE_DELETED); $comment->save(); return ''; }
/** * Delete an entry * * @return void */ public function deleteTask() { $section = Request::getVar('section', ''); $category = Request::getVar('category', ''); // Is the user logged in? if (User::isGuest()) { App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category), Lang::txt('COM_FORUM_LOGIN_NOTICE'), 'warning'); } // Incoming $id = Request::getInt('thread', 0); // Load the post $post = Post::oneOrFail($id); // Make the sure the category exist if (!$post->get('id')) { App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category), Lang::txt('COM_FORUM_MISSING_ID'), 'error'); } // Check if user is authorized to delete entries $this->_authorize('thread', $id); if (!$this->config->get('access-delete-thread')) { App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category), Lang::txt('COM_FORUM_NOT_AUTHORIZED'), 'warning'); } // Trash the post // Note: this will carry through to all replies // and attachments $post->set('state', $post::STATE_DELETED); if (!$post->save()) { App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category), $post->getError(), 'error'); } // Record the activity $url = $post->link(); $type = 'thread'; $desc = Lang::txt('COM_FORUM_ACTIVITY_' . strtoupper($type) . '_DELETED', '<a href="' . Route::url($url) . '">' . $post->get('title') . '</a>'); if ($post->get('parent')) { $thread = Post::oneOrFail($post->get('thread')); $type = 'post'; $desc = Lang::txt('COM_FORUM_ACTIVITY_' . strtoupper($type) . '_DELETED', $post->get('id'), '<a href="' . Route::url($url) . '">' . $thread->get('title') . '</a>'); } Event::trigger('system.logActivity', ['activity' => ['action' => 'deleted', 'scope' => 'forum.' . $type, 'scope_id' => $post->get('id'), 'description' => $desc, 'details' => array('thread' => $post->get('thread'), 'url' => Route::url($url))], 'recipients' => array(['forum.site', 1], ['user', $post->get('created_by')])]); // Redirect to main listing App::redirect(Route::url('index.php?option=' . $this->_option . '§ion=' . $section . '&category=' . $category), Lang::txt('COM_FORUM_THREAD_DELETED'), 'message'); }
/** * Remove a thread * * @param integer $id * @param boolean $redirect * @return void */ public function deletethread($id = 0, $redirect = true) { $section = Request::getVar('section', ''); $category = Request::getVar('category', ''); // Is the user logged in? if (User::isGuest()) { App::redirect(Route::url($this->base), Lang::txt('PLG_COURSES_DISCUSSIONS_LOGIN_NOTICE'), 'warning'); return; } // Incoming $id = $id ? $id : Request::getInt('thread', 0); // Load the post $post = Post::oneOrFail($id); // Make the sure the category exist if (!$post->get('id')) { App::redirect(Route::url($this->base), Lang::txt('PLG_COURSES_DISCUSSIONS_MISSING_ID'), 'error'); return; } // Check if user is authorized to delete entries $this->_authorize('thread', $id); if (!$this->params->get('access-delete-thread')) { App::redirect(Route::url($this->base), Lang::txt('PLG_COURSES_DISCUSSIONS_NOT_AUTHORIZED'), 'warning'); return; } // Trash the post // Note: this will carry through to all replies // and attachments $post->set('state', $post::STATE_DELETED); if (!$post->save()) { App::redirect(Route::url($this->base), $forum->getError(), 'error'); return; } // Redirect to main listing if ($redirect) { App::redirect(Route::url($this->base), Lang::txt('PLG_COURSES_DISCUSSIONS_THREAD_DELETED'), '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); }
/** * Serves up files only after passing access checks * * @return void */ public function download() { // Incoming $section = Request::getVar('section', ''); $category = Request::getVar('category', ''); $thread = Request::getInt('thread', 0); $post = Request::getInt('post', 0); $file = Request::getVar('file', ''); // Check logged in status // Login check is handled in the onGroup() method /*if (User::isGuest()) { $return = Route::url('index.php?option=' . $this->option . '&cn=' . $this->group->get('cn') . '&active=forum&scope=' . $section . '/' . $category . '/' . $thread . '/' . $post . '/' . $file); App::redirect( Route::url('index.php?option=com_users&view=login&return=' . base64_encode($return)) ); return; }*/ // Instantiate an attachment object if (!$post) { $attach = Attachment::oneByThread($thread, $file); } else { $attach = Attachment::oneByPost($post); } if (!$attach->get('filename')) { App::abort(404, Lang::txt('PLG_GROUPS_FORUM_FILE_NOT_FOUND')); } // Get the parent ticket the file is attached to $post = $attach->post(); if (!$post->get('id') || $post->get('state') == $post::STATE_DELETED) { App::abort(404, Lang::txt('PLG_GROUPS_FORUM_POST_NOT_FOUND')); } // Load ACL $this->_authorize('thread', $post->get('thread')); // Ensure the user is authorized to view this file if (!$this->params->get('access-view-thread')) { $thread = Post::oneOrFail($post->get('thread')); if (!in_array($thread->get('access'), User::getAuthorisedViewLevels())) { App::abort(403, Lang::txt('PLG_GROUPS_FORUM_NOT_AUTH_FILE')); } } // Get the configured upload path $filename = $attach->path(); // Ensure the file exist if (!file_exists($filename)) { App::abort(404, Lang::txt('PLG_GROUPS_FORUM_FILE_NOT_FOUND') . ' ' . substr($filename, strlen(PATH_ROOT))); } // Initiate a new content server and serve up the file $server = new \Hubzero\Content\Server(); $server->filename($filename); $server->disposition('inline'); $server->acceptranges(false); // @TODO fix byte range support if (!$server->serve()) { // Should only get here on error App::abort(500, Lang::txt('PLG_GROUPS_FORUM_SERVER_ERROR')); } exit; }