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 $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'), "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' => userdate($this->course->startdate,"%e %b %G"), 'enddate' => userdate($this->course->enddate, "%e %b %G"), 'amteacher' => $this->amTeacher(), '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(); } } 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' => userdate($this->course->startdate,"%e %b %G"), 'enddate' => userdate($this->course->enddate, "%e %b %G"), '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; } }