/**
  * 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();
 }
 /**
  * Up
  **/
 public function up()
 {
     if (!$this->db->tableHasField('#__courses_members', 'token')) {
         $query = "ALTER TABLE `#__courses_members` ADD `token` VARCHAR(23)  NOT NULL  DEFAULT '';";
         $this->db->setQuery($query);
         $this->db->query();
         $path = PATH_APP . DS . 'site' . DS . 'courses' . DS . 'certificates';
         if (is_dir($path)) {
             require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'course.php';
             // Loop through all files and separate them into arrays of images, folders, and other
             $dirIterator = new DirectoryIterator($path);
             foreach ($dirIterator as $file) {
                 if ($file->isDot()) {
                     continue;
                 }
                 if ($file->isDir()) {
                     continue;
                 }
                 if ($file->isFile()) {
                     $name = $file->getFilename();
                     if ('cvs' == strtolower($name) || '.svn' == strtolower($name)) {
                         continue;
                     }
                     $bits = explode('_', $name);
                     if (count($bits) < 4) {
                         continue;
                     }
                     $course = $bits[1];
                     $offering = $bits[2];
                     $user = strstr($bits[3], '.', true);
                     $member = \Components\Courses\Models\Member::getInstance($user, $course, $offering, null);
                     $member->token();
                 }
             }
         }
     }
 }
Beispiel #3
0
 /**
  * Remove one or more user IDs or usernames to the managers list
  *
  * @param     array $value List of IDs or usernames
  * @return    void
  */
 public function remove($data = array())
 {
     if (!is_array($data)) {
         $data = array($data);
     }
     if (!$this->get('course_id')) {
         require_once __DIR__ . DS . 'offering.php';
         $offering = Offering::getInstance($this->get('offering_id'));
         $this->set('course_id', $offering->get('course_id'));
     }
     foreach ($data as $result) {
         $user_id = $this->_userId($result);
         $model = Member::getInstance($user_id, $this->get('course_id'), $this->get('offering_id'), $this->get('id'));
         if (!$model->exists()) {
             $this->setError(Lang::txt('Entry for user #%s, course #%s, offering #%s, section #%s not found.', $user_id, $this->get('course_id'), $this->get('offering_id'), $this->get('id')));
             continue;
         }
         if (!$model->delete()) {
             $this->setError($model->getError());
             continue;
         }
         if (isset($this->_members[$user_id])) {
             unset($this->_members[$user_id]);
         }
     }
 }
Beispiel #4
0
 /**
  * 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('offering', 0);
     if (!$id) {
         $this->setError(Lang::txt('COM_COURSES_ERROR_NO_ID'));
         $this->displayTask();
         return;
     }
     $section = Request::getInt('section', 0);
     $model = \Components\Courses\Models\Offering::getInstance($id);
     if ($section) {
         $model->section($section);
     }
     $entries = Request::getVar('entries', array(0), 'post');
     foreach ($entries as $key => $data) {
         // Retrieve user's account info
         $member = \Components\Courses\Models\Member::getInstance($data['id'], null, null, null);
         if ($member->get('role_id') == $data['role_id']) {
             continue;
         }
         $member->set('role_id', $data['role_id']);
         if (!$member->store()) {
             $this->setError($member->getError());
         }
     }
     // Push through to the hosts view
     $this->displayTask($model);
 }
Beispiel #5
0
 /**
  * Passport badges. Placeholder for now.
  *
  * @apiMethod POST
  * @apiUri    /courses/passport/badge
  * @apiParameter {
  * 		"name":        "action",
  * 		"description": "Badge action",
  * 		"type":        "string",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @apiParameter {
  * 		"name":        "badge_id",
  * 		"description": "Passport badge ID",
  * 		"type":        "integer",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @apiParameter {
  * 		"name":        "user_email",
  * 		"description": "Email address to which the badge was asserted",
  * 		"type":        "string",
  * 		"required":    true,
  * 		"default":     null
  * }
  * @return    void
  */
 public function badgeTask()
 {
     // Require authentication and authorization
     $this->authorizeOrFail();
     $action = Request::getVar('action', '');
     $badge_id = Request::getVar('badge_id', '');
     $user_email = Request::getVar('user_email', '');
     if (empty($action)) {
         App::abort(400, 'Please provide action');
     }
     if ($action != 'accept' && $action != 'deny') {
         App::abort(400, 'Bad action. Must be either accept or deny');
     }
     if (empty($badge_id)) {
         App::abort(400, 'Please provide badge ID');
     }
     if (empty($user_email)) {
         App::abort(400, 'Please provide user email');
     }
     // Find user by email
     $user = User::oneByEmail($user_email);
     if (!$user->get('id')) {
         App::abort(404, 'User was not found');
     }
     $user_id = $user->get('id');
     // Get section from provider badge id
     $section_badge = \Components\Courses\Models\Section\Badge::loadByProviderBadgeId($badge_id);
     // Check if there is a match
     if (!($section_id = $section_badge->get('section_id'))) {
         App::abort(400, 'No matching badge found');
     }
     // Get member id via user id and section id
     $member = \Components\Courses\Models\Member::getInstance($user_id, 0, 0, $section_id);
     // Check if there is a match
     if (!$member->get('id')) {
         App::abort(400, 'Matching course member not found');
     }
     // Now actually load the badge
     $member_badge = \Components\Courses\Models\MemberBadge::loadByMemberId($member->get('id'));
     // Check if there is a match
     if (!$member_badge->get('id')) {
         App::abort(400, 'This member does not have a matching badge entry');
     }
     $now = Date::toSql();
     $member_badge->set('action', $action);
     $member_badge->set('action_on', $now);
     $member_badge->store();
     // Return message
     $this->send('Passport data saved.');
 }
