/** * Grabs the post for a given set of groups over a certain period of time * * @param array $groups the group ids to look up * @param string $interval the length of time to go back to look for posts * @return array **/ private function getPosts($groups, $interval = 'day') { $return = []; if ($groups && count($groups) > 0) { foreach ($groups as $group) { $results = \Components\Forum\Models\Post::all()->whereEquals('scope', 'group')->whereEquals('scope_id', $group)->whereEquals('state', 1)->where('created', '>', Date::of(strtotime("now -1 {$interval}"))->toSql())->order('created', 'desc')->limit(10)->rows(); if ($results->count() > 0) { $return[$group] = $results; } } } return $return; }
/** * Create an item entry for a forum thread * * @param integer $id Optional ID to use * @return boolean */ public function make($id = null) { if ($this->exists()) { return true; } $id = $id ?: Request::getInt('thread', 0); $this->_tbl->loadType($id, $this->_type); if ($this->exists()) { return true; } include_once PATH_CORE . DS . 'components' . DS . 'com_forum' . DS . 'models' . DS . 'post.php'; $thread = new Post($id); if (!$thread->exists()) { $this->setError(Lang::txt('Forum thread not found.')); return false; } $this->set('type', $this->_type)->set('object_id', $thread->get('id'))->set('created', $thread->get('created'))->set('created_by', $thread->get('created_by'))->set('title', $thread->get('title'))->set('description', $thread->content('clean', 200))->set('url', $thread->link()); if (!$this->store()) { return false; } return true; }
</span> <span class="category-discussions count"><?php echo $threads->count(); ?> </span> </div><!-- / .category-header --> <div class="category-content"> <?php $this->view('_threads')->set('category', 'categoryreplies')->set('option', $this->option)->set('threads', $threads)->set('unit', '')->set('lecture', 0)->set('config', $this->config)->set('instructors', $instructors)->set('cls', 'odd')->set('base', $base)->set('course', $this->course)->set('prfx', 'mine')->set('active', $this->thread)->display(); ?> </div><!-- / .category-content --> </div><!-- / .category --> <div class="category category-results closed" id="newcomments"> <?php $threads = \Components\Forum\Models\Post::all()->whereEquals('scope', $this->filters['scope'])->whereEquals('scope_id', $this->filters['scope_id'])->whereEquals('scope_sub_id', $this->filters['scope_sub_id'])->whereEquals('state', \Components\Forum\Models\Post::STATE_PUBLISHED)->order('created', 'desc')->limit(100)->rows(); ?> <div class="category-header"> <span class="category-title"><?php echo Lang::txt('PLG_COURSES_DISCUSSIONS_LATEST_COMMENTS'); ?> </span> <span class="category-discussions count"><?php echo $threads->count(); ?> </span> </div><!-- / .category-header --> <div class="category-content"> <?php $this->view('_threads')->set('category', 'categorynew')->set('option', $this->option)->set('threads', $threads)->set('unit', '')->set('lecture', 0)->set('config', $this->config)->set('instructors', $instructors)->set('cls', 'odd')->set('base', $base)->set('course', $this->course)->set('prfx', 'new')->set('active', $this->thread)->display(); ?>
/** * Static method for formatting results * * @param object $row Database row * @return string HTML */ public static function out($row) { include_once Component::path('com_forum') . DS . 'models' . DS . 'post.php'; $row->scope = $row->rcount; $row->scope_id = $row->data3; $row->section = $row->data2; $row->category = $row->data1; $p = explode(':', $row->params); $row->thread = $p[0]; $row->parent = $p[1]; $row->comment = $row->ftext; $view = new \Hubzero\Plugin\View(array('folder' => 'tags', 'element' => 'forum', 'name' => 'result')); $view->post = \Components\Forum\Models\Post::blank()->set(array('id' => $row->id, 'title' => $row->title, 'alias' => $row->alias, 'comment' => $row->comment, 'state' => $row->state, 'created' => $row->created, 'created_by' => $row->created_by, 'scope' => $row->rcount, 'scope_id' => $row->data3, 'thread' => $row->thread, 'parent' => $row->parent, 'section' => $row->data2, 'category' => $row->data1)); return $view->loadTemplate(); }
/** * 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(); }
/** * 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'); }
/** * Get a list of posts in this thread * * @param string $rtrn What data to return? * @param array $filters Filters to apply to data fetch * @param boolean $clear Clear cached data? * @return mixed */ public function posts($rtrn = 'list', $filters = array(), $clear = false) { $filters['thread'] = isset($filters['thread']) ? $filters['thread'] : $this->get('thread'); $filters['state'] = isset($filters['state']) ? $filters['state'] : array(self::APP_STATE_PUBLISHED, self::APP_STATE_FLAGGED); switch (strtolower($rtrn)) { case 'count': if (!isset($this->_cache['posts_count']) || $clear) { $this->_cache['posts_count'] = $this->_tbl->getCount($filters); } return $this->_cache['posts_count']; break; case 'first': return $this->posts('list', $filters)->first(); break; case 'tree': if (!$this->_cache['tree'] instanceof ItemList || $clear) { if ($rows = $this->_tbl->getTree($filters['thread'])) { $children = array(0 => array()); $levellimit = $filters['limit'] == 0 ? 500 : $filters['limit']; foreach ($rows as $row) { $v = new Post($row); $v->set('category', $this->get('category')); $v->set('section', $this->get('section')); $pt = $v->get('parent'); $list = @$children[$pt] ? $children[$pt] : array(); array_push($list, $v); $children[$pt] = $list; } $results = $this->_treeRecurse($children[$this->get('parent')], $children); } $this->_cache['tree'] = new ItemList($results); } return $this->_cache['tree']; break; case 'list': case 'results': default: if (!$this->_cache['posts'] instanceof ItemList || $clear) { if ($results = $this->_tbl->getRecords($filters)) { foreach ($results as $key => $result) { $results[$key] = new Post($result); $results[$key]->set('category', $this->get('category')); $results[$key]->set('section', $this->get('section')); } } else { $results = array(); } $this->_cache['posts'] = new ItemList($results); } return $this->_cache['posts']; break; } }
/** * 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 ''; }
total <?php echo $this->latest_cnt; ?> new ======================= Latest Discussions: <?php if (count($this->latest) > 0) { foreach ($this->latest as $post) { ?> ---------------------------------------- <?php $postObj = \Components\Forum\Models\Post::getInstance($post->id); echo User::getInstance($post->created_by)->get('name'); ?> | created: <?php echo Date::of($post->created)->toLocal('M j, Y g:i:s a') . "\n"; echo $postObj->content('raw') . "\n"; ?> ---------------------------------------- <?php } } else { ?> No new comments to display <?php
/** * Email instructor course digest * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function emailInstructorDigest(\Components\Cron\Models\Job $job) { $database = \App::get('db'); $cconfig = Component::params('com_courses'); Lang::load('com_courses') || Lang::load('com_courses', PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'site'); $from = array('name' => Config::get('sitename') . ' ' . Lang::txt('COM_COURSES'), 'email' => Config::get('mailfrom')); $subject = Lang::txt('COM_COURSES') . ': ' . Lang::txt('COM_COURSES_SUBJECT_EMAIL_DIGEST'); require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'courses.php'; $course_id = 0; $params = $job->params; if (isset($params) && is_object($params)) { $course_id = $params->get('course'); } $coursesObj = new \Components\Courses\Models\Courses(); if ($course_id) { $courses = array($coursesObj->course($course_id)); } else { $courses = $coursesObj->courses(); } if (isset($courses) && count($courses) > 0) { foreach ($courses as $course) { if (!$course->isAvailable()) { continue; } $mailed = array(); $managers = $course->managers(); $enrollments = $course->students(array('count' => true)); $offerings = $course->offerings(); if (isset($offerings) && count($offerings) > 0) { foreach ($offerings as $offering) { if (!$offering->isAvailable()) { continue; } $offering->gradebook()->refresh(); $passing = $offering->gradebook()->countPassing(false); $failing = $offering->gradebook()->countFailing(false); if (isset($managers) && count($managers) > 0) { require_once PATH_CORE . DS . 'components' . DS . 'com_forum' . DS . 'models' . DS . 'manager.php'; foreach ($managers as $manager) { // Get the user's account $user = User::getInstance($manager->get('user_id')); if (!$user->get('id')) { continue; } // Try to ensure no duplicates if (in_array($user->get('username'), $mailed)) { continue; } // Only mail instructors (i.e. not managers) if ($manager->get('role_alias') != 'instructor') { continue; } // Get discussion stats and posts $posts = \Components\Forum\Models\Post::all()->whereEquals('scope', 'course')->whereEquals('scope_id', $offering->get('id'))->whereEquals('state', \Components\Forum\Models\Post::STATE_PUBLISHED)->order('created', 'desc')->limit(100)->rows(); $posts_cnt = $posts->count(); $latest = array(); $latest_cnt = 0; if (isset($posts) && $posts_cnt > 0) { foreach ($posts as $post) { if (strtotime($post->created) > strtotime('-1 day')) { $latest[] = $post; } else { break; } } $latest_cnt = count($latest); } $eview = new \Hubzero\Component\View(array('base_path' => PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'site', 'name' => 'emails', 'layout' => 'digest_plain')); $eview->option = 'com_courses'; $eview->controller = 'courses'; $eview->delimiter = '~!~!~!~!~!~!~!~!~!~!'; $eview->course = $course; $eview->enrollments = $enrollments; $eview->passing = $passing; $eview->failing = $failing; $eview->offering = $offering; $eview->posts_cnt = $posts_cnt; $eview->latest = $latest; $eview->latest_cnt = $latest_cnt; $plain = $eview->loadTemplate(); $plain = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('digest_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // Build message $message = new \Hubzero\Mail\Message(); $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($user->get('email'), $user->get('name'))->addHeader('X-Component', 'com_courses')->addHeader('X-Component-Object', 'courses_instructor_digest'); $message->addPart($plain, 'text/plain'); $message->addPart($html, 'text/html'); // Send mail if (!$message->send()) { $this->setError('Failed to mail %s', $user->get('email')); } $mailed[] = $user->get('username'); } } } } } } return true; }
echo $threads->count(); ?> </span> </div><!-- / .category-header --> <div class="category-content"> <?php $this->view('_threads', 'threads')->set('category', 'categorymine')->set('option', $this->option)->set('threads', $threads)->set('unit', '')->set('lecture', 0)->set('config', $this->config)->set('instructors', $instructors)->set('cls', 'odd')->set('base', $base)->set('course', $this->course)->set('prfx', 'mine')->set('active', $this->thread)->display(); ?> </div><!-- / .category-content --> </div><!-- / .category --> <?php if (count($this->sections) > 0) { ?> <?php $threads = array(); $posts = \Components\Forum\Models\Post::all()->whereEquals('scope', $this->filters['scope'])->whereEquals('scope_id', $this->filters['scope_id'])->whereEquals('state', \Components\Forum\Models\Post::STATE_PUBLISHED)->whereEquals('parent', 0); if ($this->config->get('discussions_threads', 'all') != 'all') { $posts->whereEquals('scope_sub_id', $this->filters['scope_sub_id']); } $results = $posts->order('created', 'desc')->limit(100 * count($this->sections))->rows(); if ($results->count()) { foreach ($results as $thread) { if (!isset($threads[$thread->get('category_id')])) { $threads[$thread->get('category_id')] = array(); } $threads[$thread->get('category_id')][] = $thread; } } ?> <?php foreach ($this->sections as $section) {
/** * Get the most recent post made in the forum * * @return object */ public function lastActivity() { $last = Post::all()->whereEquals('scope', $this->get('scope'))->whereEquals('scope_id', $this->get('scope_id'))->whereEquals('state', Post::STATE_PUBLISHED)->whereIn('access', User::getAuthorisedViewLevels()); return $last->order('id', 'desc')->limit(1)->row(); }
/** * 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'); } }
/** * Retrieve a thread * * @apiMethod GET * @apiUri /forum/{thread} * @apiParameter { * "name": "id", * "description": "Thread identifier", * "type": "integer", * "required": true, * "default": 0 * } * @apiParameter { * "name": "limit", * "description": "Number of result to return.", * "type": "integer", * "required": false, * "default": 25 * } * @apiParameter { * "name": "limitstart", * "description": "Number of where to start returning results.", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "section", * "description": "Section alias to filter by", * "type": "string", * "required": false, * "default": "" * } * @apiParameter { * "name": "category", * "description": "Category alias to filter by", * "type": "string", * "required": false, * "default": "" * } * @apiParameter { * "name": "state", * "description": "Published state (0 = unpublished, 1 = published)", * "type": "integer", * "required": false, * "default": 1 * } * @apiParameter { * "name": "scope", * "description": "Scope (site, groups, members, etc.)", * "type": "string", * "required": false, * "default": "site" * } * @apiParameter { * "name": "scope_id", * "description": "Scope ID", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "scope_sub_id", * "description": "Scope sub-ID", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "object_id", * "description": "Object ID", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "start_id", * "description": "ID of record to start with", * "type": "integer", * "required": false, * "default": 0 * } * @apiParameter { * "name": "start_at", * "description": "Start timestamp (YYYY-MM-DD HH:mm:ss)", * "type": "string", * "required": false, * "default": "" * } * @apiParameter { * "name": "sort", * "description": "Field to sort results by.", * "type": "string", * "required": false, * "default": "newest", * "allowedValues": "newest, oldest" * } * @return void */ public function readTask() { $find = strtolower(Request::getWord('find', 'results')); $filters = array('limit' => Request::getInt('limit', Config::get('list_limit', 25)), 'start' => Request::getInt('limitstart', 0), 'section' => Request::getCmd('section', ''), 'category' => Request::getCmd('category', ''), 'state' => Request::getInt('state', Post::STATE_PUBLISHED), 'scope' => Request::getWord('scope', ''), 'scope_id' => Request::getInt('scope_id', 0), 'scope_sub_id' => Request::getInt('scope_sub_id', 0), 'object_id' => Request::getInt('object_id', 0), 'start_id' => Request::getInt('start_id', 0), 'start_at' => Request::getVar('start_at', ''), 'sticky' => false); $forum = new Manager($filters['scope'], $filters['scope_id']); if ($thread = Request::getInt('thread', 0)) { $filters['thread'] = $thread; } $sort = Request::getVar('sort', 'newest'); switch ($sort) { case 'oldest': $filters['sort_Dir'] = 'ASC'; break; case 'newest': default: $filters['sort_Dir'] = 'DESC'; break; } $filters['sort'] = 'c.created'; if ($filters['start_id']) { $filters['limit'] = 0; $filters['start'] = 0; } $data = new stdClass(); $data->code = 0; if ($find == 'count') { $data->count = 0; $data->threads = 0; if (isset($filters['thread'])) { $data->count = $forum->posts($filters)->total(); } $post = Post::all()->whereEquals('object_id', $filters['object_id'])->whereEquals('scope_id', $filters['scope_id'])->whereEquals('scope', $filters['scope'])->row(); if ($post->get('id')) { $filters['start_at'] = Request::getVar('threads_start', ''); $filters['parent'] = 0; } $data->threads = $forum->posts($filters)->total(); } else { $rows = $forum->posts($filters)->rows(); if ($rows) { if ($filters['start_id']) { $filters['limit'] = Request::getInt('limit', Config::get('list_limit')); $children = array(0 => array()); $levellimit = $filters['limit'] == 0 ? 500 : $filters['limit']; foreach ($rows as $v) { $v->set('created', with(new Date($v->get('created')))->format('Y-m-d\\TH:i:s\\Z')); $pt = $v->get('parent'); $list = @$children[$pt] ? $children[$pt] : array(); array_push($list, $v); $children[$pt] = $list; } $list = $this->treeRecurse($post->get('id'), '', array(), $children, max(0, $levellimit - 1)); $inc = false; $newlist = array(); foreach ($list as $l) { if ($l->id == $filters['start_id']) { $inc = true; } else { if ($inc) { $newlist[] = $l; } } } $rows = array_slice($newlist, $filters['start'], $filters['limit']); } } $data->response = $rows; } $this->send($data); }
/** * 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; }