/** * Return the custom definition of the properties of this model. * * @param int $courseid The course we want to generate statistics for. */ public function __construct($courseid) { global $USER; $this->competencycount = api::count_competencies_in_course($courseid); $this->proficientcompetencycount = api::count_proficient_competencies_in_course_for_user($courseid, $USER->id); $this->leastproficientcompetencies = api::get_least_proficient_competencies_for_course($courseid, 0, 3); }
/** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(\renderer_base $output) { $frameworks = array(); $scales = array(); $planexporter = new plan_exporter($this->plan, array('template' => $this->plan->get_template())); $data = new stdClass(); $data->plan = $planexporter->export($output); $data->competencies = array(); $data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(false); $data->contextid = $this->plan->get_context()->id; if ($data->plan->iscompleted) { $ucproperty = 'usercompetencyplan'; $ucexporter = 'core_competency\\external\\user_competency_plan_exporter'; } else { $ucproperty = 'usercompetency'; $ucexporter = 'core_competency\\external\\user_competency_exporter'; } $pclist = api::list_plan_competencies($this->plan); $proficientcount = 0; foreach ($pclist as $pc) { $comp = $pc->competency; $usercomp = $pc->{$ucproperty}; // Get the framework. if (!isset($frameworks[$comp->get_competencyframeworkid()])) { $frameworks[$comp->get_competencyframeworkid()] = $comp->get_framework(); } $framework = $frameworks[$comp->get_competencyframeworkid()]; // Get the scale. $scaleid = $comp->get_scaleid(); if ($scaleid === null) { $scaleid = $framework->get_scaleid(); } if (!isset($scales[$framework->get_scaleid()])) { $scales[$framework->get_scaleid()] = $framework->get_scale(); } $scale = $scales[$framework->get_scaleid()]; // Prepare the data. $record = new stdClass(); $exporter = new competency_exporter($comp, array('context' => $framework->get_context())); $record->competency = $exporter->export($output); // Competency path. $exporter = new competency_path_exporter(['ancestors' => $comp->get_ancestors(), 'framework' => $framework, 'context' => $framework->get_context()]); $record->comppath = $exporter->export($output); $exporter = new $ucexporter($usercomp, array('scale' => $scale)); $record->{$ucproperty} = $exporter->export($output); $data->competencies[] = $record; if ($usercomp->get_proficiency()) { $proficientcount++; } } $data->competencycount = count($data->competencies); $data->proficientcompetencycount = $proficientcount; if ($data->competencycount) { $data->proficientcompetencypercentage = (double) $proficientcount / (double) $data->competencycount * 100.0; } else { $data->proficientcompetencypercentage = 0.0; } $data->proficientcompetencypercentageformatted = format_float($data->proficientcompetencypercentage); return $data; }
protected function get_other_values(renderer_base $output) { // Arrays are copy on assign. $related = $this->related; $result = new stdClass(); // Remove course from related as it is not wanted by the user_competency_summary_exporter. unset($related['course']); $related['usercompetencyplan'] = null; $related['usercompetency'] = null; $exporter = new user_competency_summary_exporter(null, $related); $result->usercompetencysummary = $exporter->export($output); $result->usercompetencysummary->cangrade = user_competency::can_grade_user_in_course($this->related['user']->id, $this->related['course']->id); $context = context_course::instance($this->related['course']->id); $exporter = new course_summary_exporter($this->related['course'], array('context' => $context)); $result->course = $exporter->export($output); $coursemodules = api::list_course_modules_using_competency($this->related['competency']->get_id(), $this->related['course']->id); $fastmodinfo = get_fast_modinfo($this->related['course']->id); $exportedmodules = array(); foreach ($coursemodules as $cm) { $cminfo = $fastmodinfo->cms[$cm]; $cmexporter = new course_module_summary_exporter(null, array('cm' => $cminfo)); $exportedmodules[] = $cmexporter->export($output); } $result->coursemodules = $exportedmodules; return (array) $result; }
/** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { $data = new stdClass(); $data->userid = $this->userid; $data->competencyid = $this->competencyid; $data->planid = $this->planid; $data->baseurl = $this->baseurl; $plancompetencies = \core_competency\api::list_plan_competencies($data->planid); $data->competencies = array(); $contextcache = array(); foreach ($plancompetencies as $plancompetency) { $frameworkid = $plancompetency->competency->get_competencyframeworkid(); if (!isset($contextcache[$frameworkid])) { $contextcache[$frameworkid] = $plancompetency->competency->get_context(); } $context = $contextcache[$frameworkid]; $exporter = new competency_exporter($plancompetency->competency, array('context' => $context)); $competency = $exporter->export($output); if ($competency->id == $this->competencyid) { $competency->selected = true; } $data->competencies[] = $competency; } $data->hascompetencies = count($data->competencies); return $data; }
/** * Constructor * * @param string $elementName Element name * @param mixed $elementLabel Label(s) for an element * @param array $options Options to control the element's display * @param mixed $attributes Either a typical HTML attribute string or an associative array. */ public function __construct($elementName = null, $elementLabel = null, $options = array(), $attributes = null) { global $OUTPUT; if ($elementName == null) { // This is broken quickforms messing with the constructors. return; } if (!isset($options['courseid'])) { throw new coding_exception('Course id is required for the course_competencies form element'); } $courseid = $options['courseid']; if (!empty($options['cmid'])) { $current = \core_competency\api::list_course_module_competencies_in_course_module($options['cmid']); $ids = array(); foreach ($current as $coursemodulecompetency) { array_push($ids, $coursemodulecompetency->get_competencyid()); } $this->setValue($ids); } $competencies = api::list_course_competencies($courseid); $validoptions = array(); $context = context_course::instance($courseid); foreach ($competencies as $competency) { // We don't need to show the description as part of the options, so just set this to null. $competency['competency']->set_description(null); $exporter = new competency_exporter($competency['competency'], array('context' => $context)); $templatecontext = array('competency' => $exporter->export($OUTPUT)); $id = $competency['competency']->get_id(); $validoptions[$id] = $OUTPUT->render_from_template('tool_lp/competency_summary', $templatecontext); } $attributes['tags'] = false; $attributes['multiple'] = 'multiple'; parent::__construct($elementName, $elementLabel, $validoptions, $attributes); }
/** * Construct this renderable. * * @param context $pagecontext The page context */ public function __construct(context $pagecontext) { $this->pagecontext = $pagecontext; if (competency_framework::can_manage_context($this->pagecontext)) { $addpage = new single_button(new moodle_url('/admin/tool/lp/editcompetencyframework.php', array('pagecontextid' => $this->pagecontext->id)), get_string('addnewcompetencyframework', 'tool_lp'), 'get'); $this->navigation[] = $addpage; } $this->competencyframeworks = api::list_frameworks('shortname', 'ASC', 0, 0, $this->pagecontext); }
/** * Construct this renderable. * @param context $pagecontext */ public function __construct(context $pagecontext) { $this->pagecontext = $pagecontext; if (template::can_manage_context($this->pagecontext)) { $addpage = new single_button(new moodle_url('/admin/tool/lp/edittemplate.php', array('pagecontextid' => $this->pagecontext->id)), get_string('addnewtemplate', 'tool_lp'), 'get'); $this->navigation[] = $addpage; } $this->templates = api::list_templates('shortname', 'ASC', 0, 0, $this->pagecontext); }
/** * Construct this renderable. * * @param int $userid */ public function __construct($userid) { $this->userid = $userid; $this->plans = api::list_user_plans($userid); $this->context = context_user::instance($userid); if (plan::can_manage_user($userid) || plan::can_manage_user_draft($userid)) { $addplan = new single_button(new moodle_url('/admin/tool/lp/editplan.php', array('userid' => $userid)), get_string('addnewplan', 'tool_lp'), 'get'); $this->navigation[] = $addplan; } }
/** * Construct this renderable. * * @param int $userid */ public function __construct($userid) { $this->userid = $userid; $this->context = context_user::instance($userid); $this->evidence = api::list_user_evidence($userid); $this->canmanage = user_evidence::can_manage_user($this->userid); if ($this->canmanage) { $addevidence = new single_button(new moodle_url('/admin/tool/lp/user_evidence_edit.php', array('userid' => $userid)), get_string('addnewuserevidence', 'tool_lp'), 'get'); $this->navigation[] = $addevidence; } }
/** * Construct this renderable. * * @param \core_competency\competency $competency Competency persistent. * @param \core_competency\competency_framework $framework framework persistent. * @param boolean $includerelated Include or not related competencies. * @param boolean $includecourses Include or not competency courses. */ public function __construct($competency, $framework, $includerelated, $includecourses) { $this->competency = $competency; $this->framework = $framework; if ($includerelated) { $this->relatedcompetencies = api::list_related_competencies($competency->get_id()); } if ($includecourses) { $this->courses = api::list_courses_using_competency($competency->get_id()); } }
/** * Return the custom definition of the properties of this model. * * @param int $templateid The template we want to generate statistics for. */ public function __construct($templateid) { $template = new template($templateid); $this->competencycount = api::count_competencies_in_template($template); $this->unlinkedcompetencycount = api::count_competencies_in_template_with_no_courses($template); $this->plancount = api::count_plans_for_template($template, 0); $this->completedplancount = api::count_plans_for_template($template, plan::STATUS_COMPLETE); $this->usercompetencyplancount = api::count_user_competency_plans_for_template($template); $this->proficientusercompetencyplancount = api::count_user_competency_plans_for_template($template, true); $this->leastproficientcompetencies = api::get_least_proficient_competencies_for_template($template, 0, 3); }
/** * Do the job. */ public function execute() { if (!api::is_enabled()) { return; } $records = plan::get_recordset_for_due_and_incomplete(); foreach ($records as $record) { $plan = new plan(0, $record); api::complete_plan($plan); } $records->close(); }
/** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { if (!isset($related['user'])) { $related['user'] = core_user::get_user($this->usercompetency->get_userid()); } if (!isset($related['competency'])) { $related['competency'] = $this->usercompetency->get_competency(); } $related += array('usercompetency' => $this->usercompetency, 'usercompetencyplan' => null, 'usercompetencycourse' => null, 'evidence' => api::list_evidence($this->usercompetency->get_userid(), $this->usercompetency->get_competencyid()), 'relatedcompetencies' => api::list_related_competencies($this->usercompetency->get_competencyid())); $exporter = new user_competency_summary_exporter(null, $related); $data = $exporter->export($output); return $data; }
/** * Constructor. * @param stdClass $user The user. */ public function __construct($user = null) { global $USER; if (!$user) { $user = $USER; } $this->user = $user; // Get the plans. $this->plans = api::list_user_plans($this->user->id); // Get the competencies to review. $this->compstoreview = api::list_user_competencies_to_review(0, 3); // Get the plans to review. $this->planstoreview = api::list_plans_to_review(0, 3); }
public function test_import_framework() { $this->resetAfterTest(true); $this->setAdminUser(); $importer = new framework_importer(file_get_contents(__DIR__ . '/fixtures/example.csv')); $this->assertEquals('', $importer->get_error()); $framework = $importer->import(); $this->assertEmpty('', $importer->get_error()); $this->assertGreaterThan(0, $framework->get_id()); $filters = ['competencyframeworkid' => $framework->get_id()]; $count = api::count_competencies($filters); $this->assertEquals(64, $count); // We can't test the exporter because it sends force-download headers. }
/** * Do the job. */ public function execute() { if (!api::is_enabled()) { return; } $missingplans = template_cohort::get_all_missing_plans(self::get_last_run_time()); foreach ($missingplans as $missingplan) { foreach ($missingplan['userids'] as $userid) { try { api::create_plan_from_template($missingplan['template'], $userid); } catch (\Exception $e) { debugging(sprintf('Exception caught while creating plan for user %d from template %d. Message: %s', $userid, $missingplan['template']->get_id(), $e->getMessage()), DEBUG_DEVELOPER); } } } }
/** * Export all the competencies from this framework to a csv file. */ public function export() { global $CFG; require_once $CFG->libdir . '/csvlib.class.php'; $writer = new csv_export_writer(); $filename = clean_param($this->framework->get_shortname() . '-' . $this->framework->get_idnumber(), PARAM_FILE); $writer->set_filename($filename); $headers = framework_importer::list_required_headers(); $writer->add_data($headers); // Order and number of columns must match framework_importer::list_required_headers(). $row = array('', $this->framework->get_idnumber(), $this->framework->get_shortname(), $this->framework->get_description(), $this->framework->get_descriptionformat(), $this->framework->get_scale()->compact_items(), $this->framework->get_scaleconfiguration(), '', '', '', '', '', true, implode(',', $this->framework->get_taxonomies())); $writer->add_data($row); $filters = array('competencyframeworkid' => $this->framework->get_id()); $competencies = api::list_competencies($filters); // Index by id so we can lookup parents. $indexed = array(); foreach ($competencies as $competency) { $indexed[$competency->get_id()] = $competency; } foreach ($competencies as $competency) { $parentidnumber = ''; if ($competency->get_parentid() > 0) { $parent = $indexed[$competency->get_parentid()]; $parentidnumber = $parent->get_idnumber(); } $scalevalues = ''; $scaleconfig = ''; if ($competency->get_scaleid() !== null) { $scalevalues = $competency->get_scale()->compact_items(); $scaleconfig = $competency->get_scaleconfiguration(); } $ruleconfig = $competency->get_ruleconfig(); if ($ruleconfig === null) { $ruleconfig = "null"; } $allrelated = $competency->get_related_competencies(); $relatedidnumbers = array(); foreach ($allrelated as $onerelated) { $relatedidnumbers[] = str_replace(',', '%2C', $onerelated->get_idnumber()); } $relatedidnumbers = implode(',', $relatedidnumbers); // Order and number of columns must match framework_importer::list_required_headers(). $row = array($parentidnumber, $competency->get_idnumber(), $competency->get_shortname(), $competency->get_description(), $competency->get_descriptionformat(), $scalevalues, $scaleconfig, $competency->get_ruletype(), $competency->get_ruleoutcome(), $ruleconfig, $relatedidnumbers, $competency->get_id(), false, ''); $writer->add_data($row); } $writer->download_file(); }
/** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { global $DB; $usercompetencycourse = api::get_user_competency_in_course($this->courseid, $this->userid, $this->competencyid); $competency = $usercompetencycourse->get_competency(); if (empty($usercompetencycourse) || empty($competency)) { throw new \invalid_parameter_exception('Invalid params. The competency does not belong to the course.'); } $relatedcompetencies = api::list_related_competencies($competency->get_id()); $user = $DB->get_record('user', array('id' => $this->userid)); $evidence = api::list_evidence_in_course($this->userid, $this->courseid, $this->competencyid); $course = $DB->get_record('course', array('id' => $this->courseid)); $params = array('competency' => $competency, 'usercompetencycourse' => $usercompetencycourse, 'evidence' => $evidence, 'user' => $user, 'course' => $course, 'scale' => $competency->get_scale(), 'relatedcompetencies' => $relatedcompetencies); $exporter = new user_competency_summary_in_course_exporter(null, $params); $data = $exporter->export($output); return $data; }
/** * Define the form - called by parent constructor */ public function definition() { $mform = $this->_form; $context = context_system::instance(); $frameworks = api::list_frameworks('shortname', 'ASC', null, null, $context); $options = array(); foreach ($frameworks as $framework) { $options[$framework->get_id()] = $framework->get_shortname(); } if (empty($options)) { $mform->addElement('static', 'frameworkid', '', get_string('noframeworks', 'tool_lpimportcsv')); } else { $mform->addElement('select', 'frameworkid', get_string('competencyframework', 'tool_lp'), $options); $mform->setType('frameworkid', PARAM_INT); $mform->addRule('frameworkid', null, 'required', null, 'client'); $this->add_action_buttons(true, get_string('export', 'tool_lpimportcsv')); } $mform->setDisableShortforms(); }
/** * Constructor * * @param string $elementName Element name * @param mixed $elementLabel Label(s) for an element * @param array $options Options to control the element's display * @param mixed $attributes Either a typical HTML attribute string or an associative array. */ public function __construct($elementName = null, $elementLabel = null, $options = array(), $attributes = null) { if ($elementName == null) { // This is broken quickforms messing with the constructors. return; } if (!empty($options['cmid'])) { $cmid = $options['cmid']; $current = \core_competency\api::list_course_module_competencies_in_course_module($cmid); // Note: We just pick the outcome set on the first course_module_competency - because in our UI are are // forcing them to be all the same for each activity. if (!empty($current)) { $one = array_pop($current); $this->setValue($one->get_ruleoutcome()); } } $validoptions = course_module_competency::get_ruleoutcome_list(); parent::__construct($elementName, $elementLabel, $validoptions, $attributes); }
/** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(\renderer_base $output) { global $DB; $plan = api::read_plan($this->planid); $pc = api::get_plan_competency($plan, $this->competencyid); $competency = $pc->competency; $usercompetency = $pc->usercompetency; $usercompetencyplan = $pc->usercompetencyplan; if (empty($competency)) { throw new \invalid_parameter_exception('Invalid params. The competency does not belong to the plan.'); } $relatedcompetencies = api::list_related_competencies($competency->get_id()); $userid = $plan->get_userid(); $user = $DB->get_record('user', array('id' => $userid)); $evidence = api::list_evidence($userid, $this->competencyid, $plan->get_id()); $params = array('competency' => $competency, 'usercompetency' => $usercompetency, 'usercompetencyplan' => $usercompetencyplan, 'evidence' => $evidence, 'user' => $user, 'plan' => $plan, 'relatedcompetencies' => $relatedcompetencies); $exporter = new user_competency_summary_in_plan_exporter(null, $params); $data = $exporter->export($output); return $data; }
/** * This function will empty a course of user data. * It will retain the activities and the structure of the course. * * @param object $data an object containing all the settings including courseid (without magic quotes) * @return array status array of array component, item, error */ function reset_course_userdata($data) { global $CFG, $DB; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->libdir . '/completionlib.php'; require_once $CFG->dirroot . '/group/lib.php'; $data->courseid = $data->id; $context = context_course::instance($data->courseid); $eventparams = array('context' => $context, 'courseid' => $data->id, 'other' => array('reset_options' => (array) $data)); $event = \core\event\course_reset_started::create($eventparams); $event->trigger(); // Calculate the time shift of dates. if (!empty($data->reset_start_date)) { // Time part of course startdate should be zero. $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old); } else { $data->timeshift = 0; } // Result array: component, item, error. $status = array(); // Start the resetting. $componentstr = get_string('general'); // Move the course start time. if (!empty($data->reset_start_date) and $data->timeshift) { // Change course start data. $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid)); // Update all course and group events - do not move activity events. $updatesql = "UPDATE {event}\n SET timestart = timestart + ?\n WHERE courseid=? AND instance=0"; $DB->execute($updatesql, array($data->timeshift, $data->courseid)); // Update any date activity restrictions. if ($CFG->enableavailability) { \availability_date\condition::update_all_dates($data->courseid, $data->timeshift); } $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); } if (!empty($data->reset_end_date)) { // If the user set a end date value respect it. $DB->set_field('course', 'enddate', $data->reset_end_date, array('id' => $data->courseid)); } else { if ($data->timeshift > 0 && $data->reset_end_date_old) { // If there is a time shift apply it to the end date as well. $enddate = $data->reset_end_date_old + $data->timeshift; $DB->set_field('course', 'enddate', $enddate, array('id' => $data->courseid)); } } if (!empty($data->reset_events)) { $DB->delete_records('event', array('courseid' => $data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false); } if (!empty($data->reset_notes)) { require_once $CFG->dirroot . '/notes/lib.php'; note_delete_all($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false); } if (!empty($data->delete_blog_associations)) { require_once $CFG->dirroot . '/blog/lib.php'; blog_remove_associations_for_course($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false); } if (!empty($data->reset_completion)) { // Delete course and activity completion information. $course = $DB->get_record('course', array('id' => $data->courseid)); $cc = new completion_info($course); $cc->delete_all_completion_data(); $status[] = array('component' => $componentstr, 'item' => get_string('deletecompletiondata', 'completion'), 'error' => false); } if (!empty($data->reset_competency_ratings)) { \core_competency\api::hook_course_reset_competency_ratings($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deletecompetencyratings', 'core_competency'), 'error' => false); } $componentstr = get_string('roles'); if (!empty($data->reset_roles_overrides)) { $children = $context->get_child_contexts(); foreach ($children as $child) { $DB->delete_records('role_capabilities', array('contextid' => $child->id)); } $DB->delete_records('role_capabilities', array('contextid' => $context->id)); // Force refresh for logged in users. $context->mark_dirty(); $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false); } if (!empty($data->reset_roles_local)) { $children = $context->get_child_contexts(); foreach ($children as $child) { role_unassign_all(array('contextid' => $child->id)); } // Force refresh for logged in users. $context->mark_dirty(); $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false); } // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc. $data->unenrolled = array(); if (!empty($data->unenrol_users)) { $plugins = enrol_get_plugins(true); $instances = enrol_get_instances($data->courseid, true); foreach ($instances as $key => $instance) { if (!isset($plugins[$instance->enrol])) { unset($instances[$key]); continue; } } foreach ($data->unenrol_users as $withroleid) { if ($withroleid) { $sql = "SELECT ue.*\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)"; $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE); } else { // Without any role assigned at course context. $sql = "SELECT ue.*\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = ue.userid)\n WHERE ra.id IS null"; $params = array('courseid' => $data->courseid, 'courselevel' => CONTEXT_COURSE); } $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ue) { if (!isset($instances[$ue->enrolid])) { continue; } $instance = $instances[$ue->enrolid]; $plugin = $plugins[$instance->enrol]; if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) { continue; } $plugin->unenrol_user($instance, $ue->userid); $data->unenrolled[$ue->userid] = $ue->userid; } $rs->close(); } } if (!empty($data->unenrolled)) { $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false); } $componentstr = get_string('groups'); // Remove all group members. if (!empty($data->reset_groups_members)) { groups_delete_group_members($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false); } // Remove all groups. if (!empty($data->reset_groups_remove)) { groups_delete_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false); } // Remove all grouping members. if (!empty($data->reset_groupings_members)) { groups_delete_groupings_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false); } // Remove all groupings. if (!empty($data->reset_groupings_remove)) { groups_delete_groupings($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false); } // Look in every instance of every module for data to delete. $unsupportedmods = array(); if ($allmods = $DB->get_records('modules')) { foreach ($allmods as $mod) { $modname = $mod->name; $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php'; $moddeleteuserdata = $modname . '_reset_userdata'; // Function to delete user data. if (file_exists($modfile)) { if (!$DB->count_records($modname, array('course' => $data->courseid))) { continue; // Skip mods with no instances. } include_once $modfile; if (function_exists($moddeleteuserdata)) { $modstatus = $moddeleteuserdata($data); if (is_array($modstatus)) { $status = array_merge($status, $modstatus); } else { debugging('Module ' . $modname . ' returned incorrect staus - must be an array!'); } } else { $unsupportedmods[] = $mod; } } else { debugging('Missing lib.php in ' . $modname . ' module!'); } } } // Mention unsupported mods. if (!empty($unsupportedmods)) { foreach ($unsupportedmods as $mod) { $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented')); } } $componentstr = get_string('gradebook', 'grades'); // Reset gradebook,. if (!empty($data->reset_gradebook_items)) { remove_course_grades($data->courseid, false); grade_grab_course_grades($data->courseid); grade_regrade_final_grades($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false); } else { if (!empty($data->reset_gradebook_grades)) { grade_course_reset($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false); } } // Reset comments. if (!empty($data->reset_comments)) { require_once $CFG->dirroot . '/comment/lib.php'; comment::reset_course_page_comments($context); } $event = \core\event\course_reset_ended::create($eventparams); $event->trigger(); return $status; }
/** * Hook the add/edit of the course module. * * @param stdClass $data Data from the form submission. * @param stdClass $course The course. */ function tool_lp_coursemodule_edit_post_actions($data, $course) { if (!get_config('core_competency', 'enabled')) { return $data; } // It seems like the form did not contain any of the form fields, we can return. if (!isset($data->competency_rule) && !isset($data->competencies)) { return $data; } // We bypass the API here and go direct to the persistent layer - because we don't want to do permission // checks here - we need to load the real list of existing course module competencies. $existing = \core_competency\course_module_competency::list_course_module_competencies($data->coursemodule); $existingids = array(); foreach ($existing as $cmc) { array_push($existingids, $cmc->get_competencyid()); } $newids = isset($data->competencies) ? $data->competencies : array(); $removed = array_diff($existingids, $newids); $added = array_diff($newids, $existingids); foreach ($removed as $removedid) { \core_competency\api::remove_competency_from_course_module($data->coursemodule, $removedid); } foreach ($added as $addedid) { \core_competency\api::add_competency_to_course_module($data->coursemodule, $addedid); } if (isset($data->competency_rule)) { // Now update the rules for each course_module_competency. $current = \core_competency\api::list_course_module_competencies_in_course_module($data->coursemodule); foreach ($current as $coursemodulecompetency) { \core_competency\api::set_course_module_competency_ruleoutcome($coursemodulecompetency, $data->competency_rule); } } return $data; }
public function test_list_user_competencies_to_review() { $dg = $this->getDataGenerator(); $this->resetAfterTest(); $ccg = $dg->get_plugin_generator('core_competency'); $sysctx = context_system::instance(); $this->setAdminUser(); $reviewer = $dg->create_user(); $roleallow = $dg->create_role(); $roleprohibit = $dg->create_role(); assign_capability('moodle/competency:usercompetencyreview', CAP_ALLOW, $roleallow, $sysctx->id); assign_capability('moodle/competency:usercompetencyreview', CAP_PROHIBIT, $roleprohibit, $sysctx->id); role_assign($roleallow, $reviewer->id, $sysctx->id); accesslib_clear_all_caches_for_unit_testing(); $u1 = $dg->create_user(); $u2 = $dg->create_user(); $f1 = $ccg->create_framework(); $c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); $c2 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); $c3 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); $uc1a = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c1->get_id(), 'status' => user_competency::STATUS_IDLE]); $uc1b = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c2->get_id(), 'status' => user_competency::STATUS_WAITING_FOR_REVIEW]); $uc1c = $ccg->create_user_competency(['userid' => $u1->id, 'competencyid' => $c3->get_id(), 'status' => user_competency::STATUS_IN_REVIEW, 'reviewerid' => $reviewer->id]); $uc2a = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c1->get_id(), 'status' => user_competency::STATUS_WAITING_FOR_REVIEW]); $uc2b = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c2->get_id(), 'status' => user_competency::STATUS_IDLE]); $uc2c = $ccg->create_user_competency(['userid' => $u2->id, 'competencyid' => $c3->get_id(), 'status' => user_competency::STATUS_IN_REVIEW]); // The reviewer can review all plans waiting for review, or in review where they are the reviewer. $this->setUser($reviewer); $result = api::list_user_competencies_to_review(); $this->assertEquals(3, $result['count']); $this->assertEquals($uc2a->get_id(), $result['competencies'][0]->usercompetency->get_id()); $this->assertEquals($uc1b->get_id(), $result['competencies'][1]->usercompetency->get_id()); $this->assertEquals($uc1c->get_id(), $result['competencies'][2]->usercompetency->get_id()); // The reviewer cannot view the plans when they do not have the permission in the user's context. role_assign($roleprohibit, $reviewer->id, context_user::instance($u2->id)->id); accesslib_clear_all_caches_for_unit_testing(); $result = api::list_user_competencies_to_review(); $this->assertEquals(2, $result['count']); $this->assertEquals($uc1b->get_id(), $result['competencies'][0]->usercompetency->get_id()); $this->assertEquals($uc1c->get_id(), $result['competencies'][1]->usercompetency->get_id()); }
/** * Process the user competency course. * * @param array $data The data. */ public function process_user_competency_course($data) { global $USER, $DB; $data = (object) $data; $data->competencyid = $this->get_mappingid(\core_competency\competency::TABLE, $data->competencyid); if (!$data->competencyid) { // This is strange, the competency does not belong to the course. return; } else { if ($data->grade === null) { // We do not need to do anything when there is no grade. return; } } $data->userid = $this->get_mappingid('user', $data->userid); $shortname = $DB->get_field('course', 'shortname', array('id' => $this->task->get_courseid()), MUST_EXIST); // The method add_evidence also sets the course rating. \core_competency\api::add_evidence($data->userid, $data->competencyid, $this->task->get_contextid(), \core_competency\evidence::ACTION_OVERRIDE, 'evidence_courserestored', 'core_competency', $shortname, false, null, $data->grade, $USER->id); }
/** * Construct this renderable. * * @param int $competencyid */ public function __construct($competencyid) { $this->competency = api::read_competency($competencyid); $this->context = $this->competency->get_context(); $this->relatedcompetencies = api::list_related_competencies($competencyid); }
echo $output->header(); echo $output->heading($title); $form = new \tool_lpmigrate\form\migrate_framework($context); if ($form->is_cancelled()) { redirect($url); } else { if ($data = $form->get_data()) { // Map competencies from both framework. $mapper = new \tool_lpmigrate\framework_mapper($data->from, $data->to); $mapper->automap(); $progress = new \core\progress\display(); $progress->set_display_names(true); $processor = new \tool_lpmigrate\framework_processor($mapper, $progress); if (!empty($data->allowedcourses)) { $processor->set_allowedcourses($data->allowedcourses); } if (!empty($data->disallowedcourses)) { $processor->set_disallowedcourses($data->disallowedcourses); } $processor->set_course_start_date_from($data->coursestartdate); $processor->proceed(); $unmappedfrom = $mapper->get_unmapped_objects_from(); $unmappedto = $mapper->get_unmapped_objects_to(); $renderable = new \tool_lpmigrate\output\migrate_framework_results($context, $processor, \core_competency\api::read_framework($data->from), \core_competency\api::read_framework($data->to), $unmappedfrom, $unmappedto); echo $output->render($renderable); } else { echo html_writer::tag('p', get_string('explanation', 'tool_lpmigrate')); $form->display(); } } echo $output->footer();
/** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output Renderer base. * @return stdClass */ public function export_for_template(renderer_base $output) { global $USER; $data = new stdClass(); $data->courseid = $this->courseid; $data->pagecontextid = $this->context->id; $data->competencies = array(); $contextcache = array(); $gradable = is_enrolled($this->context, $USER, 'moodle/competency:coursecompetencygradable'); if ($gradable) { $usercompetencycourses = api::list_user_competencies_in_course($this->courseid, $USER->id); $data->gradableuserid = $USER->id; } $ruleoutcomelist = course_competency::get_ruleoutcome_list(); $ruleoutcomeoptions = array(); foreach ($ruleoutcomelist as $value => $text) { $ruleoutcomeoptions[$value] = array('value' => $value, 'text' => (string) $text, 'selected' => false); } foreach ($this->coursecompetencylist as $coursecompetencyelement) { $coursecompetency = $coursecompetencyelement['coursecompetency']; $competency = $coursecompetencyelement['competency']; if (!isset($contextcache[$competency->get_competencyframeworkid()])) { $contextcache[$competency->get_competencyframeworkid()] = $competency->get_context(); } $context = $contextcache[$competency->get_competencyframeworkid()]; $compexporter = new competency_exporter($competency, array('context' => $context)); $ccexporter = new course_competency_exporter($coursecompetency, array('context' => $context)); $ccoutcomeoptions = (array) (object) $ruleoutcomeoptions; $ccoutcomeoptions[$coursecompetency->get_ruleoutcome()]['selected'] = true; $coursemodules = api::list_course_modules_using_competency($competency->get_id(), $this->courseid); $fastmodinfo = get_fast_modinfo($this->courseid); $exportedmodules = array(); foreach ($coursemodules as $cmid) { $cminfo = $fastmodinfo->cms[$cmid]; $cmexporter = new course_module_summary_exporter(null, array('cm' => $cminfo)); $exportedmodules[] = $cmexporter->export($output); } // Competency path. $pathexporter = new competency_path_exporter(['ancestors' => $competency->get_ancestors(), 'framework' => $competency->get_framework(), 'context' => $context]); $onerow = array('competency' => $compexporter->export($output), 'coursecompetency' => $ccexporter->export($output), 'ruleoutcomeoptions' => $ccoutcomeoptions, 'coursemodules' => $exportedmodules, 'comppath' => $pathexporter->export($output)); if ($gradable) { $foundusercompetencycourse = false; foreach ($usercompetencycourses as $usercompetencycourse) { if ($usercompetencycourse->get_competencyid() == $competency->get_id()) { $foundusercompetencycourse = $usercompetencycourse; } } if ($foundusercompetencycourse) { $related = array('scale' => $competency->get_scale()); $exporter = new user_competency_course_exporter($foundusercompetencycourse, $related); $onerow['usercompetencycourse'] = $exporter->export($output); } } array_push($data->competencies, $onerow); } $data->canmanagecompetencyframeworks = $this->canmanagecompetencyframeworks; $data->canmanagecoursecompetencies = $this->canmanagecoursecompetencies; $data->canconfigurecoursecompetencies = $this->canconfigurecoursecompetencies; $data->cangradecompetencies = $this->cangradecompetencies; $exporter = new course_competency_settings_exporter($this->coursecompetencysettings); $data->settings = $exporter->export($output); $related = array('context' => $this->context); $exporter = new course_competency_statistics_exporter($this->coursecompetencystatistics, $related); $data->statistics = $exporter->export($output); $data->manageurl = null; if ($this->canmanagecompetencyframeworks) { $data->manageurl = $this->manageurl->out(true); } return $data; }
// // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * This page lets users to manage site wide competencies. * * @package tool_lp * @copyright 2015 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once __DIR__ . '/../../../config.php'; $id = required_param('courseid', PARAM_INT); $params = array('id' => $id); $course = $DB->get_record('course', $params, '*', MUST_EXIST); require_login($course); \core_competency\api::require_enabled(); $context = context_course::instance($course->id); $urlparams = array('courseid' => $id); $url = new moodle_url('/admin/tool/lp/coursecompetencies.php', $urlparams); list($title, $subtitle) = \tool_lp\page_helper::setup_for_course($url, $course); $output = $PAGE->get_renderer('tool_lp'); $page = new \tool_lp\output\course_competencies_page($course->id); echo $output->header(); echo $output->heading($title); echo $output->render($page); echo $output->footer();
/** * Process each course individually. * @return void */ protected function process_courses() { global $DB; $this->progress->start_progress(get_string('migratingcourses', 'tool_lpmigrate'), count($this->coursescompetencies)); // Process each course. foreach ($this->coursescompetencies as $courseid => $competencyids) { $this->progress->increment_progress(); $competenciestoremovefromcourse = array(); $skipcompetencies = array(); // First, add all the new competencies to the course. foreach ($competencyids as $key => $competencyid) { $this->coursecompetencyexpectedmigrations++; $mapto = isset($this->mappings[$competencyid]) ? $this->mappings[$competencyid] : false; // Skip the competencies that are not mapped. if ($mapto === false) { $this->missingmappings[$competencyid] = true; if ($this->removewhenmappingismissing) { $competenciestoremovefromcourse[$competencyid] = true; } continue; } $transaction = $DB->start_delegated_transaction(); try { // Add the new competency to the course. if (api::add_competency_to_course($courseid, $mapto)) { // Find the added course competency. $cc = course_competency::get_record(array('courseid' => $courseid, 'competencyid' => $mapto)); // Set the rule. api::set_course_competency_ruleoutcome($cc, $this->coursescompetenciesoutcomes[$courseid][$competencyid]); // Adapt the sortorder. api::reorder_course_competency($courseid, $mapto, $competencyid); $competenciestoremovefromcourse[$competencyid] = true; $this->coursecompetencymigrations++; } else { // The competency was already in the course... if ($this->removeoriginalwhenalreadypresent) { $competenciestoremovefromcourse[$competencyid] = true; } else { $this->log_warning($courseid, $competencyid, null, get_string('warningdestinationcoursecompetencyalreadyexists', 'tool_lpmigrate')); } } } catch (moodle_exception $e) { // There was a major problem with this competency, we will ignore it entirely for the course. $skipcompetencies[$competencyid] = true; $this->log_error($courseid, $competencyid, null, get_string('errorwhilemigratingcoursecompetencywithexception', 'tool_lpmigrate', $e->getMessage())); try { $transaction->rollback($e); } catch (moodle_exception $e) { // Catch the re-thrown exception. } continue; } $transaction->allow_commit(); } // Then, convert the module competencies. if (!empty($this->modulecompetencies[$courseid])) { foreach ($this->modulecompetencies[$courseid] as $cmid => $competencyids) { foreach ($competencyids as $competencyid) { $this->modulecompetencyexpectedmigrations++; // This mapped competency was not added to the course. if (!empty($skipcompetencies[$competencyid])) { continue; } $remove = true; $mapto = isset($this->mappings[$competencyid]) ? $this->mappings[$competencyid] : false; // We don't have mapping. if ($mapto === false) { if (!$this->removewhenmappingismissing) { $remove = false; } } else { // We have a mapping. $transaction = $DB->start_delegated_transaction(); try { // The competency was added successfully. if (api::add_competency_to_course_module($cmid, $mapto)) { // Find the added module competency. $mc = course_module_competency::get_record(array('cmid' => $cmid, 'competencyid' => $mapto)); // Set the competency rule. api::set_course_module_competency_ruleoutcome($mc, $this->modulecompetenciesoutcomes[$courseid][$cmid][$competencyid]); // Adapt the sortorder. api::reorder_course_module_competency($cmid, $mapto, $competencyid); $this->modulecompetencymigrations++; } else { // The competency was already in the module. if (!$this->removeoriginalwhenalreadypresent) { $remove = false; $competencieswithissues[$competencyid] = true; $this->log_warning($courseid, $competencyid, $cmid, get_string('warningdestinationmodulecompetencyalreadyexists', 'tool_lpmigrate')); } } } catch (moodle_exception $e) { // There was a major problem with this competency in this module. $competencieswithissues[$competencyid] = true; $message = get_string('errorwhilemigratingmodulecompetencywithexception', 'tool_lpmigrate', $e->getMessage()); $this->log_error($courseid, $competencyid, $cmid, $message); try { $transaction->rollback($e); } catch (moodle_exception $e) { // Catch the re-thrown exception. } continue; } $transaction->allow_commit(); } try { // Go away competency! if ($remove && api::remove_competency_from_course_module($cmid, $competencyid)) { $this->modulecompetencyremovals++; } } catch (moodle_exception $e) { $competencieswithissues[$competencyid] = true; $this->log_warning($courseid, $competencyid, $cmid, get_string('warningcouldnotremovemodulecompetency', 'tool_lpmigrate')); } } } } // Finally, we remove the course competencies, but only for the 100% successful ones. foreach ($competenciestoremovefromcourse as $competencyid => $unused) { // Skip competencies with issues. if (isset($competencieswithissues[$competencyid])) { continue; } try { // Process the course competency. api::remove_competency_from_course($courseid, $competencyid); $this->coursecompetencyremovals++; } catch (moodle_exception $e) { $this->log_warning($courseid, $competencyid, null, get_string('warningcouldnotremovecoursecompetency', 'tool_lpmigrate')); } } } $this->progress->end_progress(); }