Esempio n. 1
0
 /**
  * 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;
 }
Esempio n. 2
0
 /**
  * Tests for the user_competency_course data when api::add_evidence() is invoked when
  * grading a user competency in a course.
  */
 public function test_add_evidence_user_competency_course_grade_in_course()
 {
     global $USER;
     $this->resetAfterTest(true);
     $dg = $this->getDataGenerator();
     // Create a course.
     $course = $dg->create_course();
     $record = array('courseid' => $course->id, 'pushratingstouserplans' => false);
     $settings = new course_competency_settings(0, (object) $record);
     $settings->create();
     $coursecontext = context_course::instance($course->id);
     // Create a student and enrol into the course.
     $student = $dg->create_user();
     $studentarch = get_archetype_roles('student');
     $studentrole = array_shift($studentarch);
     $dg->role_assign($studentrole->id, $student->id, $coursecontext->id);
     $dg->enrol_user($student->id, $course->id, $studentrole->id);
     // Create a competency for the course.
     $lpg = $dg->get_plugin_generator('core_competency');
     $framework = $lpg->create_framework();
     // Do not push ratings from course to user plans.
     $comp = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
     $lpg->create_course_competency(array('courseid' => $course->id, 'competencyid' => $comp->get_id()));
     // Query for user_competency_course data.
     $filterparams = array('userid' => $student->id, 'competencyid' => $comp->get_id(), 'courseid' => $course->id);
     // Add evidence that sets a grade to the course.
     $evidence = api::add_evidence($student->id, $comp, $coursecontext, evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 3, $USER->id);
     // Get user competency course record.
     $usercompcourse = \core_competency\user_competency_course::get_record($filterparams);
     // There should be a user_competency_course object when adding a grade.
     $this->assertNotEmpty($usercompcourse);
     $grade = $evidence->get_grade();
     $this->assertEquals($grade, $usercompcourse->get_grade());
     $this->assertEquals(3, $usercompcourse->get_grade());
     $proficiency = $comp->get_proficiency_of_grade($grade);
     $this->assertEquals($proficiency, $usercompcourse->get_proficiency());
     // Confirm that the user competency's grade/proficiency has not been affected by the grade.
     $usercompetencyparams = ['userid' => $student->id, 'competencyid' => $comp->get_id()];
     $usercompetency = \core_competency\user_competency::get_record($usercompetencyparams);
     $this->assertNotEmpty($usercompetency);
     $this->assertNotEquals($usercompcourse->get_grade(), $usercompetency->get_grade());
     $this->assertNotEquals($usercompcourse->get_proficiency(), $usercompetency->get_proficiency());
 }
 public function test_who_can_change_settings()
 {
     global $CFG, $DB;
     $this->resetAfterTest(true);
     $syscontext = context_system::instance();
     $dg = $this->getDataGenerator();
     $lpg = $dg->get_plugin_generator('core_competency');
     $role = create_role('Settings changer role', 'settingschanger', 'Someone who can change course competency settings');
     assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $role, $syscontext->id);
     assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $role, $syscontext->id);
     assign_capability('moodle/competency:coursecompetencyview', CAP_ALLOW, $role, $syscontext->id);
     assign_capability('moodle/competency:planview', CAP_ALLOW, $role, $syscontext->id);
     $gradedrole = create_role('Graded role', 'graded', 'Someone who can be graded');
     assign_capability('moodle/competency:coursecompetencygradable', CAP_ALLOW, $gradedrole, $syscontext->id);
     $c1 = $dg->create_course();
     $u1 = $dg->create_user();
     $u2 = $dg->create_user();
     $u3 = $dg->create_user();
     $framework = $lpg->create_framework();
     $comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
     $comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
     $lpg->create_course_competency(array('competencyid' => $comp1->get_id(), 'courseid' => $c1->id));
     $lpg->create_course_competency(array('competencyid' => $comp2->get_id(), 'courseid' => $c1->id));
     // Enrol the user.
     $dg->enrol_user($u1->id, $c1->id);
     role_assign($gradedrole, $u1->id, $syscontext->id);
     // Assign roles.
     role_assign($role, $u2->id, $syscontext->id);
     $this->setUser($u2);
     set_config('pushcourseratingstouserplans', true, 'core_competency');
     $coursesettings = course_competency_settings::get_by_courseid($c1->id);
     $this->assertTrue((bool) $coursesettings->get_pushratingstouserplans());
     set_config('pushcourseratingstouserplans', false, 'core_competency');
     $coursesettings = course_competency_settings::get_by_courseid($c1->id);
     $this->assertFalse((bool) $coursesettings->get_pushratingstouserplans());
     api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => true));
     $coursesettings = course_competency_settings::get_by_courseid($c1->id);
     $this->assertTrue((bool) $coursesettings->get_pushratingstouserplans());
     set_config('pushcourseratingstouserplans', true, 'core_competency');
     api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => false));
     $coursesettings = course_competency_settings::get_by_courseid($c1->id);
     $this->assertFalse((bool) $coursesettings->get_pushratingstouserplans());
     // Right now the setting is false.
     api::grade_competency_in_course($c1->id, $u1->id, $comp1->get_id(), 1, 'Note');
     $filterparams = array('userid' => $u1->id, 'competencyid' => $comp1->get_id());
     $usercompcourse = \core_competency\user_competency_course::get_record($filterparams);
     $usercomp = \core_competency\user_competency::get_record($filterparams);
     // No grade in plan - only a grade in the course.
     $this->assertEmpty($usercomp->get_grade());
     $this->assertEquals(1, $usercompcourse->get_grade());
     api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => true));
     api::grade_competency_in_course($c1->id, $u1->id, $comp1->get_id(), 2, 'Note 2');
     $filterparams = array('userid' => $u1->id, 'competencyid' => $comp1->get_id());
     $usercompcourse = \core_competency\user_competency_course::get_record($filterparams);
     $usercomp = \core_competency\user_competency::get_record($filterparams);
     // Updated grade in plan - updated grade in the course.
     $this->assertEquals(2, $usercomp->get_grade());
     $this->assertEquals(2, $usercompcourse->get_grade());
     $this->setUser($u3);
     $this->setExpectedException('required_capability_exception');
     api::update_course_competency_settings($c1->id, (object) array('pushratingstouserplans' => false));
 }