/** * Constructor. * * @param competency $competency The competency. */ public function __construct(competency $competency) { $class = $competency->get_ruletype(); if (!$class || !$this instanceof $class) { throw new coding_exception('This competency does not use this rule.'); } $this->competency = $competency; }
/** * Convenience method to instantiate the event. * * @param competency $competency The competency. * @return self */ public static function create_from_competency(competency $competency) { if (!$competency->get_id()) { throw new \coding_exception('The competency ID must be set.'); } $event = static::create(array('contextid' => $competency->get_context()->id, 'objectid' => $competency->get_id())); $event->add_record_snapshot(competency::TABLE, $competency->to_record()); return $event; }
/** * 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()); } }
/** * Validate competency ID. * * @param int $value ID. * @return true|lang_string */ protected function validate_competencyid($value) { if (!competency::record_exists($value)) { return new lang_string('invaliddata', 'error'); } return true; }
public function test_get_framework_depth() { $this->resetAfterTest(); $ccg = $this->getDataGenerator()->get_plugin_generator('core_competency'); $f1 = $ccg->create_framework(); $f2 = $ccg->create_framework(); $f3 = $ccg->create_framework(); $f4 = $ccg->create_framework(); $f1c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]); $f1c11 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c1->get_id()]); $f1c111 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c11->get_id()]); $f1c1111 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c111->get_id()]); $f2c1 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]); $f2c2 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]); $f2c21 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c2->get_id()]); $f2c22 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c2->get_id()]); $f2c211 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c21->get_id()]); $f2c221 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]); $f2c222 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]); $f2c223 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]); $f2c3 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]); $f3c1 = $ccg->create_competency(['competencyframeworkid' => $f3->get_id()]); $this->assertEquals(4, competency::get_framework_depth($f1->get_id())); $this->assertEquals(3, competency::get_framework_depth($f2->get_id())); $this->assertEquals(1, competency::get_framework_depth($f3->get_id())); $this->assertEquals(0, competency::get_framework_depth($f4->get_id())); }
public function test_create_competency() { $this->resetAfterTest(true); $lpg = $this->getDataGenerator()->get_plugin_generator('core_competency'); $framework = $lpg->create_framework(); $this->assertEquals(0, competency::count_records()); $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); $competency = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id())); $this->assertEquals(2, competency::count_records()); $this->assertInstanceOf('\\core_competency\\competency', $competency); }
/** * Whether or not the rule is matched. * * @param user_competency $usercompetency The user competency. * @return bool */ public function matches(user_competency $usercompetency) { global $DB; // TODO Improve performance here, perhaps the caller could already provide records. $children = competency::get_records(array('parentid' => $this->competency->get_id())); if (empty($children)) { // Leaves are not compatible with this rule. return false; } $ids = array(); foreach ($children as $child) { $ids[] = $child->get_id(); } list($insql, $params) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED); $sql = "userid = :userid\n AND proficiency = :proficiency\n AND competencyid {$insql}"; $params['userid'] = $usercompetency->get_userid(); $params['proficiency'] = 1; // Is the user is marked as proficient in all children? return user_competency::count_records_select($sql, $params) === count($ids); }
public function test_delete_framework_competency_used_in_course() { $this->resetAfterTest(true); $dg = $this->getDataGenerator(); $lpg = $dg->get_plugin_generator('core_competency'); $this->setAdminUser(); $cat1 = $dg->create_category(); $u1 = $dg->create_user(); $course = $dg->create_course(array('category' => $cat1->id)); $f1 = $lpg->create_framework(); $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $c2id = $c2->get_id(); $c1a = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1->get_id())); $c1b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1a->get_id())); $c11b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); $c12b = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id(), 'parentid' => $c1b->get_id())); // Create related competencies. $rc = $lpg->create_related_competency(array('competencyid' => $c2->get_id(), 'relatedcompetencyid' => $c11b->get_id())); $this->assertEquals($c11b->get_id(), $rc->get_relatedcompetencyid()); // Creating a standard evidence with minimal information. $uc1 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c11b->get_id())); $usercompetencyid = $uc1->get_id(); $evidence = $lpg->create_evidence(array('usercompetencyid' => $usercompetencyid)); $this->assertEquals($uc1->get_id(), $evidence->get_usercompetencyid()); $uc1->delete(); // Add competency to course. $cc = $lpg->create_course_competency(array('courseid' => $course->id, 'competencyid' => $c11b->get_id())); // We can not delete a framework if the competency or competencies children is linked to a course. $this->assertFalse(api::delete_framework($f1->get_id())); // Check that none of associated data are deleted. $this->assertEquals($usercompetencyid, $evidence->read()->get_usercompetencyid()); $this->assertEquals($c2->get_id(), $rc->read()->get_competencyid()); // We can delete the framework if we remove the competency from course. $cc->delete(); $this->assertTrue(api::delete_framework($f1->get_id())); $this->assertFalse(competency::record_exists($c1->get_id())); $this->assertFalse(competency::record_exists($c2->get_id())); $this->assertFalse(competency::record_exists($c1a->get_id())); $this->assertFalse(competency::record_exists($c1b->get_id())); $this->assertFalse(competency::record_exists($c11b->get_id())); $this->assertFalse(competency::record_exists($c12b->get_id())); // Check if evidence are also deleted. $this->assertEquals(0, \core_competency\user_evidence_competency::count_records(array('competencyid' => $c11b->get_id()))); // Check if related conpetency relation is deleted. $this->assertEquals(0, count(\core_competency\related_competency::get_multiple_relations(array($c2id)))); }
/** * Process a course module competency. * * @param array $data The data. */ public function process_course_module_competency($data) { $data = (object) $data; // Mapping the competency by ID numbers. $framework = \core_competency\competency_framework::get_record(array('idnumber' => $data->frameworkidnumber)); if (!$framework) { return; } $competency = \core_competency\competency::get_record(array('idnumber' => $data->idnumber, 'competencyframeworkid' => $framework->get_id())); if (!$competency) { return; } $params = array('competencyid' => $competency->get_id(), 'cmid' => $this->task->get_moduleid()); $query = 'competencyid = :competencyid AND cmid = :cmid'; $existing = \core_competency\course_module_competency::record_exists_select($query, $params); if (!$existing) { // Sortorder is ignored by precaution, anyway we should walk through the records in the right order. $record = (object) $params; $record->ruleoutcome = $data->ruleoutcome; $coursemodulecompetency = new \core_competency\course_module_competency(0, $record); $coursemodulecompetency->create(); } }
/** * Create an evidence from a list of parameters. * * Requires no capability because evidence can be added in many situations under any user. * * @param int $userid The user id for which evidence is added. * @param competency|int $competencyorid The competency, or its id for which evidence is added. * @param context|int $contextorid The context in which the evidence took place. * @param int $action The type of action to take on the competency. \core_competency\evidence::ACTION_*. * @param string $descidentifier The strings identifier. * @param string $desccomponent The strings component. * @param mixed $desca Any arguments the string requires. * @param bool $recommend When true, the user competency will be sent for review. * @param string $url The url the evidence may link to. * @param int $grade The grade, or scale ID item. * @param int $actionuserid The ID of the user who took the action of adding the evidence. Null when system. * This should be used when the action was taken by a real person, this will allow * to keep track of all the evidence given by a certain person. * @param string $note A note to attach to the evidence. * @return evidence * @throws coding_exception * @throws invalid_persistent_exception * @throws moodle_exception */ public static function add_evidence($userid, $competencyorid, $contextorid, $action, $descidentifier, $desccomponent, $desca = null, $recommend = false, $url = null, $grade = null, $actionuserid = null, $note = null) { global $DB; static::require_enabled(); // Some clearly important variable assignments right there. $competencyid = $competencyorid; $competency = null; if (is_object($competencyid)) { $competency = $competencyid; $competencyid = $competency->get_id(); } $contextid = $contextorid; $context = $contextorid; if (is_object($contextorid)) { $contextid = $contextorid->id; } else { $context = context::instance_by_id($contextorid); } $setucgrade = false; $ucgrade = null; $ucproficiency = null; $usercompetencycourse = null; // Fetch or create the user competency. $usercompetency = user_competency::get_record(array('userid' => $userid, 'competencyid' => $competencyid)); if (!$usercompetency) { $usercompetency = user_competency::create_relation($userid, $competencyid); $usercompetency->create(); } // What should we be doing? switch ($action) { // Completing a competency. case evidence::ACTION_COMPLETE: // The logic here goes like this: // // if rating outside a course // - set the default grade and proficiency ONLY if there is no current grade // else we are in a course // - set the defautl grade and proficiency in the course ONLY if there is no current grade in the course // - then check the course settings to see if we should push the rating outside the course // - if we should push it // --- push it only if the user_competency (outside the course) has no grade // Done. if ($grade !== null) { throw new coding_exception("The grade MUST NOT be set with a 'completing' evidence."); } // Fetch the default grade to attach to the evidence. if (empty($competency)) { $competency = new competency($competencyid); } list($grade, $proficiency) = $competency->get_default_grade(); // Add user_competency_course record when in a course or module. if (in_array($context->contextlevel, array(CONTEXT_COURSE, CONTEXT_MODULE))) { $coursecontext = $context->get_course_context(); $courseid = $coursecontext->instanceid; $filterparams = array('userid' => $userid, 'competencyid' => $competencyid, 'courseid' => $courseid); // Fetch or create user competency course. $usercompetencycourse = user_competency_course::get_record($filterparams); if (!$usercompetencycourse) { $usercompetencycourse = user_competency_course::create_relation($userid, $competencyid, $courseid); $usercompetencycourse->create(); } // Only update the grade and proficiency if there is not already a grade. if ($usercompetencycourse->get_grade() === null) { // Set grade. $usercompetencycourse->set_grade($grade); // Set proficiency. $usercompetencycourse->set_proficiency($proficiency); } // Check the course settings to see if we should push to user plans. $coursesettings = course_competency_settings::get_by_courseid($courseid); $setucgrade = $coursesettings->get_pushratingstouserplans(); if ($setucgrade) { // Only push to user plans if there is not already a grade. if ($usercompetency->get_grade() !== null) { $setucgrade = false; } else { $ucgrade = $grade; $ucproficiency = $proficiency; } } } else { // When completing the competency we fetch the default grade from the competency. But we only mark // the user competency when a grade has not been set yet. Complete is an action to use with automated systems. if ($usercompetency->get_grade() === null) { $setucgrade = true; $ucgrade = $grade; $ucproficiency = $proficiency; } } break; // We override the grade, even overriding back to not set. // We override the grade, even overriding back to not set. case evidence::ACTION_OVERRIDE: $setucgrade = true; $ucgrade = $grade; if (empty($competency)) { $competency = new competency($competencyid); } if ($ucgrade !== null) { $ucproficiency = $competency->get_proficiency_of_grade($ucgrade); } // Add user_competency_course record when in a course or module. if (in_array($context->contextlevel, array(CONTEXT_COURSE, CONTEXT_MODULE))) { $coursecontext = $context->get_course_context(); $courseid = $coursecontext->instanceid; $filterparams = array('userid' => $userid, 'competencyid' => $competencyid, 'courseid' => $courseid); // Fetch or create user competency course. $usercompetencycourse = user_competency_course::get_record($filterparams); if (!$usercompetencycourse) { $usercompetencycourse = user_competency_course::create_relation($userid, $competencyid, $courseid); $usercompetencycourse->create(); } // Get proficiency. $proficiency = $ucproficiency; if ($proficiency === null) { if (empty($competency)) { $competency = new competency($competencyid); } $proficiency = $competency->get_proficiency_of_grade($grade); } // Set grade. $usercompetencycourse->set_grade($grade); // Set proficiency. $usercompetencycourse->set_proficiency($proficiency); $coursesettings = course_competency_settings::get_by_courseid($courseid); if (!$coursesettings->get_pushratingstouserplans()) { $setucgrade = false; } } break; // Simply logging an evidence. // Simply logging an evidence. case evidence::ACTION_LOG: if ($grade !== null) { throw new coding_exception("The grade MUST NOT be set when 'logging' an evidence."); } break; // Whoops, this is not expected. // Whoops, this is not expected. default: throw new coding_exception('Unexpected action parameter when registering an evidence.'); break; } // Should we recommend? if ($recommend && $usercompetency->get_status() == user_competency::STATUS_IDLE) { $usercompetency->set_status(user_competency::STATUS_WAITING_FOR_REVIEW); } // Setting the grade and proficiency for the user competency. $wascompleted = false; if ($setucgrade == true) { if (!$usercompetency->get_proficiency() && $ucproficiency) { $wascompleted = true; } $usercompetency->set_grade($ucgrade); $usercompetency->set_proficiency($ucproficiency); } // Prepare the evidence. $record = new stdClass(); $record->usercompetencyid = $usercompetency->get_id(); $record->contextid = $contextid; $record->action = $action; $record->descidentifier = $descidentifier; $record->desccomponent = $desccomponent; $record->grade = $grade; $record->actionuserid = $actionuserid; $record->note = $note; $evidence = new evidence(0, $record); $evidence->set_desca($desca); $evidence->set_url($url); // Validate both models, we should not operate on one if the other will not save. if (!$usercompetency->is_valid()) { throw new invalid_persistent_exception($usercompetency->get_errors()); } else { if (!$evidence->is_valid()) { throw new invalid_persistent_exception($evidence->get_errors()); } } // Save the user_competency_course record. if ($usercompetencycourse !== null) { // Validate and update. if (!$usercompetencycourse->is_valid()) { throw new invalid_persistent_exception($usercompetencycourse->get_errors()); } $usercompetencycourse->update(); } // Finally save. Pheww! $usercompetency->update(); $evidence->create(); // Trigger the evidence_created event. \core\event\competency_evidence_created::create_from_evidence($evidence, $usercompetency, $recommend)->trigger(); // The competency was marked as completed, apply the rules. if ($wascompleted) { self::apply_competency_rules_from_usercompetency($usercompetency, $competency); } return $evidence; }
/** * Create a new competency. * * @param array|stdClass $record * @return competency */ public function create_competency($record = null) { $this->frameworkcount++; $i = $this->frameworkcount; $record = (object) $record; if (!isset($record->competencyframeworkid)) { throw new coding_exception('The competencyframeworkid value is required.'); } if (!isset($record->shortname)) { $record->shortname = "Competency shortname {$i}"; } if (!isset($record->idnumber)) { $record->idnumber = "cmp{$i}"; } if (!isset($record->description)) { $record->description = "Competency {$i} description "; } if (!isset($record->descriptionformat)) { $record->descriptionformat = FORMAT_HTML; } if (isset($record->scaleconfiguration) && (is_array($record->scaleconfiguration) || is_object($record->scaleconfiguration))) { // Conveniently encode the config. $record->scaleconfiguration = json_encode($record->scaleconfiguration); } $competency = new competency(0, $record); $competency->create(); return $competency; }
/** * Set-up a competency page. * * Example: * list($title, $subtitle) = page_helper::setup_for_competency($pagecontextid, $url, $competency, $pagetitle); * echo $OUTPUT->heading($title); * echo $OUTPUT->heading($subtitle, 3); * * @param int $pagecontextid The page context ID. * @param moodle_url $url The current page. * @param \core_competency\competency_framework $framework The competency framework. * @param \core_competency\competency $competency The competency, if any. * @param \core_competency\competency $parent The parent competency, if any. * @return array With the following: * - Page title * - Page sub title * - Return URL (main competencies page) * @throws coding_exception */ public static function setup_for_competency($pagecontextid, moodle_url $url, $framework, $competency = null, $parent = null) { global $PAGE, $SITE; // Set page context. $pagecontext = context::instance_by_id($pagecontextid); $PAGE->set_context($pagecontext); // Set page heading. if ($pagecontext->contextlevel == CONTEXT_SYSTEM) { $heading = $SITE->fullname; } else { if ($pagecontext->contextlevel == CONTEXT_COURSECAT) { $heading = $pagecontext->get_context_name(); } else { throw new coding_exception('Unexpected context!'); } } $PAGE->set_heading($heading); // Set override active url. $frameworksurl = new moodle_url('/admin/tool/lp/competencyframeworks.php', ['pagecontextid' => $pagecontextid]); $PAGE->navigation->override_active_url($frameworksurl); // Set return url. $returnurloptions = ['competencyframeworkid' => $framework->get_id(), 'pagecontextid' => $pagecontextid]; $returnurl = new moodle_url('/admin/tool/lp/competencies.php', $returnurloptions); $PAGE->navbar->add($framework->get_shortname(), $returnurl); // Set page layout. $PAGE->set_pagelayout('admin'); if (empty($competency)) { // Add mode. $title = format_string($framework->get_shortname(), true, ['context' => $pagecontext]); // Set the sub-title for add mode. $level = $parent ? $parent->get_level() + 1 : 1; $subtitle = get_string('taxonomy_add_' . $framework->get_taxonomy($level), 'tool_lp'); } else { // Edit mode. $title = format_string($competency->get_shortname(), true, ['context' => $competency->get_context()]); // Add competency name to breadcrumbs, if available. $PAGE->navbar->add($title); // Set the sub-title for edit mode. $subtitle = get_string('taxonomy_edit_' . $framework->get_taxonomy($competency->get_level()), 'tool_lp'); } // Set page title. $PAGE->set_title($title); // Set page url. $PAGE->set_url($url); // Add editing mode link to breadcrumbs, if available. if (!empty($subtitle)) { $PAGE->navbar->add($subtitle, $url); } return [$title, $subtitle, $returnurl]; }
/** * Get descendant ids. * * @param competency $competency The competency. * @return array Array of competencies ids. */ public static function get_descendants_ids($competency) { global $DB; $path = $DB->sql_like_escape($competency->get_path() . $competency->get_id() . '/') . '%'; $like = $DB->sql_like('path', ':likepath'); return $DB->get_fieldset_select(self::TABLE, 'id', $like, array('likepath' => $path)); }
/** * 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) { $data = new stdClass(); $exporter = new competency_framework_exporter($this->framework); $data->framework = $exporter->export($output); $data->canmanage = $this->canmanage; $data->search = $this->search; $data->pagecontextid = $this->pagecontext->id; $data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true); $rulesmodules = array(); $rules = competency::get_available_rules(); foreach ($rules as $type => $rulename) { $amd = null; if ($type == 'core_competency\\competency_rule_all') { $amd = 'tool_lp/competency_rule_all'; } else { if ($type == 'core_competency\\competency_rule_points') { $amd = 'tool_lp/competency_rule_points'; } else { // We do not know how to display that rule. continue; } } $rulesmodules[] = ['name' => (string) $rulename, 'type' => $type, 'amd' => $amd]; } $data->rulesmodules = json_encode(array_values($rulesmodules)); return $data; }
/** * List the competencies in this course. * * @param int $courseid The course id * @return competency[] Indexed by competency ID. */ public static function list_competencies($courseid) { global $DB; $sql = 'SELECT comp.* FROM {' . competency::TABLE . '} comp JOIN {' . self::TABLE . '} coursecomp ON coursecomp.competencyid = comp.id WHERE coursecomp.courseid = ?'; $params = array($courseid); $sql .= ' ORDER BY coursecomp.sortorder ASC'; $results = $DB->get_recordset_sql($sql, $params); $instances = array(); foreach ($results as $result) { $comp = new competency(0, $result); $instances[$comp->get_id()] = $comp; } $results->close(); return $instances; }
/** * Get the list of competencies that were completed the least times (in completed plans) from a template. * * @param int $templateid * @param int $skip The number of competencies to skip * @param int $limit The max number of competencies to return * @return competency[] */ public static function get_least_proficient_competencies_for_template($templateid, $skip = 0, $limit = 0) { global $DB; $fields = competency::get_sql_fields('c', 'c_'); $params = array('templateid' => $templateid, 'notproficient' => false); $sql = 'SELECT ' . $fields . ' FROM (SELECT ucp.competencyid, COUNT(ucp.competencyid) AS timesnotproficient FROM {' . self::TABLE . '} ucp JOIN {' . plan::TABLE . '} p ON p.id = ucp.planid WHERE p.templateid = :templateid AND (ucp.proficiency = :notproficient OR ucp.proficiency IS NULL) GROUP BY ucp.competencyid ) p JOIN {' . competency::TABLE . '} c ON c.id = p.competencyid ORDER BY p.timesnotproficient DESC, c.id ASC'; $results = $DB->get_records_sql($sql, $params, $skip, $limit); $comps = array(); foreach ($results as $r) { $c = competency::extract_record($r, 'c_'); $comps[] = new competency(0, $c); } return $comps; }
/** * Get the competencies related to a competency. * * @param int $competencyid The competency ID. * @return competency[] */ public static function get_related_competencies($competencyid) { global $DB; $fields = competency::get_sql_fields('c', 'c_'); $sql = "(SELECT {$fields}, " . $DB->sql_concat('rc.relatedcompetencyid', "'_'", 'rc.competencyid') . " AS rid\n FROM {" . self::TABLE . "} rc\n JOIN {" . competency::TABLE . "} c\n ON c.id = rc.relatedcompetencyid\n WHERE rc.competencyid = :cid)\n UNION ALL\n (SELECT {$fields}, " . $DB->sql_concat('rc.competencyid', "'_'", 'rc.relatedcompetencyid') . " AS rid\n FROM {" . self::TABLE . "} rc\n JOIN {" . competency::TABLE . "} c\n ON c.id = rc.competencyid\n WHERE rc.relatedcompetencyid = :cid2)\n ORDER BY c_path ASC, c_sortorder ASC"; $competencies = array(); $records = $DB->get_recordset_sql($sql, array('cid' => $competencyid, 'cid2' => $competencyid)); foreach ($records as $record) { unset($record->rid); $competencies[$record->c_id] = new competency(null, competency::extract_record($record, 'c_')); } $records->close(); return $competencies; }
/** * Get the list of competencies that were completed the least times in a course. * * @param int $courseid * @param int $skip The number of competencies to skip * @param int $limit The max number of competencies to return * @return competency[] */ public static function get_least_proficient_competencies_for_course($courseid, $skip = 0, $limit = 0) { global $DB; $fields = competency::get_sql_fields('c', 'c_'); $params = array('courseid' => $courseid); $sql = 'SELECT ' . $fields . ' FROM (SELECT cc.competencyid, SUM(COALESCE(ucc.proficiency, 0)) AS timesproficient FROM {' . course_competency::TABLE . '} cc LEFT JOIN {' . self::TABLE . '} ucc ON ucc.competencyid = cc.competencyid AND ucc.courseid = cc.courseid WHERE cc.courseid = :courseid GROUP BY cc.competencyid ) p JOIN {' . competency::TABLE . '} c ON c.id = p.competencyid ORDER BY p.timesproficient ASC, c.id DESC'; $results = $DB->get_records_sql($sql, $params, $skip, $limit); $a = $DB->get_records_sql('SELECT * from {' . self::TABLE . '}'); $comps = array(); foreach ($results as $r) { $c = competency::extract_record($r, 'c_'); $comps[] = new competency(0, $c); } return $comps; }
/** * Return the current depth of a competency framework. * * @see competency::get_framework_depth() * @return int */ public function get_depth() { return competency::get_framework_depth($this->get_id()); }