/** * 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; }
/** * 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(); }
</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(); ?>
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) {
/** * 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; }
/** * 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(); }
/** * 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'); }
/** * 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); }