libdir.'/externallib.php'); use \local_treestudyplan\courseinfo; use \local_treestudyplan\local\helpers\webservicehelper; class courseservice extends \external_api { /************************ * * * list_courses * * * ************************/ public static function map_categories_parameters() { return new \external_function_parameters( [ "root_id" => new \external_value(PARAM_INT, 'root category to use as base', VALUE_DEFAULT), ] ); } public static function map_categories_returns() { return new \external_multiple_structure(static::map_category_structure(false)); } protected static function map_category_structure($lazy=false,$value=VALUE_REQUIRED) { $s = [ "id" => new \external_value(PARAM_INT, 'course category id'), "context_id" => new \external_value(PARAM_INT, 'course category context id'), "category" => contextinfo::structure(VALUE_OPTIONAL), "haschildren" => new \external_value(PARAM_BOOL, 'True if the category has child categories'), "hascourses" => new \external_value(PARAM_BOOL, 'True if the category contains courses'), "studyplancount" => new \external_value(PARAM_INT, 'number of linked studyplans',VALUE_OPTIONAL), ]; if(!$lazy > 0) { $s["courses"] = new \external_multiple_structure( courseinfo::editor_structure() ); $s["children"] = new \external_multiple_structure( static::map_category_structure(true)); } return new \external_single_structure($s,"CourseCat info",$value); } public static function map_categories($root_id = 0){ global $CFG, $DB; $root = \core_course_category::get($root_id); $context = $root->get_context(); // Make sure the user has access to the context for editing purposes webservicehelper::require_capabilities("local/treestudyplan:editstudyplan",$context); // Determine top categories from provided context if($root->id == 0){ // on the system level, determine the user's topmost allowed catecories $user_top = \core_course_category::user_top(); if($user_top->id == 0){ // top category.. $children = $root->get_children(); // returns a list of çore_course_category, let it overwrite $children } else { $children = [$user_top]; } } else if ($root->is_uservisible()){ $children = [$root]; } foreach($children as $cat){ $list[] = static::map_category($cat,false); } return $list; } public static function get_category_parameters() { return new \external_function_parameters( [ "id" => new \external_value(PARAM_INT, 'id of category'), ] ); } public static function get_category_returns() { return static::map_category_structure(false); } public static function get_category($id){ $cat = \core_course_category::get($id); return static::map_category($cat); } protected static function map_category(\core_course_category $cat,$lazy=false){ global $DB; $catcontext = $cat->get_context(); $ctx_info = new contextinfo($catcontext); $children = $cat->get_children(); // only shows children visible to the current user $courses = $cat->get_courses(); $model = [ "id" => $cat->id, "context_id" => $catcontext->id, "category" => $ctx_info->model(), "haschildren" => !empty($children), "hascourses" => !empty($courses), ]; if(!$lazy) { $model["courses"] = []; foreach($courses as $course){ $courseinfo = new courseinfo($course->id); $model["courses"][] = $courseinfo->editor_model(); } $model["children"] = []; foreach($children as $child){ $model["children"][] = static::map_category($child,true); } } return $model; } public static function list_accessible_categories_parameters() { return new \external_function_parameters( [ "operation" => new \external_value(PARAM_TEXT, 'type of operation ["view"|"edit"]',VALUE_DEFAULT),] ); } public static function list_accessible_categories_returns() { return new \external_multiple_structure(static::map_category_structure(true)); } public static function list_accessible_categories($operation="edit") { if($operation == "edit"){ $capability = "local/treestudyplan:editstudyplan"; } else { // $operation == "view" || default $capability = "local/treestudyplan:viewuserreports"; } $cats = static::categories_by_capability($capability); $list = []; /* @var $cat \core_course_category */ foreach($cats as $cat){ $list[] = static::map_category($cat,true); } return $list; } public static function categories_by_capability($capability,\core_course_category $parent=null){ // List the categories in which the user has a specific capability $list = []; // initialize parent if needed if($parent == null){ $parent = \core_course_category::user_top(); if(has_capability($capability,$parent->get_context())){ $list[] = $parent; } } $children = $parent->get_children(); foreach($children as $child){ // Check if we should add this category if(has_capability($capability,$child->get_context())){ $list[] = $child; // For optimization purposes, we include all its children now, since they will have inherited the permission // #PREMATURE_OPTIMIZATION ??? $list = array_merge($list,self::recursive_child_categories($child)); } else { if($child->get_children_count() > 0){ $list = array_merge($list,self::categories_by_capability($capability,$child)); } } } return $list; } protected static function recursive_child_categories(\core_course_category $parent){ $list = []; $children = $parent->get_children(); foreach($children as $child){ $list[] = $child; if($child->get_children_count() > 0){ $list = array_merge($list,self::recursive_child_categories($child)); } } return $list; } public static function list_used_categories_parameters() { return new \external_function_parameters( [ "operation" => new \external_value(PARAM_TEXT, 'type of operation ["view"|"edit"]',VALUE_DEFAULT), ]); } public static function list_used_categories_returns() { return new \external_multiple_structure(static::map_category_structure(true)); } public static function list_used_categories($operation='edit') { global $DB; if($operation == "edit"){ $capability = "local/treestudyplan:editstudyplan"; } else { // $operation == "view" || default $capability = "local/treestudyplan:viewuserreports"; } $context_ids = []; $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan} GROUP BY context_id"); foreach($rs as $r){ $context_ids[$r->context_id] = $r->num; } $rs->close(); // Now filter the categories that the user has acces to by the used context id's // (That should filter out irrelevant stuff) $cats = static::categories_by_capability($capability); $list = []; foreach($cats as $cat){ $count = 0; $ctxid = $cat->get_context()->id; if(array_key_exists($ctxid,$context_ids)){ $count = $context_ids[$ctxid]; } $o = static::map_category($cat,true); $o["studyplancount"] = $count; $list[] = $o; } return $list; } public static function list_accessible_categories_with_usage($operation='edit'){ global $DB; if($operation == "edit"){ $capability = "local/treestudyplan:editstudyplan"; } else { // $operation == "view" || default $capability = "local/treestudyplan:viewuserreports"; } // retrieve context ids used $context_ids = []; $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan} GROUP BY context_id"); foreach($rs as $r){ $context_ids[$r->context_id] = $r->num; } $rs->close(); // Now filter the categories that the user has acces to by the used context id's // (That should filter out irrelevant stuff) $cats = static::categories_by_capability($capability); $list = []; foreach($cats as $cat){ $count = 0; $ctxid = $cat->get_context()->id; if(array_key_exists($ctxid,$context_ids)){ $count = $context_ids[$ctxid]; } $o = new \stdClass(); $o->cat = $cat; $o->count = $count; $list[] = $o; } return $list; } }