public function handle() { require_once PATH_CORE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Memberships.php'; $ms = new \Components\Storefront\Models\Memberships(); // Get current registration $membership = $ms->getMembershipInfo($this->crtId, $this->item['info']->pId); $expiration = $membership['crtmExpires']; // Get course ID $courseId = $this->item['meta']['courseId']; // Get user ID for the cart require_once dirname(dirname(dirname(__DIR__))) . DS . 'models' . DS . 'Cart.php'; $userId = \Components\Cart\Models\Cart::getCartUser($this->crtId); // Load courses model and register // registerForCourse($userId, $courseId, $expiration); require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'course.php'; $course = \Components\Courses\Models\Course::getInstance($this->item['meta']['courseId']); if (!$course->offerings()->count()) { // error enrolling } else { // Get to the first and probably the only offering //$offering = $course->offerings()->current(); $offering = $course->offering($this->item['meta']['offeringId']); $offering->add($userId); //$offering->remove($userId); } }
/** * Displays a list of courses * * @return void */ public function displayTask() { // Incoming $this->view->filters = array('unit' => Request::getState($this->_option . '.' . $this->_controller . '.unit', 'unit', 0), 'search' => urldecode(Request::getState($this->_option . '.' . $this->_controller . '.search', 'search', '')), 'state' => Request::getState($this->_option . '.' . $this->_controller . '.state', 'state', '-1'), 'limit' => Request::getState($this->_option . '.' . $this->_controller . '.limit', 'limit', Config::get('list_limit'), 'int'), 'start' => Request::getState($this->_option . '.' . $this->_controller . '.limitstart', 'limitstart', 0, 'int')); $this->view->unit = \Components\Courses\Models\Unit::getInstance($this->view->filters['unit']); if (!$this->view->unit->exists()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=courses', false)); return; } $this->view->offering = \Components\Courses\Models\Offering::getInstance($this->view->unit->get('offering_id')); $this->view->course = \Components\Courses\Models\Course::getInstance($this->view->offering->get('course_id')); $rows = $this->view->unit->assetgroups(null, $this->view->filters); // establish the hierarchy of the menu $children = array(0 => array()); $levellimit = $this->view->filters['limit'] == 0 ? 500 : $this->view->filters['limit']; // first pass - collect children foreach ($rows as $v) { $children[0][] = $v; $children[$v->get('id')] = $v->children(); } // second pass - get an indent list of the items $list = $this->treeRecurse(0, '', array(), $children, max(0, $levellimit - 1)); $this->view->total = count($list); $this->view->rows = array_slice($list, $this->view->filters['start'], $this->view->filters['limit']); // Set any errors foreach ($this->getErrors() as $error) { $this->view->setError($error); } // Output the HTML $this->view->display(); }
/** * Generate and return various links to the entry * Link will vary depending upon action desired, such as edit, delete, etc. * * @param string $type The type of link to return * @return string */ public function link($type = '') { if (!isset($this->_base)) { if (!$this->get('course')) { $course = Course::getInstance($this->get('item_id')); $this->set('course', $course->get('alias')); } $this->_base = 'index.php?option=com_courses&gid=' . $this->get('course') . '&active=reviews'; } $link = $this->_base; // If it doesn't exist or isn't published switch (strtolower($type)) { case 'edit': $link .= '&action=edit&comment=' . $this->get('id'); break; case 'delete': $link .= '&action=delete&comment=' . $this->get('id'); break; case 'reply': $link .= '&action=reply&comment=' . $this->get('id'); break; case 'report': $link = 'index.php?option=com_support&task=reportabuse&category=itemcomment&id=' . $this->get('id') . '&parent=' . $this->get('item_id'); break; case 'permalink': default: $link .= '#c' . $this->get('id'); break; } return $link; }
/** * Displays a list of courses * * @return void */ public function displayTask() { $course = Course::getInstance(Request::getVar('course', '')); $offering = $course->offering(Request::getVar('offering', '')); // Ensure the course exists if (!$course->exists() || !$offering->exists()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=courses'), Lang::txt('COM_COURSES_ERROR_COURSE_OR_OFFERING_NOT_FOUND'), 'error'); return; } // Ensure specified user is enrolled in the course //$student = $offering->member(User::get('id')); $student = Member::getInstance(User::get('id'), $course->get('id'), $offering->get('id'), null, 1); if (!$student->exists()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=courses'), Lang::txt('COM_COURSES_ERROR_STUDENT_RECORD_NOT_FOUND'), 'error'); return; } $certificate = $course->certificate(); if (!$certificate->exists() || !$certificate->hasFile()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=courses'), Lang::txt('COM_COURSES_ERROR_NO_CERTIFICATE_FOR_COURSE'), 'error'); return; } // Path and file name $dir = PATH_APP . DS . 'site' . DS . 'courses' . DS . 'certificates'; $file = $dir . DS . 'certificate_' . $course->get('id') . '_' . $offering->get('id') . '_' . User::get('id') . '.pdf'; // If the file exists and we want to force regenerate it if (is_file($file) && Request::getInt('regenerate', 0)) { if (!Filesystem::delete($file)) { throw new Exception(Lang::txt('UNABLE_TO_DELETE_FILE'), 500); } } // Does the file exist already? if (!is_file($file)) { // Create the upload directory if needed if (!is_dir($dir)) { if (!Filesystem::makeDirectory($dir)) { throw new Exception(Lang::txt('COM_COURSES_ERROR_FAILED_TO_CREATE_DIRECTORY'), 500); } } $certificate->render(User::getRoot(), $file); } // If file exists if (is_file($file)) { $student->token(); // Serve up the file $xserver = new Server(); $xserver->filename($file); $xserver->serve_attachment($file); // Firefox and Chrome fail if served inline exit; } // Output failure message $this->view->display(); }
/** * Constructor * * @param integer $scope_id Scope ID (group, course, etc.) * @return void */ public function __construct($scope_id = 0) { $this->set('scope_id', $scope_id); include_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'courses.php'; $offering = \Components\Courses\Models\Offering::getInstance($this->get('scope_id')); $course = \Components\Courses\Models\Course::getInstance($offering->get('course_id')); $this->_segments['gid'] = $course->get('alias'); $this->_segments['offering'] = $offering->alias(); $this->_segments['active'] = 'discussions'; if (Request::getVar('active') == 'outline') { $this->_segments['active'] = 'outline'; } $this->_name = String::truncate($course->get('alias'), 50) . ': ' . String::truncate($offering->get('alias'), 50); }
/** * Retrieves a row from the database * * @param string $refid ID of the database table row * @param string $category Element type (determines table to look in) * @param string $parent If the element has a parent element * @return array */ public function getReportedItem($refid, $category, $parent) { if (!in_array($category, array('wishcomment', 'answercomment', 'reviewcomment', 'citations', 'citationscomment', 'collection', 'itemcomment', 'coursescomment'))) { return null; } $query = "SELECT rc.`id`, rc.`content` as `text`, rc.`created_by` as `author`, rc.`created`, NULL as `subject`, rc.`anonymous` as `anon`, concat(rc.`item_type`, 'comment') AS `parent_category`, NULL AS `href` " . "FROM #__item_comments AS rc " . "WHERE rc.id=" . $refid; $database = App::get('db'); $database->setQuery($query); if ($rows = $database->loadObjectList()) { if ($parent) { foreach ($rows as $key => $row) { if (preg_match('/^<!-- \\{FORMAT:(.*)\\} -->/i', $row->text, $matches)) { $rows[$key]->text = preg_replace('/^(<!-- \\{FORMAT:.*\\} -->)/i', '', $row->text); } switch ($row->parent_category) { case 'collection': $rows[$key]->href = Route::url('index.php?option=com_collections&controller=posts&post=' . $parent); break; case 'coursescomment': require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'course.php'; $course = \Components\Courses\Models\Course::getInstance($parent); $rows[$key]->href = Route::url($course->link() . '&active=reviews'); break; case 'citations': case 'citationscomment': $rows[$key]->href = Route::url('index.php?option=com_citations&task=view&id=' . $parent . '&area=reviews'); break; case 'review': case 'reviewcomment': $rows[$key]->href = Route::url('index.php?option=com_resources&id=' . $parent . '&active=reviews'); break; case 'pubreview': case 'pubreviewcomment': $rows[$key]->href = Route::url('index.php?option=com_publications&id=' . $parent . '&active=reviews'); break; case 'answer': case 'answercomment': $rows[$key]->href = Route::url('index.php?option=com_answers&task=question&id=' . $parent); break; case 'wish': case 'wishcomment': $rows[$key]->href = Route::url('index.php?option=com_wishlist&task=wish&wishid=' . $parent); break; } } } } return $rows; }
/** * Checks to ensure appropriate authorization * * @return bool * @throws Exception */ protected function authorizeOrFail($action = 'manage') { // Make sure we have a valid user $this->requiresAuthentication(); // Get the course id $this->course_id = Request::getInt('course_id', 0); $this->offering_alias = Request::getCmd('offering', ''); $this->section_id = Request::getInt('section_id', ''); // Load the course page $course = Course::getInstance($this->course_id); $offering = $course->offering($this->offering_alias); $section = $course->offering()->section($this->section_id); if (!$course->access($action)) { App::abort(401, 'Unauthorized'); } // Set the course for reuse later $this->course = $course; return true; }
/** * Get items reported as abusive * * @param integer $refid Comment ID * @param string $category Item type (kb) * @param integer $parent Parent ID * @return array */ public function getReportedItem($refid, $category, $parent) { if ($category != 'forum') { return null; } $query = "SELECT rc.id, rc.comment as `text`, rc.parent, rc.created_by as author, rc.created, rc.title as subject, rc.anonymous as anon, 'forum' AS parent_category,\n\t\t\t\t\ts.alias AS section, c.alias AS category, rc.scope, rc.scope_id, rc.object_id, rc.thread\n\t\t\t\t\tFROM `#__forum_posts` AS rc\n\t\t\t\t\tLEFT JOIN `#__forum_categories` AS c ON c.id = rc.category_id\n\t\t\t\t\tLEFT JOIN `#__forum_sections` AS s ON s.id = c.section_id\n\t\t\t\t\tWHERE rc.id=" . $refid; $database = App::get('db'); $database->setQuery($query); $rows = $database->loadObjectList(); if ($rows) { require_once PATH_CORE . DS . 'components' . DS . 'com_forum' . DS . 'models' . DS . 'manager.php'; foreach ($rows as $key => $row) { /*$thread = $row->id; if ($row->parent) { $thread = $this->_getThread($row->parent); }*/ if (preg_match('/^<!-- \\{FORMAT:(.*)\\} -->/i', $row->text, $matches)) { $rows[$key]->text = preg_replace('/^(<!-- \\{FORMAT:.*\\} -->)/i', '', $row->text); } switch ($row->scope) { case 'course': require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'course.php'; $offering = \Components\Courses\Models\Offering::getInstance($row->scope_id); $course = \Components\Courses\Models\Course::getInstance($offering->get('course_id')); $url = 'index.php?option=com_courses&gid=' . $course->get('alias') . '&controller=offering&offering=' . $offering->get('alias') . '&active=discussions&thread=' . $row->thread; break; case 'group': $group = \Hubzero\User\Group::getInstance($row->scope_id); $url = 'index.php?option=com_groups&cn=' . $group->get('cn') . '&active=forum&scope=' . $row->section . '/' . $row->category . '/' . $parent; break; case 'site': default: $url = 'index.php?option=com_forum§ion=' . $row->section . '&category=' . $row->category . '&thread=' . $parent; break; } $rows[$key]->href = Route::url($url); } } return $rows; }
/** * Get the state of the entry as either text or numerical value * * @param string $as Format to return state in [text, number] * @param integer $shorten Number of characters to shorten text to * @return mixed String or Integer */ public function content($as = 'parsed', $shorten = 0) { $as = strtolower($as); $options = array(); switch ($as) { case 'parsed': $content = $this->get('content_parsed', null); if ($content === null) { $config = array('option' => Request::getCmd('option', 'com_courses'), 'scope' => Request::getVar('gid', ''), 'pagename' => $this->get('url'), 'pageid' => '', 'filepath' => DS . ltrim($this->config()->get('uploadpath', '/site/courses'), DS) . DS . $this->get('course_id') . DS . 'pagefiles' . ($this->get('offering_id') ? DS . $this->get('offering_id') : ''), 'domain' => $this->get('course_id')); if ($this->get('offering_id')) { $config['scope'] = Course::getInstance($this->get('course_id'))->get('alias') . DS . Offering::getInstance($this->get('offering_id'))->get('alias') . DS . 'pages'; } if ($this->get('section_id')) { $config['filepath'] = DS . trim($this->config()->get('uploadpath', '/site/courses'), DS) . DS . $this->get('course_id') . DS . 'sections' . DS . $this->get('section_id') . DS . 'pagefiles'; } $content = $this->get('content'); $this->importPlugin('content')->trigger('onContentPrepare', array($this->_context, &$this, &$config)); $this->set('content_parsed', (string) $this->get('content')); $this->set('content', $content); return $this->content($as, $shorten); } $options['html'] = true; break; case 'clean': $content = strip_tags($this->content('parsed')); break; case 'raw': default: $content = $this->get('content'); $content = preg_replace('/^(<!-- \\{FORMAT:.*\\} -->)/i', '', $content); $content = html_entity_decode($content); break; } if ($shorten) { $content = String::truncate($content, $shorten, $options); } return $content; }
/** * Displays a list of courses * * @return void */ public function displayTask() { // Incoming $this->view->filters = array('offering' => Request::getState($this->_option . '.' . $this->_controller . '.offering', 'offering', 0), 'search' => urldecode(Request::getState($this->_option . '.' . $this->_controller . '.search', 'search', '')), 'state' => Request::getState($this->_option . '.' . $this->_controller . '.state', 'state', '-1'), 'limit' => Request::getState($this->_option . '.' . $this->_controller . '.limit', 'limit', Config::get('list_limit'), 'int'), 'start' => Request::getState($this->_option . '.' . $this->_controller . '.limitstart', 'limitstart', 0, 'int')); $this->view->offering = \Components\Courses\Models\Offering::getInstance($this->view->filters['offering']); if (!$this->view->offering->exists()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=courses', false)); return; } $this->view->course = \Components\Courses\Models\Course::getInstance($this->view->offering->get('course_id')); // In case limit has been changed, adjust limitstart accordingly $this->view->filters['start'] = $this->view->filters['limit'] != 0 ? floor($this->view->filters['start'] / $this->view->filters['limit']) * $this->view->filters['limit'] : 0; $this->view->filters['count'] = true; $this->view->total = $this->view->offering->units($this->view->filters); $this->view->filters['count'] = false; $this->view->rows = $this->view->offering->units($this->view->filters); // Set any errors foreach ($this->getErrors() as $error) { $this->view->setError($error); } // Output the HTML $this->view->display(); }
/** * Parse the segments of a URL. * * @param array &$segments The segments of the URL to parse. * @return array The URL attributes to be used by the application. */ public function parse(&$segments) { $vars = array(); if (empty($segments)) { return $vars; } if (isset($segments[0])) { if (in_array($segments[0], array('intro', 'browse', 'badge'))) { $vars['controller'] = 'courses'; $vars['task'] = $segments[0]; if ($segments[0] == 'badge' && isset($segments[1]) && is_numeric($segments[1])) { $vars['badge_id'] = $segments[1]; if (in_array($segments[2], array('image', 'criteria', 'validation'))) { $vars['action'] = $segments[2]; if ($segments[2] == 'validation' && isset($segments[3])) { $vars['validation_token'] = $segments[3]; } } return $vars; } } else { if ($segments[0] == 'certificate') { $vars['controller'] = $segments[0]; if (isset($segments[1])) { $vars['course'] = $segments[1]; } if (isset($segments[2])) { $vars['offering'] = $segments[2]; } return $vars; } else { if ($segments[0] == 'new') { $vars['task'] = $segments[0]; } else { $vars['gid'] = $segments[0]; $vars['task'] = 'display'; } $vars['controller'] = 'course'; } } } if (isset($segments[1])) { $vars['controller'] = 'course'; switch ($segments[1]) { case 'overview': case 'reviews': case 'offerings': case 'faq': $vars['active'] = $segments[1]; break; case 'logo': case 'edit': case 'newoffering': case 'saveoffering': case 'deletepage': $vars['task'] = $segments[1]; break; case 'instructors': $vars['controller'] = 'managers'; break; case 'delete': case 'join': case 'accept': case 'cancel': case 'invite': case 'customize': case 'manage': if (isset($segments[2])) { $vars['task'] = 'editoutline'; $vars['offering'] = $segments[2]; } $vars['controller'] = 'offering'; if (isset($segments[3])) { $vars['task'] = 'manage'; $vars['controller'] = $segments[3]; } return $vars; break; case 'editoutline': case 'offerings': //case 'managemodules': //case 'managemodules': case 'ajaxupload': $vars['task'] = $segments[1]; $vars['controller'] = 'media'; break; // Defaults // Defaults default: $pagefound = false; require_once dirname(__DIR__) . DS . 'models' . DS . 'course.php'; $course = \Components\Courses\Models\Course::getInstance($vars['gid']); if ($course->exists()) { $pages = $course->pages(array('active' => 1)); foreach ($pages as $page) { if ($page->get('url') == $segments[1]) { $pagefound = true; $vars['active'] = $segments[1]; break; } } } if (!$pagefound) { $vars['offering'] = $segments[1]; $vars['controller'] = 'offering'; } break; } } if (isset($segments[2])) { if ($segments[2] == 'form.index' || $segments[2] == 'form.layout' || $segments[2] == 'form.saveLayout' || $segments[2] == 'form.upload' || $segments[2] == 'form.deploy' || $segments[2] == 'form.showDeployment' || $segments[2] == 'form.complete') { $vars['controller'] = 'form'; $vars['task'] = substr($segments[2], 5); } elseif ($segments[2] == 'asset' && isset($segments[3]) && is_numeric($segments[3])) { $vars['controller'] = 'offering'; $vars['task'] = 'asset'; $vars['asset_id'] = $segments[3]; if (isset($segments[4])) { $vars['file'] = $segments[4]; } } else { if ($vars['controller'] == 'course' && isset($vars['active'])) { $vars['task'] = 'download'; $vars['file'] = $segments[2]; } else { if ($segments[2] == 'enroll' || $segments[2] == 'logo') { $vars['task'] = $segments[2]; } else { $vars['active'] = $segments[2]; } $vars['controller'] = 'offering'; } } } if (isset($segments[3])) { $vars['unit'] = $segments[3]; } if (isset($segments[4])) { $vars['group'] = $segments[4]; } if (isset($segments[5])) { $vars['asset'] = $segments[5]; } if (isset($segments[6])) { $vars['d'] = $segments[6]; } return $vars; }
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * HUBzero is a registered trademark of Purdue University. * * @package hubzero-cms * @author Shawn Rice <*****@*****.**> * @copyright Copyright 2005-2015 HUBzero Foundation, LLC. * @license http://opensource.org/licenses/MIT MIT */ // No direct access defined('_HZEXEC_') or die; $this->css('media.css'); $base = rtrim(Request::base(true), '/'); $course = \Components\Courses\Models\Course::getInstance($this->listdir); ?> <script type="text/javascript"> function updateDir() { var allPaths = window.top.document.forms[0].dirPath.options; for (i=0; i<allPaths.length; i++) { allPaths.item(i).selected = false; if ((allPaths.item(i).value)== '<?php if (strlen($this->listdir) > 0) { echo $this->listdir; } else { echo '/'; } ?>
/** * Generate and return various links to the entry * Link will vary depending upon action desired, such as edit, delete, etc. * * @param string $type The type of link to return * @return string */ public function link($type = '') { if (!isset($this->_link)) { if (!$this->get('course_alias')) { $course = Course::getInstance($this->get('course_id')); $this->set('course_alias', $course->get('alias')); } $this->_link = 'index.php?option=com_courses&controller=offering&gid=' . $this->get('course_alias') . '&offering=' . $this->alias(); } // If it doesn't exist or isn't published switch (strtolower($type)) { case 'edit': $link = $this->_link . '&task=edit'; break; case 'delete': $link = $this->_link . '&task=delete'; break; case 'enroll': $this->importPlugin('courses'); $course = Course::getInstance($this->get('course_id')); $data = $this->trigger('onCourseEnrollLink', array($course, $this, $this->section())); if ($data && count($data) > 0) { $link = implode('', $data); } else { $link = $this->_link . '&task=enroll'; } break; case 'overview': $link = 'index.php?option=com_courses&gid=' . $this->get('course_alias'); break; case 'permalink': default: $link = $this->_link; break; } return $link; }
/** * Create an item entry * * @param integer $id Optional ID to use * @return boolean */ public function make($id = null) { if ($this->exists()) { return true; } $id = $id ?: Request::getInt('id', 0); include_once Component::path('com_courses') . DS . 'models' . DS . 'courses.php'; $course = null; if (!$id) { $course = \Components\Courses\Models\Course::getInstance(Request::getVar('gid', '')); $id = $course->get('id'); } $this->_tbl->loadType($id, $this->_type); if ($this->exists()) { return true; } if (!$course) { $course = new \Components\Courses\Models\Course($id); } if (!$course->exists()) { $this->setError(Lang::txt('Course not found.')); return false; } $this->set('type', $this->_type)->set('object_id', $course->get('id'))->set('created', $course->get('created'))->set('created_by', $course->get('created_by'))->set('title', $course->get('title'))->set('description', String::truncate($course->get('blurb'), 200))->set('url', Route::url($course->link())); if (!$this->store()) { return false; } return true; }
/** * Saves changes to a course or saves a new entry if creating * * @return void */ public function saveTask($redirect = true) { // Check for request forgeries Request::checkToken(); // Incoming $fields = Request::getVar('fields', array(), 'post'); // Instantiate a Course object $model = \Components\Courses\Models\Section::getInstance($fields['id']); if (!$model->bind($fields)) { $this->setError($model->getError()); $this->editTask($model); return; } $p = new \Hubzero\Config\Registry(Request::getVar('params', '', 'post')); // Make sure the logo gets carried over $op = new \Hubzero\Config\Registry($model->get('params')); $p->set('logo', $op->get('logo')); $model->set('params', $p->toString()); if (!$model->store(true)) { $this->setError($model->getError()); $this->editTask($model); return; } $dates = Request::getVar('dates', array(), 'post'); //$i=0; //$unit_up = ''; //$unit_down = ''; foreach ($dates as $i => $dt) { /*if (!$unit_up && $i == 0) { $unit_up = $dt['publish_up']; } if (!$unit_down && $i == 0) { $unit_down = $dt['publish_down']; }*/ $dt['section_id'] = $model->get('id'); $dt = $this->_datesToUTC($dt); $dtmodel = new \Components\Courses\Models\Section\Date($dt['id']); if (!$dtmodel->bind($dt)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } if (isset($dt['asset_group'])) { foreach ($dt['asset_group'] as $j => $ag) { $ag = $this->_datesToUTC($ag); if (!isset($ag['publish_up']) || !$ag['publish_up']) { $ag['publish_up'] = $dt['publish_up']; } if (!isset($ag['publish_down']) || !$ag['publish_down']) { $ag['publish_down'] = $dt['publish_down']; } $ag['section_id'] = $model->get('id'); $dtmodel = new \Components\Courses\Models\Section\Date($ag['id']); if (!$dtmodel->bind($ag)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } if (isset($ag['asset_group'])) { foreach ($ag['asset_group'] as $k => $agt) { $agt = $this->_datesToUTC($agt); if (!isset($agt['publish_up']) || !$agt['publish_up']) { $agt['publish_up'] = $ag['publish_up']; } if (!isset($agt['publish_down']) || !$agt['publish_down']) { $agt['publish_down'] = $ag['publish_down']; } $agt['section_id'] = $model->get('id'); $dtmodel = new \Components\Courses\Models\Section\Date($agt['id']); if (!$dtmodel->bind($agt)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } if (isset($agt['asset'])) { foreach ($agt['asset'] as $z => $a) { $a = $this->_datesToUTC($a); if (!isset($a['publish_up']) || !$a['publish_up']) { $a['publish_up'] = $agt['publish_up']; } if (!isset($a['publish_down']) || !$a['publish_down']) { $a['publish_down'] = $agt['publish_down']; } $a['section_id'] = $model->get('id'); $dtmodel = new \Components\Courses\Models\Section\Date($a['id']); if (!$dtmodel->bind($a)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } //$agt['asset'][$z] = $a; } } //$ag['asset_group'][$k] = $agt; } } if (isset($ag['asset'])) { foreach ($ag['asset'] as $z => $a) { $a = $this->_datesToUTC($a); if (!isset($a['publish_up']) || !$a['publish_up']) { $a['publish_up'] = $ag['publish_up']; } if (!isset($a['publish_down']) || !$a['publish_down']) { $a['publish_down'] = $ag['publish_down']; } $a['section_id'] = $model->get('id'); $dtmodel = new \Components\Courses\Models\Section\Date($a['id']); if (!$dtmodel->bind($a)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } } } } } if (isset($dt['asset'])) { foreach ($dt['asset'] as $z => $a) { $a = $this->_datesToUTC($a); if (!isset($a['publish_up']) || !$a['publish_up']) { $a['publish_up'] = $dt['publish_up']; } if (!isset($a['publish_down']) || !$a['publish_down']) { $a['publish_down'] = $dt['publish_down']; } $a['section_id'] = $model->get('id'); $dtmodel = new \Components\Courses\Models\Section\Date($a['id']); if (!$dtmodel->bind($a)) { $this->setError($dtmodel->getError()); continue; } if (!$dtmodel->store(true)) { $this->setError($dtmodel->getError()); continue; } //$agt['asset'][$z] = $a; } } } // Process badge info $badge = Request::getVar('badge', array(), 'post', 'array', JREQUEST_ALLOWHTML); if (isset($badge['published']) && $badge['published']) { // Get courses config $cconfig = Component::params('com_courses'); // Save the basic badge content $badge['section_id'] = $model->get('id'); $badgeObj = new \Components\Courses\Models\Section\Badge($badge['id']); $badgeObj->bind($badge); $badgeObj->store(); // See if we have an image coming in as well $badge_image = Request::getVar('badge_image', false, 'files', 'array'); // If so, proceed with saving the image if (isset($badge_image['name']) && $badge_image['name']) { // Get the file extension $pathinfo = pathinfo($badge_image['name']); $filename = $pathinfo['filename']; $ext = $pathinfo['extension']; // Check for square and at least 420 x 420 $dimensions = getimagesize($badge_image['tmp_name']); if ($dimensions[0] != $dimensions[1]) { $this->setError(Lang::txt('COM_COURSES_ERROR_IMG_MUST_BE_SQUARE')); } else { if ($dimensions[0] < 450) { $this->setError(Lang::txt('COM_COURSES_ERROR_IMG_MIN_WIDTH')); } else { // Build the upload path if it doesn't exist $uploadDirectory = PATH_APP . DS . trim($cconfig->get('uploadpath', '/site/courses'), DS); $uploadDirectory .= DS . 'badges' . DS . $badgeObj->get('id') . DS; // Make sure upload directory exists and is writable if (!is_dir($uploadDirectory)) { if (!\Filesystem::makeDirectory($uploadDirectory)) { $this->setError(Lang::txt('COM_COURSES_ERROR_UNABLE_TO_CREATE_UPLOAD_PATH')); } } if (!is_writable($uploadDirectory)) { $this->setError(Lang::txt('COM_COURSES_ERROR_UPLOAD_DIRECTORY_IS_NOT_WRITABLE')); } // Get the final file path $target_path = $uploadDirectory . 'badge.' . $ext; if (!($move = move_uploaded_file($badge_image['tmp_name'], $target_path))) { $this->setError(Lang::txt('COM_COURSES_ERROR_FILE_MOVE_FAILED')); } else { // Move successful, save the image url to the badge entry $img_url = DS . 'courses' . DS . 'badge' . DS . $badgeObj->get('id') . DS . 'image'; $badgeObj->bind(array('img_url' => $img_url)); $badgeObj->store(); } } } } // Process criteria text if (strcmp($badgeObj->get('criteria_text'), $badge['criteria'])) { $badgeObj->set('criteria_text_new', $badge['criteria']); $badgeObj->store(); $badgeObj->set('criteria_text_new', NULL); } // If we don't already have a provider badge id set, then we're processing our initial badge creation if ($badgeObj->get('provider_name') && !$badgeObj->get('provider_badge_id') && $badgeObj->get('img_url')) { $request_type = $cconfig->get('badges_request_type', 'oauth'); $badgesHandler = new \Hubzero\Badges\Wallet(strtoupper($badgeObj->get('provider_name')), $request_type); $badgesProvider = $badgesHandler->getProvider(); if (is_object($badgesProvider)) { $credentials = new stdClass(); $credentials->consumer_key = $cconfig->get($badgeObj->get('provider_name') . '_consumer_key', 0); $credentials->consumer_secret = $cconfig->get($badgeObj->get('provider_name') . '_consumer_secret', 0); $credentials->issuerId = $cconfig->get($badgeObj->get('provider_name') . '_issuer_id'); $badgesProvider->setCredentials($credentials); $offering = \Components\Courses\Models\Offering::getInstance($model->get('offering_id')); $course = \Components\Courses\Models\Course::getInstance($offering->get('course_id')); $data = array(); $data['Name'] = $course->get('title'); $data['Description'] = trim($course->get('title')) . ' Badge'; $data['CriteriaUrl'] = rtrim(Request::root(), '/') . '/courses/badge/' . $badgeObj->get('id') . '/criteria'; $data['Version'] = '1'; $data['BadgeImageUrl'] = rtrim(Request::root(), '/') . '/' . trim($badgeObj->get('img_url'), '/'); if (!$credentials->consumer_key || !$credentials->consumer_secret) { $this->setError(Lang::txt('COM_COURSES_ERROR_BADGE_MISSING_OPTIONS')); } else { try { $provider_badge_id = $badgesProvider->createBadge($data); } catch (Exception $e) { $this->setError($e->getMessage()); } if (isset($provider_badge_id) && $provider_badge_id) { // We've successfully created a badge, so save that id to the database $badgeObj->bind(array('provider_badge_id' => $provider_badge_id)); $badgeObj->store(); } else { $this->setError(Lang::txt('COM_COURSES_ERROR_FAILED_TO_SAVE_BADGE')); } } } } } elseif ($badge['id']) { $badgeObj = new \Components\Courses\Models\Section\Badge($badge['id']); $badgeObj->bind(array('published' => 0)); $badgeObj->store(); } if ($this->getError()) { $this->setError(implode('<br />', $this->getErrors())); $this->editTask($model); return; } if ($this->_task == 'apply') { return $this->editTask($model); } // Output messsage and redirect App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&offering=' . $model->get('offering_id'), false), Lang::txt('COM_COURSES_ITEM_SAVED')); }
/** * Edit a course page * * @return void */ public function editTask($model = null) { Request::setVar('hidemainmenu', 1); if (!is_object($model)) { // Incoming $id = Request::getVar('id', array(0)); // Get the single ID we're working with if (is_array($id)) { $id = !empty($id) ? $id[0] : 0; } $model = new \Components\Courses\Models\Page($id); } $this->view->row = $model; if (!$this->view->row->get('course_id')) { $this->view->row->set('course_id', Request::getInt('course', 0)); } if (!$this->view->row->get('offering_id')) { $this->view->row->set('offering_id', Request::getInt('offering', 0)); } if (!$this->view->row->exists()) { $this->view->row->set('active', 1); } $this->view->course = \Components\Courses\Models\Course::getInstance($this->view->row->get('course_id')); $this->view->offering = \Components\Courses\Models\Offering::getInstance($this->view->row->get('offering_id')); // Set any errors foreach ($this->getErrors() as $error) { \Notify::error($error); } // Output the HTML $this->view->setLayout('edit')->display(); }
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * HUBzero is a registered trademark of Purdue University. * * @package hubzero-cms * @copyright Copyright 2005-2015 HUBzero Foundation, LLC. * @license http://opensource.org/licenses/MIT MIT */ // No direct access defined('_HZEXEC_') or die; $course = \Components\Courses\Models\Course::getInstance($this->model->get('course_id')); $roles = $course->offering(0)->roles(array('alias' => '!student')); $offerings = $course->offerings(); if ($this->getError()) { ?> <dl id="system-message"> <dt><?php echo Lang::txt('ERROR'); ?> </dt> <dd class="error"><?php echo implode('<br />', $this->getErrors()); ?> </dd> </dl> <?php
/** * Display a file and its info * * @param string $file File name * @param integer $id User ID * @return void */ public function displayTask($file = '', $id = 0) { // Load the component config $this->view->config = $this->config; // Incoming if (!$id) { $id = Request::getInt('id', 0); } $this->view->id = $id; $this->view->type = strtolower(Request::getWord('type', '')); // Build the file path $this->view->dir = $id; $this->view->path = $this->_path($this->view->type, $id); switch ($this->view->type) { case 'section': $model = \Components\Courses\Models\Section::getInstance($id); $this->view->file = $model->params('logo'); break; case 'offering': $model = \Components\Courses\Models\Offering::getInstance($id); $this->view->file = $model->params('logo'); break; case 'course': $model = \Components\Courses\Models\Course::getInstance($id); $this->view->file = $model->get('logo'); break; default: $this->setError(Lang::txt('COM_COURSES_ERROR_INVALID_TYPE')); return; break; } // Set any errors foreach ($this->getErrors() as $error) { $this->view->setError($error); } // Output the HTML $this->view->setLayout('display')->display(); }
/** * Calculate scores for each unit and the course as a whole * * @param int $member_id * @param int $asset_id * @return boolean true on success, false otherwise */ public function calculateScores($member_id = null, $asset_id = null) { // We need one of $course or $asset_id if (is_null($this->course) && is_null($asset_id)) { return false; } // Get the course id if (!is_null($this->course) && is_object($this->course)) { // Get our course model as well (to retrieve grade policy) $course = $this->course; $course_id = $this->course->get('id'); } elseif (!is_null($asset_id) && is_numeric($asset_id)) { $asset = new Tables\Asset(\App::get('db')); $asset->load($asset_id); $course_id = $asset->course_id; // Get our course model as well (to retrieve grade policy) $course = new Course($course_id); } else { // Could not determine course id return false; } if (!is_null($member_id) && !empty($member_id)) { if (!is_array($member_id)) { $member_id = (array) $member_id; } } else { // Pull all offering members $members = $course->offering()->students(); $member_id = array(); // Get member id's for refresh filter foreach ($members as $member) { $member_id[] = $member->get('id'); } } // Get our units and track which units have grades that might need to be cleared $unit_ids = array(); $units = $course->offering()->units(); foreach ($units as $unit) { $unit_ids[$unit->get('id')] = $member_id; } // Get a grade policy object $gradePolicy = new GradePolicies($course->offering()->section()->get('grade_policy_id'), $course->offering()->section()->get('id')); // Calculate course grades, start by getting all grades $filters = array('member_id' => $member_id, 'scope' => 'asset', 'graded' => true); $results = $this->_grades($filters); $grades = array(); $scores = array(); foreach ($results as $grade) { if (is_null($grade->score) && is_null($grade->override)) { continue; } // Check for overrides if ($grade->override) { $grades[$grade->member_id][$grade->unit_id][$grade->scope_id] = array('score' => $grade->override, 'weighting' => $grade->grade_weight); } else { $grades[$grade->member_id][$grade->unit_id][$grade->scope_id] = array('score' => $grade->score, 'weighting' => $grade->grade_weight); } } if (count($grades) > 0) { foreach ($grades as $member_id => $values) { $scores[$member_id]['course_exam_count'] = 0; $scores[$member_id]['course_quiz_count'] = 0; $scores[$member_id]['course_homework_count'] = 0; $scores[$member_id]['course_exam_sum'] = 0; $scores[$member_id]['course_quiz_sum'] = 0; $scores[$member_id]['course_homework_sum'] = 0; // Loop through units and compute scores foreach ($values as $unit_id => $val) { // We're processing this unit/member, thus it doesn't need to be cleared - so remove it from the list of potentials if (isset($unit_ids[$unit_id]) && ($key = array_search($member_id, $unit_ids[$unit_id])) !== false) { unset($unit_ids[$unit_id][$key]); } $scores[$member_id]['units'][$unit_id]['exam_count'] = 0; $scores[$member_id]['units'][$unit_id]['quiz_count'] = 0; $scores[$member_id]['units'][$unit_id]['homework_count'] = 0; $scores[$member_id]['units'][$unit_id]['exam_sum'] = 0; $scores[$member_id]['units'][$unit_id]['quiz_sum'] = 0; $scores[$member_id]['units'][$unit_id]['homework_sum'] = 0; foreach ($val as $grade) { switch ($grade['weighting']) { case 'exam': $scores[$member_id]['course_exam_count']++; $scores[$member_id]['course_exam_sum'] += $grade['score']; $scores[$member_id]['units'][$unit_id]['exam_count']++; $scores[$member_id]['units'][$unit_id]['exam_sum'] += $grade['score']; break; case 'quiz': $scores[$member_id]['course_quiz_count']++; $scores[$member_id]['course_quiz_sum'] += $grade['score']; $scores[$member_id]['units'][$unit_id]['quiz_count']++; $scores[$member_id]['units'][$unit_id]['quiz_sum'] += $grade['score']; break; case 'homework': $scores[$member_id]['course_homework_count']++; $scores[$member_id]['course_homework_sum'] += $grade['score']; $scores[$member_id]['units'][$unit_id]['homework_count']++; $scores[$member_id]['units'][$unit_id]['homework_sum'] += $grade['score']; break; } } if ($scores[$member_id]['units'][$unit_id]['exam_count'] > 0) { $scores[$member_id]['units'][$unit_id]['exam_score'] = $scores[$member_id]['units'][$unit_id]['exam_sum'] / $scores[$member_id]['units'][$unit_id]['exam_count']; $scores[$member_id]['units'][$unit_id]['exam_weight'] = $gradePolicy->get('exam_weight') > 0 ? $gradePolicy->get('exam_weight') : 0; } else { $scores[$member_id]['units'][$unit_id]['exam_score'] = null; $scores[$member_id]['units'][$unit_id]['exam_weight'] = null; } if ($scores[$member_id]['units'][$unit_id]['quiz_count'] > 0) { $scores[$member_id]['units'][$unit_id]['quiz_score'] = $scores[$member_id]['units'][$unit_id]['quiz_sum'] / $scores[$member_id]['units'][$unit_id]['quiz_count']; $scores[$member_id]['units'][$unit_id]['quiz_weight'] = $gradePolicy->get('quiz_weight') > 0 ? $gradePolicy->get('quiz_weight') : 0; } else { $scores[$member_id]['units'][$unit_id]['quiz_score'] = null; $scores[$member_id]['units'][$unit_id]['quiz_weight'] = null; } if ($scores[$member_id]['units'][$unit_id]['homework_count'] > 0) { $scores[$member_id]['units'][$unit_id]['homework_score'] = $scores[$member_id]['units'][$unit_id]['homework_sum'] / $scores[$member_id]['units'][$unit_id]['homework_count']; $scores[$member_id]['units'][$unit_id]['homework_weight'] = $gradePolicy->get('homework_weight') > 0 ? $gradePolicy->get('homework_weight') : 0; } else { $scores[$member_id]['units'][$unit_id]['homework_score'] = null; $scores[$member_id]['units'][$unit_id]['homework_weight'] = null; } $numerator = array_sum(array($scores[$member_id]['units'][$unit_id]['exam_score'] * $gradePolicy->get('exam_weight'), $scores[$member_id]['units'][$unit_id]['quiz_score'] * $gradePolicy->get('quiz_weight'), $scores[$member_id]['units'][$unit_id]['homework_score'] * $gradePolicy->get('homework_weight'))); $denominator = array_sum(array($scores[$member_id]['units'][$unit_id]['exam_weight'], $scores[$member_id]['units'][$unit_id]['quiz_weight'], $scores[$member_id]['units'][$unit_id]['homework_weight'])); if ($denominator) { $scores[$member_id]['units'][$unit_id]['unit_weighted'] = $numerator / $denominator; } else { $scores[$member_id]['units'][$unit_id]['unit_weighted'] = NULL; } } // Now calculate overall course scores if ($scores[$member_id]['course_exam_count'] > 0) { $scores[$member_id]['course_exam_score'] = $scores[$member_id]['course_exam_sum'] / $scores[$member_id]['course_exam_count']; $scores[$member_id]['course_exam_weight'] = $gradePolicy->get('exam_weight') > 0 ? $gradePolicy->get('exam_weight') : 0; } else { $scores[$member_id]['course_exam_score'] = null; $scores[$member_id]['course_exam_weight'] = null; } if ($scores[$member_id]['course_quiz_count'] > 0) { $scores[$member_id]['course_quiz_score'] = $scores[$member_id]['course_quiz_sum'] / $scores[$member_id]['course_quiz_count']; $scores[$member_id]['course_quiz_weight'] = $gradePolicy->get('quiz_weight') > 0 ? $gradePolicy->get('quiz_weight') : 0; } else { $scores[$member_id]['course_quiz_score'] = null; $scores[$member_id]['course_quiz_weight'] = null; } if ($scores[$member_id]['course_homework_count'] > 0) { $scores[$member_id]['course_homework_score'] = $scores[$member_id]['course_homework_sum'] / $scores[$member_id]['course_homework_count']; $scores[$member_id]['course_homework_weight'] = $gradePolicy->get('homework_weight') > 0 ? $gradePolicy->get('homework_weight') : 0; } else { $scores[$member_id]['course_homework_score'] = null; $scores[$member_id]['course_homework_weight'] = null; } $numerator = array_sum(array($scores[$member_id]['course_exam_score'] * $gradePolicy->get('exam_weight'), $scores[$member_id]['course_quiz_score'] * $gradePolicy->get('quiz_weight'), $scores[$member_id]['course_homework_score'] * $gradePolicy->get('homework_weight'))); $denominator = array_sum(array($scores[$member_id]['course_exam_weight'], $scores[$member_id]['course_quiz_weight'], $scores[$member_id]['course_homework_weight'])); if ($denominator) { $scores[$member_id]['course_weighted'] = $numerator / $denominator; } else { $scores[$member_id]['course_weighted'] = NULL; } } } else { // Make sure nothing is lingering around...given that there shouldn't be any grades there $this->_tbl->clearGrades($member_id, $course); } $this->_tbl->saveGrades($scores, $course_id); $this->_tbl->clearUnits($unit_ids); // Success return true; }
/** * Remove one or more users from the course manager list * * @return void */ public function updateTask() { // Check for request forgeries Request::checkToken(); // Incoming member ID $id = Request::getInt('id', 0); if (!$id) { $this->setError(Lang::txt('COM_COURSES_ERROR_MISSING_COURSE')); $this->displayTask(); return; } $model = Course::getInstance($id); $entries = Request::getVar('entries', array(0), 'post'); require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'member.php'; foreach ($entries as $key => $data) { // Retrieve user's account info $tbl = new Tables\Member($this->database); $tbl->load($data['user_id'], $data['course_id'], $data['offering_id'], $data['section_id'], 0); if ($tbl->role_id == $data['role_id']) { continue; } $tbl->role_id = $data['role_id']; if (!$tbl->store()) { $this->setError($tbl->getError()); } } // Push through to the hosts view $this->displayTask(); }
/** * Processes grade save from unity app * * @apiMethod POST * @apiUri /courses/unity/save * @apiParameter { * "name": "referrer", * "description": "Host page", * "type": "string", * "required": false, * "default": "$_SERVER['HTTP_REFERER']" * } * @apiParameter { * "name": "payload", * "description": "Score notes/content", * "type": "string", * "required": true, * "default": null * } * @return void */ public function saveTask() { // Require authentication and authorization $this->authorizeOrFail(); $user_id = App::get('authn')['user_id']; // Parse some things out of the referer $referer = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : Request::getVar('referrer'); preg_match('/\\/asset\\/([[:digit:]]*)/', $referer, $matches); if (!($asset_id = $matches[1])) { App::abort(400, 'Failed to get asset ID'); } // Get course info...this seems a little wonky preg_match('/\\/courses\\/([[:alnum:]\\-\\_]*)\\/([[:alnum:]\\:\\-\\_]*)/', $referer, $matches); $course_alias = $matches[1]; $offering_alias = $matches[2]; $section_alias = null; if (strpos($offering_alias, ":")) { $parts = explode(":", $offering_alias); $offering_alias = $parts[0]; $section_alias = $parts[1]; } $course = Course::getInstance($course_alias); $course->offering($offering_alias); $course->offering()->section($section_alias); $section_id = $course->offering()->section()->get('id'); $member = Member::getInstance($user_id, 0, 0, $section_id); if (!($member_id = $member->get('id'))) { App::abort(500, 'Failed to get course member ID'); } if (!($data = Request::getVar('payload', false))) { App::abort(400, 'Missing payload'); } // Get the key and IV - Trim the first xx characters from the payload for IV $key = $course->config()->get('unity_key', 0); $iv = substr($data, 0, 32); $data = substr($data, 32); $message = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_CBC, $iv); $message = trim($message); $message = json_decode($message); if (!$message || !is_object($message)) { App::abort(500, 'Failed to decode message'); } // Get timestamp $now = Date::toSql(); // Save the unity details $unity = new AssetUnity($this->db); $unity->set('member_id', $member_id); $unity->set('asset_id', $asset_id); $unity->set('created', $now); $unity->set('passed', $message->passed ? 1 : 0); $unity->set('details', $message->details); if (!$unity->store()) { App::abort(500, $unity->getError()); } // Now set/update the gradebook item $gradebook = new GradeBook($this->db); $gradebook->loadByUserAndAssetId($member_id, $asset_id); // Score is either 100 or 0 $score = $message->passed ? 100 : 0; // See if gradebook entry already exists if ($gradebook->get('id')) { // Entry does exist, see if current score is better than previous score if ($score > $gradebook->get('score')) { $gradebook->set('score', $score); $gradebook->set('score_recorded', Date::toSql()); if (!$gradebook->store()) { App::abort(500, $gradebook->getError()); } } } else { $gradebook->set('member_id', $member_id); $gradebook->set('score', $score); $gradebook->set('scope', 'asset'); $gradebook->set('scope_id', $asset_id); $gradebook->set('score_recorded', Date::toSql()); if (!$gradebook->store()) { App::abort(500, $gradebook->getError()); } } // Return message $this->send(['success' => true]); }
/** * Display a list of 'manager' for a specific course * * @param object $profile \Hubzero\User\Profile * @return void */ public function displayTask($course = null) { // Incoming if (!$course) { $id = Request::getInt('id', 0, 'get'); $course = \Components\Courses\Models\Course::getInstance($id); } $this->view->course = $course; // Set any errors foreach ($this->getErrors() as $error) { $this->view->setError($error); } // Output the HTML $this->view->setLayout('display')->display(); }
/** * Display an offering asset * * @return void */ public function enrollTask() { // Check if they're logged in if (User::isGuest()) { $this->loginTask(Lang::txt('COM_COURSES_ENROLLMENT_REQUIRES_LOGIN')); return; } $offering = $this->course->offering(); // Is the user a manager or student? if ($offering->isManager() || $offering->isStudent()) { // Yes! Already enrolled // Redirect back to the course page App::redirect(Route::url($offering->link()), Lang::txt('COM_COURSES_ALREADY_ENROLLED')); return; } $this->view->course = $this->course; // Build the title $this->_buildTitle(); // Build pathway $this->_buildPathway(); // Can the user enroll? if (!$offering->section()->canEnroll()) { $this->view->setLayout('enroll_closed'); $this->view->display(); return; } $enrolled = false; // If enrollment is open OR a coupon code was posted if (!$offering->section()->get('enrollment') || ($code = Request::getVar('code', ''))) { $section_id = $offering->section()->get('id'); // If a coupon code was posted if (isset($code)) { // Get the coupon $coupon = $offering->section()->code($code); // Is it a valid code? if (!$coupon->exists()) { $this->setError(Lang::txt('COM_COURSES_ERROR_CODE_INVALID', $code)); } // Has it already been redeemed? if ($coupon->isRedeemed()) { $this->setError(Lang::txt('COM_COURSES_ERROR_CODE_ALREADY_REDEEMED', $code)); } else { // Has it expired? if ($coupon->isExpired()) { $this->setError(Lang::txt('COM_COURSES_ERROR_CODE_EXPIRED', $code)); } } if (!$this->getError()) { // Is this a coupon for a different section? if ($offering->section()->get('id') != $coupon->get('section_id')) { $section = \Components\Courses\Models\Section::getInstance($coupon->get('section_id')); if ($section->exists() && $section->get('offering_id') != $offering->get('id')) { $offering = \Components\Courses\Models\Offering::getInstance($section->get('offering_id')); if ($offering->exists() && $offering->get('course_id') != $this->course->get('id')) { $this->course = \Components\Courses\Models\Course::getInstance($offering->get('course_id')); } } App::redirect(Route::url($offering->link() . '&task=enroll&code=' . $code)); return; } // Redeem the code $coupon->redeem(User::get('id')); // set('redeemed_by', User::get('id')); //$coupon->store(); } } // If no errors if (!$this->getError()) { // Add the user to the course $model = new \Components\Courses\Models\Member(0); //::getInstance(User::get('id'), $offering->get('id')); $model->set('user_id', User::get('id')); $model->set('course_id', $this->course->get('id')); $model->set('offering_id', $offering->get('id')); $model->set('section_id', $offering->section()->get('id')); if ($roles = $offering->roles()) { foreach ($roles as $role) { if ($role->alias == 'student') { $model->set('role_id', $role->id); break; } } } $model->set('student', 1); if ($model->store(true)) { $enrolled = true; } else { $this->setError($model->getError()); } } } if ($enrolled) { $link = $offering->link(); $data = Event::trigger('courses.onCourseEnrolled', array($this->course, $offering, $offering->section())); if ($data && count($data) > 0) { $link = implode('', $data); } App::redirect(Route::url($link)); return; } // If enrollment is srestricted and the user isn't enrolled yet if ($offering->section()->get('enrollment') == 1 && !$enrolled) { // Show a form for entering a coupon code $this->view->setLayout('enroll_restricted'); } if ($this->getError()) { \Notify::error($this->getError(), 'courses'); } $this->view->notifications = \Notify::messages('courses'); $this->view->display(); }
/** * Calculate permissions * * @return void */ private function _calculate() { // List of actions $actions = array('admin', 'manage', 'create', 'delete', 'edit', 'edit-state', 'edit-own', 'view'); // Are they an admin? if ($this->config()->get('access-admin-course') || $this->config()->get('access-manage-course')) { // Admin - no need to go any further return; } /*if (!$this->config()->get('access-checked-course')) { }*/ // If no course Id found if (!$this->get('course_id')) { // Try to get the course from request $course = Course::getInstance(Request::getVar('gid', '')); if ($course->exists()) { $this->set('course_id', $course->get('id')); } } // Still no course? Can't do anything from here if ($this->get('course_id') === null) { return; } // Get the course if (!isset($course)) { $course = Course::getInstance($this->get('course_id')); } // Make sure the course exists if ($course->exists() && $course->isPublished()) { $this->config()->set('access-view-course', true); } // If they're logged in if (!User::isGuest()) { $manager = $this->manager(User::get('id')); // If they're NOT an admin if ($manager->exists()) { // If no specific permissions set if ($manager->get('course_id') == $this->get('course_id')) { if (!$manager->get('offering_id') && !$manager->get('section_id')) { if (!$manager->get('permissions')) { foreach ($actions as $action) { $this->config()->set('access-' . $action . '-section', true); $this->config()->set('access-' . $action . '-offering', true); $this->config()->set('access-' . $action . '-course', true); } } else { // Merge permissions $this->config()->merge($permissions); } } else { $this->config()->set('access-view-section', true); $this->config()->set('access-view-offering', true); $this->config()->set('access-view-course', true); } $this->config()->set('is-manager', true); $this->config()->set('access-checked-offering', true); $this->config()->set('access-checked-section', true); } } else { if ($student = $this->student(User::get('id'))) { if ($student->exists()) { // Allow them to view content $this->config()->set('is-student', true); $this->config()->set('access-view-course', true); } } } } // Passed course level checks $this->config()->set('access-checked-course', true); // If no offering ID is found if (!$this->get('offering_id')) { $oid = Request::getVar('offering', ''); //$course = \Components\Courses\Models\Course::getInstance($this->get('course_id')); $offering = $course->offering($oid); if ($offering->exists()) { $this->set('offering_id', $offering->get('id')); $this->set('section_id', $offering->section()->get('id')); } } // Ensure we have an offering to work with if ($this->get('offering_id') === null) { return; } if (!isset($offering)) { $course = Course::getInstance($this->get('course_id')); $offering = $course->offering($this->get('offering_id')); } // Offering isn't available if (!$offering->exists() || !$offering->isPublished()) { return; } // If they're logged in if (!User::isGuest()) { $manager = $this->manager(User::get('id')); if ($manager->exists()) { // If no specific permissions set if ($manager->get('course_id') == $this->get('course_id') && $manager->get('offering_id') == $this->get('offering_id')) { if (!$manager->get('permissions')) { // If section_id is set, then they're a section manager if ($manager->get('section_id') == $this->get('section_id')) { foreach ($actions as $action) { $this->config()->set('access-' . $action . '-section', true); } } else { foreach ($actions as $action) { $this->config()->set('access-' . $action . '-section', true); $this->config()->set('access-' . $action . '-offering', true); //$this->config()->set('access-' . $action . '-course', true); } } } else { // Merge permissions $this->config()->merge($permissions); } $this->config()->set('access-view-offering', true); $this->config()->set('access-view-section', true); } } else { if ($student = $this->student(User::get('id'))) { if ($student->exists()) { // Allow them to view content $this->config()->set('access-view-offering', true); // Give section view privileges if in identified section if ($student->get('section_id') == $this->get('section_id')) { $this->config()->set('access-view-section', true); } } } } } $this->config()->set('access-checked-offering', true); $this->config()->set('access-checked-section', true); }
/** * Download a file * * @param string $filename File name * @return void */ public function downloadTask($filename) { //get the course $course = Course::getInstance($this->gid); //authorize $authorized = $this->_authorize(); //get the file name if (substr(strtolower($filename), 0, 5) == 'image') { $file = urldecode(substr($filename, 6)); } elseif (substr(strtolower($filename), 0, 4) == 'file') { $file = urldecode(substr($filename, 5)); } //if were on the wiki we need to output files a specific way if ($this->active == 'wiki') { //check to make sure user has access to wiki section if (!in_array(User::get('id'), $course->get('members')) || User::isGuest()) { return App::abort(403, Lang::txt('COM_COURSES_NOT_AUTH') . ' ' . $file); } //load wiki page from db require_once PATH_CORE . DS . 'components' . DS . 'com_wiki' . DS . 'tables' . DS . 'page.php'; $page = new \Components\Wiki\Tables\Page($this->database); $page->load(Request::getVar('pagename'), $course->get('cn') . DS . 'wiki'); //check specific wiki page access if ($page->get('access') == 1 && !in_array(User::get('id'), $course->get('members')) && $authorized != 'admin') { return App::abort(403, Lang::txt('COM_COURSES_NOT_AUTH') . ' ' . $file); } //get the config and build base path $wiki_config = Component::params('com_wiki'); $base_path = $wiki_config->get('filepath') . DS . $page->get('id'); } else { //check to make sure we can access it if (!in_array(User::get('id'), $course->get('members')) || User::isGuest()) { return App::abort(403, Lang::txt('COM_COURSES_NOT_AUTH') . ' ' . $file); } // Build the path $base_path = $this->config->get('uploadpath'); $base_path .= DS . $course->get('gidNumber'); } // Final path of file $file_path = $base_path . DS . $file; // Ensure the file exist if (!file_exists(PATH_APP . DS . $file_path)) { return App::abort(404, Lang::txt('COM_COURSES_FILE_NOT_FOUND') . ' ' . $file); } // Serve up the file $xserver = new \Hubzero\Content\Server(); $xserver->filename(PATH_APP . DS . $file_path); $xserver->disposition('attachment'); $xserver->acceptranges(false); // @TODO fix byte range support if (!$xserver->serve()) { return App::abort(404, Lang::txt('COM_COURSES_SERVER_ERROR')); } else { exit; } return; }
/** * Render a certificate * * @param object $user User * @param string $path Path to store rendered file to * @return boolean True on success, false on error */ public function render($user = null, $path = null) { if (!$user) { $user = \User::getRoot(); } if (!class_exists('\\Components\\Courses\\Models\\Course')) { require_once __DIR__ . DS . 'course.php'; } $course = Course::getInstance($this->get('course_id')); require_once PATH_CORE . DS . 'libraries' . DS . 'fpdf16' . DS . 'fpdf.php'; require_once PATH_CORE . DS . 'libraries' . DS . 'fpdi' . DS . 'fpdi.php'; // Get the pdf and draw on top of it $pdf = new \FPDI(); $pageCount = $pdf->setSourceFile($this->path('system') . DS . 'certificate.pdf'); $tplIdx = $pdf->importPage(1); $size = $pdf->getTemplateSize($tplIdx); $pdf->AddPage('L', array($size['h'], $size['w'])); $pdf->useTemplate($tplIdx, 0, 0, 0, 0, true); $pdf->SetFillColor(0, 0, 0); foreach ($this->properties()->elements as $element) { // Convert pixel values to percents $element->x = $element->x / $this->properties()->width; $element->y = $element->y / $this->properties()->height; $element->w = $element->w / $this->properties()->width; $element->h = $element->h / $this->properties()->height; $val = ''; switch ($element->id) { case 'name': case 'email': case 'username': $val = $user->get($element->id); break; case 'course': $val = $course->get('title'); break; case 'offering': $val = $course->offering()->get('title'); break; case 'section': $val = $course->offering()->section()->get('title'); break; case 'date': $val = \Date::of('now')->format(Lang::txt('d M Y')); break; } $pdf->SetFont('Arial', '', 30); //($element->h * $size['h'])); $pdf->setXY($element->x * $size['w'], $element->y * $size['h']); // - ($element->h * $size['h']) $pdf->Cell($element->w * $size['w'], $element->h * $size['h'], $val, '', 1, 'C'); } if (!$path) { $pdf->Output(); die; } $pdf->Output($path, 'F'); return true; }
/** * Actions to perform after saving a course * * @param object $model \Components\Courses\Models\Course * @param boolean $isNew Is this a newly created entry? * @return void */ public function onOfferingSave($model) { if (!$model->exists()) { return; } $params = new \Hubzero\Config\Registry($model->get('params')); if ($params->get('store_product', 0)) { $course = \Components\Courses\Models\Course::getInstance($model->get('course_id')); $title = $course->get('title') . ' (' . $model->get('title') . ')'; $description = $course->get('blurb'); $price = $params->get('store_price', '30.00'); $duration = $params->get('store_membership_duration', '1 YEAR'); if (!$params->get('store_product_id', 0)) { include_once PATH_CORE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Course.php'; $product = new StorefrontModelCourse(); $product->setName($title); $product->setDescription($description); $product->setPrice($price); // We don't want products showing up for non-published courses if ($model->get('state') != 1) { $product->setActiveStatus(0); } else { $product->setActiveStatus(1); } // Membership model: membership duration period (must me in MySQL date format: 1 DAY, 2 MONTH, 3 YEAR...) $product->setTimeToLive($duration); // Course alias id $product->setCourseId($course->get('alias')); $product->setOfferingId($model->get('alias')); try { // Returns object with values, pId is the new product ID to link to $info = $product->add(); $params->set('store_product_id', $info->pId); $model->set('params', $params->toString()); $model->store(); } catch (Exception $e) { $this->setError('ERROR: ' . $e->getMessage()); } } else { $warehouse = new StorefrontModelWarehouse(); try { // Get course by pID returned with $course->add() above $product = $warehouse->getCourse($params->get('store_product_id', 0)); $product->setName($title); $product->setDescription($description); $product->setPrice($price); $product->setTimeToLive($duration); if ($model->get('state') != 1) { $product->setActiveStatus(0); } else { $product->setActiveStatus(1); } $product->update(); } catch (Exception $e) { $this->setError('ERROR: ' . $e->getMessage()); } } } }
/** * Set the state of a course * * @param integer $state * @return void */ public function stateTask($state = 0) { // Check for request forgeries Request::checkToken(['get', 'post']); $state = $this->_task == 'publish' ? 1 : 0; // Incoming $ids = Request::getVar('id', array()); $ids = !is_array($ids) ? array($ids) : $ids; // Do we have any IDs? $num = 0; if (!empty($ids)) { // foreach course id passed in foreach ($ids as $id) { // Load the course page $course = \Components\Courses\Models\Course::getInstance($id); // Ensure we found the course info if (!$course->exists()) { continue; } //set the course to be published and update $course->set('state', $state); if (!$course->store()) { $this->setError(Lang::txt('COM_COURSES_ERROR_UNABLE_TO_SET_STATE', $id)); continue; } // Log the course approval $course->log($course->get('id'), 'course', $state ? 'published' : 'unpublished'); $num++; } } if ($this->getErrors()) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller, false), implode('<br />', $this->getErrors()), 'error'); } else { // Output messsage and redirect App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller, false), $state ? Lang::txt('COM_COURSES_ITEMS_PUBLISHED', $num) : Lang::txt('COM_COURSES_ITEMS_UNPUBLISHED', $num)); } }
/** * Get a course's availability * * @param object $course CoursesCourse * @return string */ private function courseAvailability($course = NULL) { //get the course $course = !is_null($course) ? $course : Request::getVar('course', ''); $course = strtolower(trim($course)); if ($course == '') { return; } // Ensure the data passed is valid $c = Models\Course::getInstance($course); if ($course == 'new' || $course == 'browse' || !$this->_validCn($course) || $c->exists()) { $availability = false; } else { $availability = true; } if (Request::getVar('no_html', 0) == 1) { echo json_encode(array('available' => $availability)); return; } else { return $availability; } }
/** * Track asset views * * @param object $course \Components\Courses\Models\Course * @return mixed */ public function logView($course = null) { require_once dirname(__DIR__) . DS . 'tables' . DS . 'asset.views.php'; if (!$course || !is_object($course)) { $gid = Request::getVar('gid'); $offering = Request::getVar('offering'); $section = Request::getVar('section'); $course = new Course($gid); $course->offering($offering); $course->offering()->section($section); } $member = $course->offering()->section()->member(User::get('id')); if (!$member->get('id')) { $member = $course->offering()->member(User::get('id')); } if (!$member || !is_object($member) || !$member->get('id')) { return false; } $view = new Tables\AssetViews($this->_db); $view->asset_id = $this->_tbl->id; $view->course_id = $this->get('course_id'); $view->viewed = Date::toSql(); $view->viewed_by = $member->get('id'); $view->ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; $view->url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; $view->referrer = isset($_SERVER['HTTP_REFERRER']) ? $_SERVER['HTTP_REFERRER'] : ''; $view->user_agent_string = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $view->session_id = App::get('session')->getId(); if (!$view->store()) { $this->setError($view->getError()); } }