/** * Test successful program enrolment creation. */ public function test_success() { global $DB; $this->give_permissions(array('local/elisprogram:program_enrol')); // Initialize version1elis importplugin for utility functions. $importplugin = rlip_dataplugin_factory::factory('dhimport_version1elis'); // Create test program. $datagen = new elis_program_datagenerator($DB); $program = $datagen->create_program(array('idnumber' => 'TestProgramEnrolmentCreate')); $userid = $DB->get_field(user::TABLE, 'id', array('username' => 'assigninguser')); // Create the program enrolment record to delete. $stucur = new curriculumstudent(array('curriculumid' => $program->id, 'userid' => $userid)); $stucur->save(); // Perform enrolment delete. $data = array('program_idnumber' => $program->idnumber, 'user_username' => 'assigninguser', 'user_email' => '*****@*****.**'); $response = local_datahub_elis_program_enrolment_delete::program_enrolment_delete($data); $this->assertNotEmpty($response); $this->assertInternalType('array', $response); $this->assertArrayHasKey('messagecode', $response); $this->assertArrayHasKey('message', $response); $this->assertEquals(get_string('ws_program_enrolment_delete_success_code', 'local_datahub'), $response['messagecode']); $this->assertEquals(get_string('ws_program_enrolment_delete_success_msg', 'local_datahub'), $response['message']); $this->assertFalse($DB->record_exists(curriculumstudent::TABLE, array('curriculumid' => $program->id, 'userid' => $userid))); }
/** * List the certificates available to be printed. * @return unknown_type */ function action_default() { global $CFG, $USER, $CURMAN; // This is for a Moodle user, so get the Curriculum user id. $cuserid = cm_get_crlmuserid($USER->id); $curasses = curriculumstudent::get_completed_for_user($cuserid); if (count($curasses) == 0) { print_string('certificates_none_earned', 'block_curr_admin'); return; } print_string('certificates_earned', 'block_curr_admin'); echo "<UL>\n"; foreach ($curasses as $curass) { echo "<LI><a href=\"certificate.php?id={$curass->id}\">{$curass->curriculum->name}</a>\n"; } echo "</UL>\n"; }
/** * Perform all necessary tasks to add a student enrolment to the system. * * @param array $checks what checks to perform before adding enrolling the * user. e.g. array('prereq' => 1, 'waitlist' => 1) will check that * prerequisites are satisfied, and that the class is not full * @param boolean $notify whether or not notifications should be sent if a * check fails */ function add($checks = array(), $notify = false) { global $CURMAN, $CFG, $USER; $status = true; if ($CURMAN->db->record_exists(STUTABLE, 'userid', $this->userid, 'classid', $this->classid)) { // already enrolled -- pretend we succeeded return true; } // check that the student can be enrolled first if (!empty($checks['prereq'])) { // check prerequisites $cmclass = new cmclass($this->classid); // get all the curricula that the user is in $curricula = curriculumstudent::get_curricula($this->userid); foreach ($curricula as $curriculum) { $curcrs = new curriculumcourse(); $curcrs->courseid = $cmclass->courseid; $curcrs->curriculumid = $curriculum->curid; if (!$curcrs->prerequisites_satisfied($this->userid)) { // prerequisites not satisfied if ($notify) { $data = new stdClass(); $data->userid = $this->userid; $data->classid = $this->classid; //$data->trackid = $trackid; events_trigger('crlm_prereq_unsatisfied', $data); } $status = new Object(); $status->message = get_string('unsatisfiedprereqs', 'block_curr_admin'); $status->code = 'unsatisfiedprereqs'; return $status; } } } if (!empty($checks['waitlist'])) { // check class enrolment limit $cmclass = new cmclass($this->classid); $limit = $cmclass->maxstudents; if (!empty($limit) && $limit <= student::count_enroled($this->classid)) { // class is full // put student on wait list $wait_list = new waitlist($this); $wait_list->timecreated = time(); $wait_list->position = 0; $wait_list->add(); if ($notify) { $subject = get_string('user_waitlisted', 'block_curr_admin'); $a = new object(); $a->user = $this->user->idnumber; $a->cmclass = $cmclass->idnumber; $message = get_string('user_waitlisted_msg', 'block_curr_admin', $a); $from = $user = get_admin(); notification::notify($message, $user, $from); email_to_user($user, $from, $subject, $message); } $status = new Object(); $status->message = get_string('user_waitlisted', 'block_curr_admin'); $status->code = 'user_waitlisted'; return $status; } } //set end time based on class duration $studentclass = new cmclass($this->classid); if (empty($this->endtime)) { if (isset($studentclass->duration) && $studentclass->duration) { $this->endtime = $this->enrolmenttime + $studentclass->duration; } else { // no class duration -> no end time $this->endtime = 0; } } $status = $this->data_insert_record(); // TBD: we should check this! /// Get the Moodle user ID or create a new account for this user. if (!($muserid = cm_get_moodleuserid($this->userid))) { $user = new user($this->userid); if (!($muserid = $user->synchronize_moodle_user(true, true))) { $status = new Object(); $status->message = get_string('errorsynchronizeuser', 'block_curr_admin'); $muserid = false; } } /// Enrol them into the Moodle class. if ($moodlecourseid = moodle_get_course($this->classid)) { if ($mcourse = get_record('course', 'id', $moodlecourseid)) { $enrol = $mcourse->enrol; if (!$enrol) { $enrol = $CFG->enrol; } if ($CURMAN->config->restrict_to_elis_enrolment_plugin && $enrol != 'elis') { $status = new Object(); $status->message = get_string('error_not_using_elis_enrolment', 'block_curr_admin'); return $status; } $timestart = $this->enrolmenttime; $timeend = $this->endtime; if ($role = get_default_course_role($mcourse)) { $context = get_context_instance(CONTEXT_COURSE, $mcourse->id); if (!empty($muserid)) { if (!role_assign($role->id, $muserid, 0, $context->id, $timestart, $timeend, 0, 'manual')) { $status = new Object(); $status->message = get_string('errorroleassign', 'block_curr_admin'); } } } } } else { if (!empty($muserid)) { $sturole = $CURMAN->config->enrolment_role_sync_student_role; // ELIS-2776: must still trigger events for notifications $ra = new stdClass(); $ra->roleid = !empty($sturole) ? $sturole : get_field('role', 'id', 'shortname', 'student'); $ra->contextid = context_level_base::get_custom_context_level('class', 'block_curr_admin'); // TBD $ra->userid = $muserid; $ra->component = ''; // TBD: 'enrol_elis' $ra->itemid = $this->classid; // TBD $ra->timemodified = time(); $ra->modifierid = empty($USER->id) ? 0 : $USER->id; events_trigger('role_assigned', $ra); } } return $status; }
/** * Enrols a user in a track. * * @param int $userid The user id * @param int $trackid The track id */ public static function enrol($userid, $trackid) { global $DB; // make sure we don't double-enrol if ($DB->record_exists(self::TABLE, array('userid' => $userid, 'trackid' => $trackid))) { return false; } $record = new usertrack(); $record->userid = $userid; $record->trackid = $trackid; $record->save(); $user = new user($userid); $track = new track($trackid); if (!$DB->record_exists(curriculumstudent::TABLE, array('userid' => $userid, 'curriculumid' => $track->curid))) { $curstu = new curriculumstudent(); $curstu->userid = $userid; $curstu->curriculumid = $track->curid; $curstu->completed = 0; $curstu->credits = 0; $curstu->locked = 0; $curstu->save(); } events_trigger('track_assigned', $record); /** * Get autoenrollable classes in the track. Classes are autoenrollable * if: * - the autoenrol flag is set * - it is the only class in that course slot for the track */ $sql = 'SELECT classid, courseid ' . 'FROM {' . trackassignment::TABLE . '} ' . 'WHERE trackid = ? ' . 'GROUP BY courseid ' . 'HAVING COUNT(*) = 1 AND MAX(autoenrol) = 1'; $params = array($trackid); $classes = $DB->get_recordset_sql($sql, $params); foreach ($classes as $class) { // ELIS-3460: check pre-requisites ... $curcrs = new curriculumcourse(array('courseid' => $class->courseid, 'curriculumid' => $track->curid)); if (!$curcrs->prerequisites_satisfied($userid)) { //error_log("/local/elisprogram/lib/data/usertrack.class.php::enrol({$userid}); pre-requisites NOT satisfied for course: {$class->courseid}, curriculum: {$track->curid}"); continue; } $now = time(); // enrol user in each autoenrolable class $stu_record = new object(); $stu_record->userid = $userid; $stu_record->classid = $class->classid; $stu_record->enrolmenttime = $now; $enrolment = new student($stu_record); // catch enrolment limits try { $status = $enrolment->save(); } catch (pmclass_enrolment_limit_validation_exception $e) { // autoenrol into waitlist $wait_record = new object(); $wait_record->userid = $userid; $wait_record->classid = $class->classid; $wait_record->enrolmenttime = $now; $wait_record->timecreated = $now; $wait_record->position = 0; $wait_list = new waitlist($wait_record); $wait_list->save(); $status = true; } catch (Exception $e) { $param = array('message' => $e->getMessage()); echo cm_error(get_string('record_not_created_reason', 'local_elisprogram', $param)); } } unset($classes); return true; }
/** * Function to handle curriculum completed events. * * @param curriculumstudent $student The curriculum-student entry to mark as completed * * @return boolean TRUE is successful, otherwise FALSE */ public static function curriculum_completed_handler($student) { return $student->complete(); }
protected function process_unassignment($data) { global $CURMAN; $curid = $data->id; foreach ($data->_selection as $associd) { $curstu = new curriculumstudent($associd); if ($curstu->curriculumid == $curid) { // sanity check $curstu->delete(); } } $tmppage = $this->get_basepage(); redirect($tmppage->get_url(), get_string('num_users_unassigned', 'block_curr_admin', count($data->_selection))); }
/** * Validate that mappings are applied during the program enrolment delete action */ public function test_mapping_applied_during_program_enrolment_delete() { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/data/curriculum.class.php'; require_once $CFG->dirroot . '/local/elisprogram/lib/data/curriculumstudent.class.php'; $this->init_mapping(); $userid = $this->create_test_user(); $program = new curriculum(array('idnumber' => 'testprogramidnumber')); $program->save(); $curriculumstudent = new curriculumstudent(array('curriculumid' => $program->id, 'userid' => $userid)); $curriculumstudent->save(); // Run the program enrolment delete action. $record = new stdClass(); $record->customaction = 'delete'; $record->customcontext = 'curriculum_testprogramidnumber'; $record->customuser_username = '******'; $record->customuser_email = '*****@*****.**'; $record->customuser_idnumber = 'testuseridnumber'; $this->run_enrolment_import((array) $record); // Validation. $this->assertEquals(0, $DB->count_records(curriculumstudent::TABLE)); }
/** * Transforms each result. * @param array $row An array for a single result. * @return array The transformed result. */ protected function results_row_transform(array $row) { $row = parent::results_row_transform($row); // Whether the user can unassign from the program at all. static $canunassignany = null; // Whether the user can unassin any user from the program. static $canunassignall = null; // If not already set, determine whether the user can do any unassigning. if ($canunassignany === null) { $canunassignany = curriculumpage::can_enrol_into_curriculum($this->programid); } // If not already set, determine whether the user can unassign anyone - but only if $canunassignany is true. if ($canunassignany === true && $canunassignall === null) { $cpage = new curriculumpage(); if ($cpage->_has_capability('local/elisprogram:program_enrol', $this->programid)) { $canunassignall = true; } } // Set the 'canunassign' parameter for use in javascript. if ($canunassignall === true) { $row['canunassign'] = '1'; } else { if ($canunassignany === true) { $row['canunassign'] = curriculumstudent::can_manage_assoc($row['element_id'], $this->programid) === true ? '1' : '0'; } else { $row['canunassign'] = '0'; } } return $row; }
/** * Check for any curriculum completed nags that need to be handled. */ public static function check_for_completed_nags() { global $CFG, $CURMAN; /// Completed curricula: $select = "SELECT cce.id as id, cce.credits AS curcredits, " . "cur.id as curid, cur.reqcredits as reqcredits, " . "cca.id as curassid, cca.userid, cca.curriculumid, cca.completed, cca.timecompleted, " . "cca.credits, cca.locked, cca.timecreated, cca.certificatecode, cca.timemodified, " . "cca.timeexpired, ccc.courseid as courseid "; /// >* This will return ALL class enrolment records for a user's curriculum assignment. $from = "FROM {$CFG->prefix}crlm_curriculum_assignment cca "; $join = "INNER JOIN {$CFG->prefix}crlm_user cu ON cu.id = cca.userid " . "INNER JOIN {$CFG->prefix}crlm_curriculum cur ON cca.curriculumid = cur.id " . "INNER JOIN {$CFG->prefix}crlm_curriculum_course ccc ON ccc.curriculumid = cur.id " . "INNER JOIN {$CFG->prefix}crlm_course cco ON cco.id = ccc.courseid " . "INNER JOIN {$CFG->prefix}crlm_class ccl ON ccl.courseid = cco.id " . "INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON (cce.classid = ccl.id) AND (cce.userid = cca.userid) "; /// >* $where = "WHERE (cca.completed = 0) AND (cce.completestatusid != " . STUSTATUS_NOTCOMPLETE . ") "; $order = "ORDER BY cur.id, cca.id ASC "; //$groupby = "GROUP BY cca.id HAVING numcredits > cur.reqcredits "; /// The "HAVING" clause limits the returns to completed CURRICULA only. $groupby = ''; $sql = $select . $from . $join . $where . $groupby . $order; $curassid = 0; $curid = 0; $numcredits = 0; $reqcredits = 10000; /// Initially so a completion event is not triggered. $requiredcourseids = array(); $checkcourses = $requiredcourseids; $context = false; $curasstempl = new curriculumstudent(); // used just for its properties. $studenttempl = new student(); // used just for its properties. $timenow = time(); $secondsinaday = 60 * 60 * 24; $rs = get_recordset_sql($sql); if ($rs) { while ($rec = rs_fetch_next_record($rs)) { /// Loop through enrolment records grouped by curriculum and curriculum assignments, /// counting the credits achieved and looking for all required courses to be complete. /// Load a new curriculum assignment if ($curassid != $rec->curassid) { /// Check for completion - all credits have been earned and all required courses completed if ($curassid && $numcredits >= $reqcredits && empty($checkcourses)) { $currstudent->complete($timenow, $numcredits, 1); } $curassid = $rec->curassid; $curassdata = array(); foreach ($curasstempl->properties as $prop => $type) { $curassdata[$prop] = $rec->{$prop}; } $curassdata['id'] = $rec->curassid; $currstudent = new curriculumstudent($curassdata); $numcredits = 0; $checkcourses = $requiredcourseids; } /// Get a new list of required courses. if ($curid != $rec->curid) { $curid = $rec->curid; $reqcredits = $rec->reqcredits; $select = 'curriculumid = ' . $curid . ' AND required = 1'; if (!($requiredcourseids = get_records_select('crlm_curriculum_course', $select, '', 'courseid,required'))) { $requiredcourseids = array(); } $checkcourses = $requiredcourseids; } /// Track data for completion... $numcredits += $rec->curcredits; if (isset($checkcourses[$rec->courseid])) { unset($checkcourses[$rec->courseid]); } } } /// Check for last record completion - all credits have been earned and all required courses completed if ($curassid && $numcredits >= $reqcredits && empty($checkcourses)) { $currstudent->complete($timenow, $numcredits, 1); } $sendtouser = $CURMAN->config->notify_curriculumnotcompleted_user; $sendtorole = $CURMAN->config->notify_curriculumnotcompleted_role; $sendtosupervisor = $CURMAN->config->notify_curriculumnotcompleted_supervisor; /// If nobody receives a notification, we're done. if (!$sendtouser && !$sendtorole && !$sendtosupervisor) { return true; } /// Incomplete curricula: $select = "SELECT cca.id as id, cca.userid, cca.curriculumid, cca.completed, cca.timecompleted, " . "cca.credits, cca.locked, cca.timecreated, cca.timemodified, " . "cur.id as curid, cur.timetocomplete as timetocomplete "; /// >* This will return ALL class enrolment records for a user's curriculum assignment. $from = "FROM {$CFG->prefix}crlm_curriculum_assignment cca "; $join = "INNER JOIN {$CFG->prefix}crlm_user cu ON cu.id = cca.userid " . "INNER JOIN {$CFG->prefix}crlm_curriculum cur ON cca.curriculumid = cur.id " . "LEFT JOIN {$CFG->prefix}crlm_notification_log cnl ON cnl.fromuserid = cu.id AND cnl.instance = cca.id AND " . "cnl.event = 'curriculum_notcompleted' "; $where = "WHERE (cca.completed = 0) AND (cur.timetocomplete != '') AND (cur.timetocomplete NOT LIKE '0h, 0d, 0w, 0m, 0y%') AND cnl.id IS NULL "; $order = "ORDER BY cur.id, cca.id ASC "; $groupby = ''; $sql = $select . $from . $join . $where . $groupby . $order; $context = false; $curasstempl = new curriculumstudent(); // used just for its properties. $studenttempl = new student(); // used just for its properties. $timenow = time(); $secondsinaday = 60 * 60 * 24; $rs = get_recordset_sql($sql); if ($rs) { while ($rec = rs_fetch_next_record($rs)) { /// Loop through curriculum assignments checking for nags. $deltad = new datedelta($rec->timetocomplete); /// Need to fit this into the SQL instead. $reqcompletetime = $rec->timecreated + $deltad->gettimestamp(); /// If no time to completion set, it has no completion restriction. if ($reqcompletetime == 0) { continue; } $daysfrom = ($reqcompletetime - $timenow) / $secondsinaday; if ($daysfrom <= $CURMAN->config->notify_curriculumnotcompleted_days) { $curstudent = new curriculumstudent($rec); mtrace("Triggering curriculum_notcompleted event.\n"); events_trigger('curriculum_notcompleted', $curstudent); } } } return true; }
/** * List the certificates available to be printed. * TODO: Figure out a better way of displaying all of the cert entity types */ public function display_default() { global $CFG, $USER, $OUTPUT; // This is for a Moodle user, so get the Curriculum user id. $cuserid = cm_get_crlmuserid($USER->id); $link = ''; $attributes = array(); $text = ''; if (empty($cuserid)) { print_error('notelisuser', 'local_elisprogram'); } if (empty(elis::$config->local_elisprogram->disablecertificates)) { $curasses = curriculumstudent::get_completed_for_user($cuserid); if (count($curasses) == 0) { print_string('certificates_none_earned', 'local_elisprogram'); } else { print_string('certificates_earned', 'local_elisprogram'); echo html_writer::start_tag('ul'); foreach ($curasses as $curass) { $attributes['href'] = 'certificate.php?id=' . $curass->id; $attributes['target'] = '_blank'; $text = $curass->curriculum->name; $link = html_writer::tag('a', $text, $attributes); echo html_writer::tag('li', $link); } echo html_writer::end_tag('ul'); } } if (isset(elis::$config->local_elisprogram->disablecoursecertificates) && empty(elis::$config->local_elisprogram->disablecoursecertificates)) { $records = get_user_certificates($cuserid); $this->display_entity_certificates($records); $records->close(); } }
/** * Enrols a user in a track. * * @param int $userid The user id * @param int $trackid The track id */ static function enrol($userid, $trackid) { global $CURMAN; // make sure we don't double-enrol if ($CURMAN->db->record_exists(USRTRKTABLE, 'userid', $userid, 'trackid', $trackid)) { return false; } $record = new usertrack(); $record->userid = $userid; $record->trackid = $trackid; $record->data_insert_record(); $user = new user($userid); $track = new track($trackid); // add the student to the associated curriculum, if they're not already // enrolled if (!$CURMAN->db->record_exists(CURASSTABLE, 'userid', $userid, 'curriculumid', $track->curid)) { $curstu = new curriculumstudent(); $curstu->userid = $userid; $curstu->curriculumid = $track->curid; $curstu->completed = 0; $curstu->credits = 0; $curstu->locked = 0; $curstu->add(); } events_trigger('track_assigned', $record); /** * Get autoenrollable classes in the track. Classes are autoenrollable * if: * - the autoenrol flag is set * - it is the only class in that course slot for the track */ $sql = 'SELECT classid, courseid ' . 'FROM ' . $CURMAN->db->prefix_table(TRACKCLASSTABLE) . ' ' . 'WHERE trackid = \'' . $trackid . '\' ' . 'GROUP BY courseid ' . 'HAVING COUNT(*) = 1 AND MAX(autoenrol) = 1'; $classes = $CURMAN->db->get_records_sql($sql); if (!empty($classes)) { foreach ($classes as $class) { // enrol user in each autoenrolable class $stu_record = new object(); $stu_record->userid = $userid; $stu_record->classid = $class->classid; $stu_record->enrolmenttime = time(); $enrolment = new student($stu_record); // check prerequisites and enrolment limits $enrolment->add(array('prereq' => 1, 'waitlist' => 1), true); } } return true; }
/** * Test check_for_completed_nags function with completion time in the past. */ public function test_checkforcompletednagsdate() { global $DB; $dataset = $this->createCsvDataSet(array(user::TABLE => elispm::file('tests/fixtures/pmuser.csv'), curriculum::TABLE => elispm::file('tests/fixtures/curriculum.csv'), curriculumstudent::TABLE => elispm::file('tests/fixtures/curriculum_student.csv'), course::TABLE => elispm::file('tests/fixtures/pmcourse.csv'), curriculumcourse::TABLE => elispm::file('tests/fixtures/curriculum_course.csv'), pmclass::TABLE => elispm::file('tests/fixtures/pmclass.csv'), student::TABLE => elispm::file('tests/fixtures/student.csv'))); $this->loadDataSet($dataset); // Set the course to be required in the program. $sql = "UPDATE {" . curriculumcourse::TABLE . "} SET required = 1 WHERE curriculumid = 1 AND courseid = 100"; $DB->execute($sql); // Set the completion time to a month ago and status to completed on the class enrolment. $completetime = time() - 2592000; $sql = 'UPDATE {' . student::TABLE . '} SET completetime = ' . $completetime . ', completestatusid = 2 WHERE userid = 103 AND classid = 100'; $DB->execute($sql); // Execute check_for_completed_nags. $curriculum = new curriculum(1); $curriculum->load(); $result = $curriculum->check_for_completed_nags(); // Verify completion time in program assignment table. $recordset = curriculumstudent::get_curricula(103); foreach ($recordset as $record) { $this->assertEquals(1, $record->curid); $this->assertEquals($completetime, $record->timecompleted); } }
function curriculum_enrolment_delete($record, $filename, $idnumber) { global $DB, $CFG; if (!($curid = $DB->get_field(curriculum::TABLE, 'id', array('idnumber' => $idnumber)))) { $this->fslogger->log_failure("instance value of \"{$idnumber}\" does not refer to a valid instance of a program context.", 0, $filename, $this->linenumber, $record, "enrolment"); return false; } if (!$this->validate_program_enrolment_data('delete', $record, $filename)) { return false; } $userid = $this->get_userid_from_record($record, $filename); $associd = $DB->get_field(curriculumstudent::TABLE, 'id', array('userid' => $userid, 'curriculumid' => $curid)); $stucur = new curriculumstudent(array('id' => $associd)); $stucur->delete(); //string to describe the user $user_descriptor = $this->get_user_descriptor($record, false, 'user_'); //log success $success_message = "User with {$user_descriptor} successfully unenrolled from program \"{$idnumber}\"."; $this->fslogger->log_success($success_message, 0, $filename, $this->linenumber); return true; }
/** * curriculum overview menu * * @global object $CFG * @global object $USER * @global object $CURMAN */ function action_available() { global $CFG, $USER, $CURMAN; /// This is for a Moodle user, so get the Curriculum user id. $cuserid = cm_get_crlmuserid($USER->id); $usercurs = curriculumstudent::get_curricula($cuserid); if (count($usercurs) > $CURMAN->config->catalog_collapse_count) { $buttonLabel = get_string('show', 'block_curr_admin'); $extraclass = ' hide'; } else { $buttonLabel = get_string('hide', 'block_curr_admin'); $extraclass = ''; } require_js($CFG->wwwroot . '/curriculum/js/util.js'); $this->include_yui(); // Process this user's curricula in turn, outputting the courses within each. if ($usercurs) { foreach ($usercurs as $usercur) { print_heading('<div class="clearfix"></div><div class="headermenu"><script id="curriculum' . $usercur->curid . 'script" type="text/javascript">toggleVisibleInit("curriculum' . $usercur->curid . 'script", "curriculum' . $usercur->curid . 'button", "' . $buttonLabel . '", "Hide", "Show", "curriculum' . $usercur->curid . '");</script></div>' . $usercur->name . ' (' . $usercur->idnumber . ')'); echo '<div id="curriculum' . $usercur->curid . '" class="yui-skin-sam ' . $extraclass . '">'; if ($courses = user::get_user_course_curriculum($cuserid, $usercur->curid)) { echo "<div id=\"{$usercur->id}\"></div>"; $table = new availablecoursetable($courses); $table->print_yui_table($usercur->id); } else { echo '<p>' . get_string('nocoursesinthiscurriculum', 'block_curr_admin') . '</p>'; } echo '</div>'; } } else { print_heading(get_string('nocoursesinthiscurriculum', 'block_curr_admin')); } echo '<br/>'; print_box(get_string('lp_curriculum_instructions', 'block_curr_admin'), 'generalbox lp_instructions'); }
/** * Check for any curriculum completed nags that need to be handled. * @return boolean True if successful, otherwise false. */ public static function check_for_completed_nags() { global $CFG, $DB; // Completed curricula: $select = 'SELECT cce.id as id, cce.credits AS curcredits, cce.completetime AS clscomplete, cur.id as curid, cur.reqcredits as reqcredits, cca.id as curassid, cca.userid, cca.curriculumid, cca.completed, cca.timecompleted, cca.credits, cca.locked, cca.timecreated, cca.timemodified, cca.timeexpired, ccc.courseid as courseid, ccc.required AS crsrequired '; // >* This will return ALL class enrolment records for a user's curriculum assignment. $from = 'FROM {' . curriculumstudent::TABLE . '} cca '; $join = 'INNER JOIN {' . user::TABLE . '} cu ON cu.id = cca.userid INNER JOIN {' . curriculum::TABLE . '} cur ON cca.curriculumid = cur.id INNER JOIN {' . curriculumcourse::TABLE . '} ccc ON ccc.curriculumid = cur.id INNER JOIN {' . course::TABLE . '} cco ON cco.id = ccc.courseid INNER JOIN {' . pmclass::TABLE . '} ccl ON ccl.courseid = cco.id INNER JOIN {' . student::TABLE . '} cce ON (cce.classid = ccl.id) AND (cce.userid = cca.userid) '; // >* $where = 'WHERE (cca.completed = 0) AND (cce.completestatusid != ' . STUSTATUS_NOTCOMPLETE . ') '; $order = 'ORDER BY cur.id, cca.id ASC '; $sql = $select . $from . $join . $where . $order; $curassid = 0; $curid = 0; $numcredits = 0; $reqcredits = 10000; // Initially so a completion event is not triggered. $requiredcourseids = array(); $checkcourses = $requiredcourseids; $context = false; $timenow = 0; $timerun = time(); $secondsinaday = 60 * 60 * 24; $rs = $DB->get_recordset_sql($sql); if ($rs) { foreach ($rs as $rec) { // Loop through enrolment records grouped by curriculum and curriculum assignments, // counting the credits achieved and looking for all required courses to be complete. // Load a new curriculum assignment. if ($curassid != $rec->curassid) { // Check for completion - all credits have been earned and all required courses completed. if ($curassid && $numcredits >= $reqcredits && empty($checkcourses)) { $currstudent->complete($timenow ? $timenow : $timerun, $numcredits, 1); $timenow = 0; } $curassid = $rec->curassid; $currstudent = new curriculumstudent($rec->curassid); $currstudent->load(); $numcredits = 0; $checkcourses = $requiredcourseids; } if (!empty($rec->crsrequired) && $rec->clscomplete > $timenow) { $timenow = $rec->clscomplete; } // Get a new list of required courses. if ($curid != $rec->curid) { $curid = $rec->curid; $reqcredits = $rec->reqcredits; $select = 'curriculumid = ' . $curid . ' AND required = 1'; if (!($requiredcourseids = $DB->get_records_select(curriculumcourse::TABLE, $select, null, '', 'courseid,required'))) { $requiredcourseids = array(); } $checkcourses = $requiredcourseids; } // Track data for completion... $numcredits += $rec->curcredits; if (isset($checkcourses[$rec->courseid])) { unset($checkcourses[$rec->courseid]); } } } // Check for last record completion - all credits have been earned and all required courses completed. if ($curassid && $numcredits >= $reqcredits && empty($checkcourses)) { $currstudent->complete($timenow ? $timenow : $timerun, $numcredits, 1); } $sendtouser = elis::$config->local_elisprogram->notify_curriculumnotcompleted_user; $sendtorole = elis::$config->local_elisprogram->notify_curriculumnotcompleted_role; $sendtosupervisor = elis::$config->local_elisprogram->notify_curriculumnotcompleted_supervisor; // If nobody receives a notification, we're done. if (!$sendtouser && !$sendtorole && !$sendtosupervisor) { return true; } // Incomplete curricula: $select = 'SELECT cca.id as id, cca.userid, cca.curriculumid, cca.completed, cca.timecompleted, cca.credits, cca.locked, cca.timecreated, cca.certificatecode, cca.timemodified, cur.id as curid, cur.timetocomplete as timetocomplete '; $from = 'FROM {' . curriculumstudent::TABLE . '} cca '; $join = 'INNER JOIN {' . user::TABLE . '} cu ON cu.id = cca.userid INNER JOIN {' . curriculum::TABLE . '} cur ON cca.curriculumid = cur.id LEFT JOIN {' . notificationlog::TABLE . '} cnl ON cnl.fromuserid = cu.id AND cnl.instance = cca.id AND cnl.event = \'curriculum_notcompleted\' '; $where = 'WHERE (cca.completed = 0) AND (cur.timetocomplete != \'\') AND (cur.timetocomplete NOT LIKE \'0h, 0d, 0w, 0m, 0y%\') AND cnl.id IS NULL '; $order = 'ORDER BY cur.id, cca.id ASC '; $sql = $select . $from . $join . $where . $order; $context = false; $timenow = time(); $secondsinaday = 60 * 60 * 24; $rs = $DB->get_recordset_sql($sql); if ($rs) { foreach ($rs as $rec) { // Loop through curriculum assignments checking for nags. $deltad = new datedelta($rec->timetocomplete); // Need to fit this into the SQL instead. $reqcompletetime = $rec->timecreated + $deltad->gettimestamp(); // If no time to completion set, it has no completion restriction. if ($reqcompletetime == 0) { continue; } $daysfrom = ($reqcompletetime - $timenow) / $secondsinaday; if ($daysfrom <= elis::$config->local_elisprogram->notify_curriculumnotcompleted_days) { events_trigger('curriculum_notcompleted', $rec); } } } return true; }
public function delete() { global $CFG; $muser = $this->get_moodleuser(); if (empty($muser) || !is_primary_admin($muser->id)) { // delete associated data require_once elis::lib('data/data_filter.class.php'); $filter = new field_filter('userid', $this->id); curriculumstudent::delete_records($filter, $this->_db); student::delete_records($filter, $this->_db); student_grade::delete_records($filter, $this->_db); waitlist::delete_records($filter, $this->_db); instructor::delete_records($filter, $this->_db); usertrack::delete_records($filter, $this->_db); clusterassignment::delete_records($filter, $this->_db); //delete association to Moodle user, if applicable require_once elispm::lib('data/usermoodle.class.php'); $filter = new field_filter('cuserid', $this->id); usermoodle::delete_records($filter, $this->_db); // Delete Moodle user. if (!empty($muser)) { delete_user($muser); } parent::delete(); $context = \local_elisprogram\context\user::instance($this->id); $context->delete(); } }
function assign_curriculum($curdata) { global $CFG, $CURMAN; require_once $CFG->dirroot . '/curriculum/lib/curriculum.class.php'; require_once $CFG->dirroot . '/curriculum/lib/curriculumstudent.class.php'; if (is_object($curdata)) { if (get_class($curdata) == 'curriculum') { $curid = $curdata->id; } else { /// Don't know what to do. return false; } } else { if (is_array($curdata)) { $select = ''; foreach ($curdata as $field => $value) { if (!empty($select)) { $select .= ' AND '; } $select .= '(' . $field . ' = \'' . $value . '\')'; } if (!($curid = $CURMAN->db->get_field_select(CURTABLE, 'id', $select))) { /// Don't know what to do. return false; } } } if (!$CURMAN->db->record_exists(CURASSTABLE, 'userid', $this->id, 'curriculumid', $curid)) { $student = new curriculumstudent(); $student->userid = $this->id; $student->curriculumid = $curid; return $student->data_insert_record(); } return true; }
/** * curriculum overview menu * * @uses $OUTPUT * @uses $PAGE * @uses $USER */ function display_available() { // action_available() global $OUTPUT, $PAGE, $USER; /// This is for a Moodle user, so get the Curriculum user id. $cuserid = cm_get_crlmuserid($USER->id); $usercurs = curriculumstudent::get_curricula($cuserid); if (count($usercurs) > elis::$config->local_elisprogram->catalog_collapse_count) { $buttonLabel = get_string('show'); $extraclass = ' hide'; } else { $buttonLabel = get_string('hide'); $extraclass = ''; } // Needed for the hide buttons $this->include_js(); // Process this user's curricula in turn, outputting the courses within each. if ($usercurs) { foreach ($usercurs as $usercur) { echo $OUTPUT->heading('<div class="clearfix"></div><div class="headermenu"><script id="curriculum' . $usercur->curid . 'script" type="text/javascript">toggleVisibleInit("curriculum' . $usercur->curid . 'script", "curriculum' . $usercur->curid . 'button", "' . $buttonLabel . '", "Hide", "Show", "curriculum' . $usercur->curid . '");</script></div>' . $usercur->name . ' (' . $usercur->idnumber . ')'); echo '<div id="curriculum' . $usercur->curid . "\" {$this->div_attrs} " . '" class="yui-skin-sam' . $extraclass . '">'; if ($courses = user::get_user_course_curriculum($cuserid, $usercur->curid)) { echo "<div id=\"{$usercur->id}\"></div>"; $table = new availablecoursetable($courses, $cuserid); $table->print_yui_table('curriculum' . $usercur->curid); } else { echo '<p>' . get_string('nocoursesinthiscurriculum', 'local_elisprogram') . '</p>'; } echo '</div>'; } } else { echo $OUTPUT->heading(get_string('nocoursesinthiscurriculum', 'local_elisprogram')); } echo '<br/>'; echo $OUTPUT->box(get_string('lp_curriculum_instructions', 'local_elisprogram'), 'generalbox lp_instructions'); }
/** * Enrol the test user in the provided context * * @param string $contextlevel The string descriptor of the context level * @param string $role The shortname of the import record's role column */ private function create_enrolment($contextlevel, $role) { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; switch ($contextlevel) { case 'curriculum': // Program enrolment. require_once elispm::lib('data/curriculumstudent.class.php'); $data = array('curriculumid' => 1, 'userid' => 1); $curriculumstudent = new curriculumstudent($data); $curriculumstudent->save(); break; case 'track': // Track enrolment. require_once elispm::lib('data/usertrack.class.php'); $data = array('trackid' => 1, 'userid' => 1); $usertrack = new usertrack($data); $usertrack->save(); break; case 'cluster': // User set enrolment. require_once elispm::lib('data/clusterassignment.class.php'); $data = array('clusterid' => 1, 'userid' => 1); $clusterassignment = new clusterassignment($data); $clusterassignment->save(); break; case 'class': if ($role == 'instructor') { // Class instance instructor enrolment. require_once elispm::lib('data/instructor.class.php'); $data = array('classid' => 1, 'userid' => 1); $instructor = new instructor($data); $instructor->save(); } else { // Class instance student enrolment. require_once elispm::lib('data/student.class.php'); $data = array('classid' => 1, 'userid' => 1); $student = new student($data); $student->save(); } break; case 'user': // Moodle user role assignment. $roleid = $DB->get_field('role', 'id', array('shortname' => $role)); $userid = $DB->get_field('user', 'id', array('idnumber' => 'testuseridnumber')); $context = context_user::instance($userid); role_assign($roleid, $userid, $context->id); break; default: break; } }
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @copyright (C) 2008-2013 Remote Learner.net Inc http://www.remote-learner.net * */ /** * Generates a PDF certificate corresponding to a particular curriculum assignment. */ require_once dirname(__FILE__) . '/../../config.php'; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elispm::lib('data/curriculumstudent.class.php'); require_once elispm::lib('certificate.php'); require_once elispm::lib('deprecatedlib.php'); // cm_get_crlmuserid() // Retrieve curriculum assignment. $id = required_param('id', PARAM_INT); $curass = new curriculumstudent($id); // TBD: following required to get user name to display on certificate! $curass->load(); if (!empty($curass->user)) { $curass->user->load(); } $curuserid = cm_get_crlmuserid($USER->id); if (!isset($curass->user) || !isset($curass->curriculum)) { print_string('invalid_curriculum_completion', 'local_elisprogram'); } else { if ($curuserid != $curass->userid) { print_string('curriculum_userid_mismatch', 'local_elisprogram'); } else { if (0 == (int) $curass->timecompleted) { print_string('error_curriculum_incomplete', 'local_elisprogram'); } else {
/** * Determine whether the current user can unassign the user from the program. * @param int $programid The ID of the program. * @param int $userid The ID of the user (the assignee). * @return bool Whether the current user has permission. */ protected function can_unassign($programid, $userid) { return curriculumstudent::can_manage_assoc($userid, $programid); }
/** * Performs program_enrolment deletion * @throws moodle_exception If there was an error in passed parameters. * @throws data_object_exception If there was an error deleting the association. * @param array $data The incoming data parameter. * @return array An array of parameters, if successful. */ public static function program_enrolment_delete(array $data) { global $DB, $USER; if (static::require_elis_dependencies() !== true) { throw new moodle_exception('ws_function_requires_elis', 'local_datahub'); } // Parameter validation. $params = self::validate_parameters(self::program_enrolment_delete_parameters(), array('data' => $data)); // Context validation. $context = context_user::instance($USER->id); self::validate_context($context); $data = (object) $data; // Parse program if (empty($data->program_idnumber) || !($curid = $DB->get_field(curriculum::TABLE, 'id', array('idnumber' => $data->program_idnumber)))) { throw new data_object_exception('ws_program_enrolment_delete_fail_invalid_program', 'local_datahub', '', $data); } // Capability checking. require_capability('local/elisprogram:program_enrol', \local_elisprogram\context\program::instance($curid)); // Initialize version1elis importplugin for utility functions. $importplugin = rlip_dataplugin_factory::factory('dhimport_version1elis'); $userparams = array(); $userid = $importplugin->get_userid_from_record($data, '', $userparams); if ($userid == false) { $a = new stdClass(); if (empty($userparams)) { $a->userparams = '{empty}'; } else { $a->userparams = ''; foreach ($userparams as $userfield => $uservalue) { $subfield = strpos($userfield, '_'); $userfield = substr($userfield, $subfield === false ? 0 : $subfield + 1); if (!empty($a->userparams)) { $a->userparams .= ', '; } $a->userparams .= "{$userfield}: '{$uservalue}'"; } } throw new data_object_exception('ws_program_enrolment_delete_fail_invalid_user', 'local_datahub', '', $a); } $id = $DB->get_field(curriculumstudent::TABLE, 'id', array('curriculumid' => $curid, 'userid' => $userid)); // Respond. if (!empty($id) && ($stucur = new curriculumstudent($id))) { $stucur->delete(); return array('messagecode' => get_string('ws_program_enrolment_delete_success_code', 'local_datahub'), 'message' => get_string('ws_program_enrolment_delete_success_msg', 'local_datahub')); } else { throw new data_object_exception('ws_program_enrolment_delete_fail', 'local_datahub'); } }
/** * Test available table doesn't show assigned programs. * @dataProvider dataprovider_available_doesnt_show_assigned_programs * @param array $associations An array of arrays of parameters to construct curriculumstudent associations. * @param int $tableuserid The user ID of the user we're going to manage. * @param array $expectedresults The expected page of results. * @param int $expectedtotal The expected number of total results. */ public function test_available_doesnt_show_assigned_programs($associations, $tableuserid, $expectedresults, $expectedtotal) { global $USER, $DB, $CFG; $userbackup = $USER; // Set up permissions. $USER = $this->setup_permissions_test(); $this->give_permission_for_context($USER->id, 'local/elisprogram:program_enrol', context_system::instance()); foreach ($associations as $association) { $curriculumstudent = new curriculumstudent($association); $curriculumstudent->save(); } // Construct test table. $table = new deepsight_datatable_userprogram_available_mock($DB, 'test', 'http://localhost', 'testuniqid'); $table->set_userid($tableuserid); // Perform test. $actualresults = $table->get_search_results(array(), array(), 0, 20); // Verify result. $this->assert_search_results($expectedresults, $expectedtotal, $actualresults); // Restore user. $USER = $userbackup; }
static function cluster_assigned_handler($eventdata) { require_once elispm::lib('data/clusterassignment.class.php'); require_once elispm::lib('data/clustercurriculum.class.php'); require_once elispm::lib('data/curriculumstudent.class.php'); require_once elispm::lib('data/clustertrack.class.php'); require_once elispm::lib('data/usertrack.class.php'); $assignment = new clusterassignment($eventdata); $userset = $assignment->cluster; // assign user to the curricula associated with the cluster /** * @todo we may need to change this if associating a user with a * curriculum does anything more complicated */ // enrol user in associated curricula $prog_assocs = $userset->clustercurriculum; foreach ($prog_assocs as $prog_assoc) { if ($prog_assoc->autoenrol && !curriculumstudent::exists(array(new field_filter('userid', $eventdata->userid), new field_filter('curriculumid', $prog_assoc->curriculumid)))) { $progass = new curriculumstudent(); $progass->userid = $eventdata->userid; $progass->curriculumid = $prog_assoc->curriculumid; $progass->timecreated = $progass->timemodified = time(); $progass->save(); } } // enrol user in associated tracks if autoenrol flag is set on the cluster-track associations $track_assocs = $userset->clustertrack; foreach ($track_assocs as $track_assoc) { if ($track_assoc->autoenrol && !usertrack::exists(array(new field_filter('userid', $eventdata->userid), new field_filter('trackid', $track_assoc->trackid)))) { usertrack::enrol($eventdata->userid, $track_assoc->trackid); } } return true; }