. /** * * @package local_treestudyplan * @copyright 2023 P.M. Kuipers * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace local_treestudyplan; require_once($CFG->libdir.'/externallib.php'); require_once($CFG->libdir.'/gradelib.php'); require_once($CFG->dirroot.'/course/lib.php'); use core_course\local\repository\caching_content_item_readonly_repository; use core_course\local\repository\content_item_readonly_repository; use \grade_item; use \grade_scale; use \grade_outcome; class courseinfo { const TABLE = 'course'; private $course; private $context; private $coursecontext; private $studyitem; private static $contentitems = null; public function id() { return $this->course->id; } public function shortname() { return $this->course->shortname; } public function course() { return $this->course; // Php arrays are assigned by copy. } public function course_context() { return $this->coursecontext; } public function category_context() { return $this->context; } protected function get_contentitems() { global $PAGE; if (empty(static::$contentitems)) { $PAGE->set_context(\context_system::instance()); static::$contentitems = (new content_item_readonly_repository())->find_all(); } return static::$contentitems; } protected function amTeacher() { global $USER; return is_enrolled($this->coursecontext, $USER, 'mod/assign:grade'); } protected function iCanSelectGradables($userid=-1) { global $USER, $DB; if ($userid <= 0) { $usr = $USER; } else { $usr = $DB->get_record('user', ['id' => $userid, 'deleted' => 0]); } return($usr && is_enrolled($this->coursecontext, $usr, 'local/treestudyplan:selectowngradables')); } public static function get_contentitem($name) { $contentitems = static::get_contentitems(); for ($i = 0; $i < count($contentitems); $i++) { if ($contentitems[$i]->get_name() == $name) { return $contentitems[$i]; } } return null; } public function __construct($id, studyitem $studyitem = null) { global $DB; $this->studyitem = $studyitem; $this->course = \get_course($id); $this->context = \context_coursecat::instance($this->course->category); $this->coursecontext = \context_course::instance($this->course->id); } public static function exists($id) { global $DB; return is_numeric($id) && $DB->record_exists(self::TABLE, ['id' => $id]); } public static function id_from_shortname($shortname) { global $DB; return $DB->get_field(self::TABLE, "id", ['shortname' => $shortname]); } public static function coursetiming($course) { $now = time(); if ($now > $course->startdate) { if ($course->enddate > 0 && $now > $course->enddate) { return "past"; } else { return "present"; } } else { return "future"; } } public function timing() { return self::coursetiming($this->course); } public function displayname() { $displayfield = get_config("local_treestudyplan", "display_field"); if ($displayfield == "idnumber") { $idnumber = trim(preg_replace("/\s+/u", " ", $this->course->idnumber)); if (strlen($idnumber) > 0) { return $this->course->idnumber; } } else if (strpos( $displayfield , "customfield_") === 0) { $fieldname = substr($displayfield, strlen("customfield_")); $handler = \core_customfield\handler::get_handler('core_course', 'course'); $datas = $handler->get_instance_data($this->course->id); foreach ($datas as $data) { if ($data->get_field()->get('shortname') == $fieldname) { $value = trim(preg_replace("/\s+/u", " ", $data->get_value())); if (strlen($value) > 0) { return $value; } } } } // Fallback to shortname when the specified display field fails, since shortname is never empty. return $this->course->shortname; } public static function simple_structure($value=VALUE_REQUIRED) { return new \external_single_structure([ "id" => new \external_value(PARAM_INT, 'linked course id'), "fullname" => new \external_value(PARAM_TEXT, 'linked course name'), "shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'), "displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'), "context" => contextinfo::structure(VALUE_OPTIONAL), ], 'referenced course information', $value); } public function simple_model() { $contextinfo = new contextinfo($this->context); $info = [ 'id' => $this->course->id, 'fullname' => $this->course->fullname, 'shortname' => $this->course->shortname, 'displayname' => $this->displayname(), 'context' => $contextinfo->model() ]; return $info; } public static function editor_structure($value=VALUE_REQUIRED) { return new \external_single_structure([ "id" => new \external_value(PARAM_INT, 'linked course id'), "fullname" => new \external_value(PARAM_TEXT, 'linked course name'), "shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'), "displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'), "context" => contextinfo::structure(VALUE_OPTIONAL), "ctxid" => new \external_value(PARAM_INT, 'course context id name'), "grades" => new \external_multiple_structure(gradeinfo::editor_structure(), 'grade list (legacy list)', VALUE_OPTIONAL), "completion" => corecompletioninfo::editor_structure(VALUE_OPTIONAL), "timing" => new \external_value(PARAM_TEXT, '(past|present|future)'), "startdate" => new \external_value(PARAM_TEXT, 'Course start date'), "enddate" => new \external_value(PARAM_TEXT, 'Course end date'), "amteacher" => new \external_value(PARAM_BOOL, 'Requesting user is teacher in this course'), "canupdatecourse" => new \external_value(PARAM_BOOL, "If the current user can update this course"), "canselectgradables" => new \external_value(PARAM_BOOL, 'Requesting user can change selected gradables'), "tag" => new \external_value(PARAM_TEXT, 'Tag'), ], 'referenced course information', $value); } public function editor_model(studyitem $studyitem=null, $usecorecompletioninfo=false) { global $DB; $contextinfo = new contextinfo($this->context); $timing = $this->timing(); $info = [ 'id' => $this->course->id, 'fullname' => $this->course->fullname, 'shortname' => $this->course->shortname, 'displayname' => $this->displayname(), 'context' => $contextinfo->model(), 'ctxid' => $this->coursecontext->id, 'timing' => $timing, 'startdate' => date("Y-m-d", $this->course->startdate, ), 'enddate' => date("Y-m-d", $this->course->enddate), 'amteacher' => $this->amTeacher(), 'canupdatecourse' => \has_capability("moodle/course:update", $this->coursecontext), 'canselectgradables' => $this->iCanSelectGradables(), 'tag' => "Editormodel", 'grades' => [], ]; if (!$usecorecompletioninfo) { $gradables = gradeinfo::list_course_gradables($this->course, $studyitem); foreach ($gradables as $gradable) { $info['grades'][] = $gradable->editor_model($studyitem); } } else { $cc = new corecompletioninfo($this->course); $info['completion'] = $cc->editor_model(); } return $info; } public static function user_structure($value=VALUE_REQUIRED) { return new \external_single_structure([ "id" => new \external_value(PARAM_INT, 'linked course id'), "fullname" => new \external_value(PARAM_TEXT, 'linked course name'), "shortname" => new \external_value(PARAM_TEXT, 'linked course shortname'), "displayname" => new \external_value(PARAM_TEXT, 'linked course displayname'), "context" => contextinfo::structure(VALUE_OPTIONAL), "ctxid" => new \external_value(PARAM_INT, 'course context id name'), "grades" => new \external_multiple_structure(gradeinfo::user_structure(), 'grade list (legacy list)', VALUE_OPTIONAL), "completion" => corecompletioninfo::user_structure(VALUE_OPTIONAL), "timing" => new \external_value(PARAM_TEXT, '(past|present|future)'), "startdate" => new \external_value(PARAM_TEXT, 'Course start date'), "enddate" => new \external_value(PARAM_TEXT, 'Course end date'), ], 'course information', $value); } public function user_model($userid, $usecorecompletioninfo=false) { global $DB; $contextinfo = new contextinfo($this->context); $timing = $this->timing(); $info = [ 'id' => $this->course->id, 'fullname' => $this->course->fullname, 'shortname' => $this->course->shortname, 'displayname' => $this->displayname(), 'context' => $contextinfo->model(), 'ctxid' => $this->coursecontext->id, 'timing' => $timing, 'startdate' => date("Y-m-d", $this->course->startdate), 'enddate' => date("Y-m-d", $this->course->enddate), 'grades' => [], ]; if (!$usecorecompletioninfo) { $gradables = gradeinfo::list_studyitem_gradables($this->studyitem); foreach ($gradables as $gi) { $info['grades'][] = $gi->user_model($userid); } } else { $cc = new corecompletioninfo($this->course); $info['completion'] = $cc->user_model($userid); } return $info; } }