Beispiel #6
0
 /**
  * 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]);
 }
Beispiel #7
0
 /**
  * Add one or more user IDs or usernames to the managers list
  *
  * @param     array $value List of IDs or usernames
  * @return    void
  */
 public function add($data = array(), $role_id = 'student')
 {
     if (!is_array($data)) {
         $data = array($data);
     }
     $role = new Tables\Role($this->_db);
     $role->load($role_id);
     if (is_string($role_id)) {
         $role_id = $role->get('id');
     }
     foreach ($data as $result) {
         $user_id = (int) $this->_userId($result);
         $model = Member::getInstance($user_id, $this->get('course_id'), $this->get('id'), $this->section()->get('id'));
         $model->set('user_id', $user_id);
         $model->set('course_id', $this->get('course_id'));
         $model->set('offering_id', $this->get('id'));
         $model->set('section_id', $this->section()->get('id'));
         $model->set('role_id', $role_id);
         if ($role->get('alias') == 'student') {
             $model->set('student', 1);
         }
         if (!$model->store()) {
             $this->setError($model->getError());
             continue;
         }
         $this->_managers[$user_id] = $model;
     }
 }
Beispiel #8
0
 /**
  * Saves data to the database
  *
  * @return void
  */
 public function saveTask($redirect = true)
 {
     // Check for request forgeries
     Request::checkToken();
     // Incoming
     $fields = Request::getVar('fields', array(), 'post');
     if (strstr($fields['user_id'], ',')) {
         $user_ids = explode(',', $fields['user_id']);
         $user_ids = array_map('trim', $user_ids);
     } else {
         $user_ids = array($fields['user_id']);
     }
     $offering = Request::getInt('offering', 0);
     if (!$offering && isset($fields['offering_id'])) {
         $offering = $fields['offering_id'];
     }
     $offeringObj = \Components\Courses\Models\Offering::getInstance($offering);
     $c = 0;
     foreach ($user_ids as $user_id) {
         if (!is_int($user_id)) {
             $user = User::getInstance($user_id);
             if (!is_object($user)) {
                 \Notify::error(Lang::txt('COM_COURSES_ERROR_USER_NOTFOUND') . ' ' . $user_id);
                 $this->editTask();
                 return;
             }
             $fields['user_id'] = $user->get('id');
         } else {
             $fields['user_id'] = $user_id;
         }
         // Instantiate the model
         $fields['course_id'] = $offeringObj->get('course_id');
         //$section_id = $offeringObj->section()->get('id');
         //$model = \Components\Courses\Models\Member::getInstance($fields['user_id'], $fields['course_id'], $offering, $section_id);
         $model = \Components\Courses\Models\Member::getInstance($fields['user_id'], $fields['course_id'], null, null);
         // Is there an existing record and are they a student?
         if ($model->exists() && !$model->get('student')) {
             \Notify::error(Lang::txt('COM_COURSES_ERROR_ALREADY_COURSE_MANAGER', $user_id));
             continue;
         }
         // If the section is the same
         if ($model->exists() && $model->get('section_id') == $fields['section_id']) {
             \Notify::warning(Lang::txt('COM_COURSES_ERROR_ALREADY_STUDENT', $user_id));
             continue;
         }
         // Ensure it's a new record as the check above
         // could pull a record for another section
         $model->set('id', null);
         // Safe to proceed...
         // Bind posted data
         if (!$model->bind($fields)) {
             \Notify::error($model->getError());
             $this->editTask($model);
             return;
         }
         // Store data
         if (!$model->store()) {
             \Notify::error($model->getError());
             $this->editTask($model);
             return;
         }
     }
     if (count($user_ids) > 1) {
         $redirect = true;
     }
     // Are we redirecting?
     if ($redirect) {
         // Output messsage and redirect
         App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&offering=' . $fields['offering_id'] . '&section=' . $fields['section_id'], false), $c > 0 ? Lang::txt('COM_COURSES_STUDENTS_SAVED', $c) : null);
         return;
     }
     // Display edit form with posted data
     $this->editTask($model);
 }