. /** * Webservice class for retrieving student studyplans * @package local_treestudyplan * @copyright 2023 P.M. Kuipers * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace local_treestudyplan; defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir.'/externallib.php'); use local_treestudyplan\local\helpers\webservicehelper; use local_treestudyplan\task\autocohortsync; require_once($CFG->libdir.'/badgeslib.php'); /** * Webservice class for retrieving student studyplans */ class studentstudyplanservice extends \external_api { /** * Capability required to view studyplans of other users * @var string */ const CAP_VIEWOTHER = "local/treestudyplan:viewuserreports"; /** * Capability required to be linked as coach to a studyplan * @var string */ const CAP_COACH = "local/treestudyplan:coach"; /************************ * * * list_user_studyplans * * * ************************/ /** * Parameter description for webservice function list_user_studyplans */ public static function list_user_studyplans_parameters(): \external_function_parameters { return new \external_function_parameters([ "userid" => new \external_value(PARAM_INT, 'id of student', VALUE_DEFAULT), ]); } /** * Return value description for webservice function list_user_studyplans */ public static function list_user_studyplans_returns(): \external_description { return new \external_multiple_structure( studyplan::simple_structure() ); } /** * Return overview of the studyplans for a specific user * @param int $userid ID of user to check specific info for * @return array */ public static function list_user_studyplans($userid) { global $CFG, $DB; $list = []; $studyplans = studyplan::find_for_user($userid); foreach ($studyplans as $studyplan) { // Only include studyplans in the context the user has permissions for. if (webservicehelper::has_capabilities(self::CAP_VIEWOTHER, $studyplan->context(), false)) { $list[] = $studyplan->simple_model($userid); } } return $list; } /************************ * * * get_user_studyplan * * * ************************/ /** * Parameter description for webservice function get_user_studyplan */ public static function get_user_studyplan_parameters(): \external_function_parameters { return new \external_function_parameters( [ "userid" => new \external_value(PARAM_INT, 'id of user'), "studyplanid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide'), ] ); } /** * Return value description for webservice function get_user_studyplan */ public static function get_user_studyplan_returns(): \external_description { return studyplan::user_structure(); } /** * Get a specific studyplan for a given user * @param int $userid ID of user to check specific info for * @param int $studyplanid ID of studyplan to view * @return array */ public static function get_user_studyplan($userid, $studyplanid) { global $CFG, $DB; $studyplan = studyplan::find_by_id($studyplanid); if ($studyplan->is_coach() && !$studyplan->suspended()) { \external_api::validate_context($studyplan->context()); } else { webservicehelper::require_capabilities(self::CAP_VIEWOTHER, $studyplan->context()); } if ($studyplan->exist_for_user($userid)) { $model = $studyplan->user_model($userid); return $model; } else { return null; } } /************************ * * * get_user_page * * * ************************/ /** * Parameter description for webservice function get_user_page */ public static function get_user_page_parameters(): \external_function_parameters { return new \external_function_parameters( [ "userid" => new \external_value(PARAM_INT, 'id of user'), "pageid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide'), ] ); } /** * Return value description for webservice function get_user_page */ public static function get_user_page_returns(): \external_description { return studyplan::user_structure(); } /** * Get a specific studyplan page for a given user * @param int $userid ID of user to check specific info for * @param int $pageid ID of studyplan to view * @return array */ public static function get_user_page($userid, $pageid) { global $CFG, $DB; $studyplan = studyplan::find_by_id($pageid); webservicehelper::require_capabilities(self::CAP_VIEWOTHER, $studyplan->context()); if ($studyplan->exist_for_user($userid)) { return $studyplan->user_model($userid); } else { return null; } } /**************************** * * * list_invited_studyplan * * * ****************************/ /** * Parameter description for webservice function list_invited_studyplan */ public static function list_invited_studyplans_parameters(): \external_function_parameters { return new \external_function_parameters( [ "invitekey" => new \external_value(PARAM_RAW, 'invite key'), ] ); } /** * Return value description for webservice function list_invited_studyplan */ public static function list_invited_studyplans_returns(): \external_description { return new \external_multiple_structure( studyplan::simple_structure() ); } /** * List available studyplans based on invite key * @param int $invitekey Invitation key * @return array */ public static function list_invited_studyplans($invitekey) { global $DB; // First check if studyplan sharing is enabled. if (!get_config("local_treestudyplan", "enableplansharing")) { return []; } $invite = $DB->get_record_select( "local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey] ); if (empty($invite)) { return []; } // Do not validate the context in this instance to avoid requiring logins when this is not wanted. $userid = $invite->user_id; $list = []; $studyplans = studyplan::find_for_user($userid); foreach ($studyplans as $studyplan) { $list[] = $studyplan->simple_model($userid); } return $list; } /**************************** * * * get_invited_studyplan * * * ****************************/ /** * Parameter description for webservice function get_invited_studyplan */ public static function get_invited_studyplan_parameters(): \external_function_parameters { return new \external_function_parameters( [ "invitekey" => new \external_value(PARAM_RAW, 'invite key'), "studyplanid" => new \external_value(PARAM_INT, 'studyplan_id'), ] ); } /** * Return value description for webservice function get_invited_studyplan */ public static function get_invited_studyplan_returns(): \external_description { return studyplan::user_structure(); } /** * Get studyplan based on invite key and studyplan id * @param string $invitekey Invitation key * @param int $studyplanid ID of the studyplan to retrieve * @return array */ public static function get_invited_studyplan($invitekey, $studyplanid) { global $DB; // First check if studyplan sharing is enabled. if (!get_config("local_treestudyplan", "enableplansharing")) { return []; } $invite = $DB->get_record_select( "local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey] ); if (empty($invite)) { return []; } // Do not validate the context in this instance to avoid requiring logins when this is not wanted. $studyplan = studyplan::find_by_id($studyplanid); $userid = $invite->user_id; if ($studyplan->exist_for_user($userid)) { if (!$studyplan->suspended()) { return $studyplan->user_model($userid); } else { throw new \moodle_exception("The selected studyplan is suspended"); } } else { throw new \moodle_exception("Invitation's user is not linked to this studyplan"); } } /**************************** * * * get_invited_page * * * ****************************/ /** * Parameter description for webservice function get_invited_studyplan */ public static function get_invited_page_parameters(): \external_function_parameters { return new \external_function_parameters( [ "invitekey" => new \external_value(PARAM_RAW, 'invite key'), "pageid" => new \external_value(PARAM_INT, 'studyplan page id'), ] ); } /** * Return value description for webservice function get_invited_studyplan */ public static function get_invited_page_returns(): \external_description { return studyplanpage::user_structure(); } /** * Get studyplan based on invite key and studyplan id * @param string $invitekey Invitation key * @param int $pageid ID of the studyplan to retrieve * @return array */ public static function get_invited_page($invitekey, $pageid) { global $DB; // First check if studyplan sharing is enabled. if (!get_config("local_treestudyplan", "enableplansharing")) { return []; } $invite = $DB->get_record_select( "local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey] ); if (empty($invite)) { return []; } // Do not validate the context in this instance to avoid requiring logins when this is not wanted. $page = studyplanpage::find_by_id($pageid); $studyplan = $page->studyplan(); $userid = $invite->user_id; if ($studyplan->exist_for_user($userid)) { return $page->user_model($userid); } else { throw new \moodle_exception("Invitation's user is not linked to this studyplan"); } } /************************ * * * list_own_studyplans * * * ************************/ /** * Parameter description for webservice function list_own_studyplans */ public static function list_own_studyplans_parameters(): \external_function_parameters { return new \external_function_parameters([]); } /** * Return value description for webservice function list_own_studyplans */ public static function list_own_studyplans_returns(): \external_description { return new \external_multiple_structure( studyplan::simple_structure() ); } /** * Return overview of the studyplans the current user is linked to * @return array */ public static function list_own_studyplans() { global $CFG, $DB, $USER; $userid = $USER->id; $list = []; $studyplans = studyplan::find_for_user($userid); foreach ($studyplans as $studyplan) { $list[] = $studyplan->simple_model($userid); } return $list; } /************************ * * * get_own_studyplan * * * ************************/ /** * Parameter description for webservice function get_own_studyplan */ public static function get_own_studyplan_parameters(): \external_function_parameters { return new \external_function_parameters( [ "studyplanid" => new \external_value(PARAM_INT, 'id of studyplan to retrieve'), ] ); } /** * Return value description for webservice function get_own_studyplan */ public static function get_own_studyplan_returns(): \external_description { return studyplan::user_structure(); } /** * Get a studyplans for the current user * @param int $studyplanid Id of specific studyplan * @return array */ public static function get_own_studyplan($studyplanid) { global $USER; // Validate this call in the system context. \external_api::validate_context(\context_system::instance()); $userid = $USER->id; $studyplan = studyplan::find_by_id($studyplanid); if ($studyplan->exist_for_user($userid) && !$studyplan->suspended()) { $model = $studyplan->user_model($userid); return $model; } else { throw new \moodle_exception("You do not have access to this studyplan"); } } /************************ * * * get_own_page * * * ************************/ /** * Parameter description for webservice function get_own_page */ public static function get_own_page_parameters(): \external_function_parameters { return new \external_function_parameters( [ "pageid" => new \external_value(PARAM_INT, 'id of studyplan to retrieve'), ] ); } /** * Return value description for webservice function get_own_page */ public static function get_own_page_returns(): \external_description { return studyplan::user_structure(); } /** * Get studyplanpage for current user * @param int $pageid ID of specific studyplan page * @return array */ public static function get_own_page($pageid) { global $USER; // Validate this call in the system context. \external_api::validate_context(\context_system::instance()); $userid = $USER->id; $page = studyplanpage::find_by_id($pageid); $studyplan = $page->studyplan(); if ($studyplan->exist_for_user($userid && !$studyplan->suspended())) { return $page->user_model($userid); } else { throw new \moodle_exception("You do not have access to this studyplan page"); } } /*************************** * * * list_teaching_studyplans * * * ***************************/ /** * Parameter description for webservice function list_teaching_studyplans */ public static function list_teaching_studyplans_parameters(): \external_function_parameters { return new \external_function_parameters( [] ); } /** * Return value description for webservice function list_teaching_studyplans */ public static function list_teaching_studyplans_returns(): \external_description { return new \external_multiple_structure( studyplan::simple_structure() ); } /** * Get all studyplans the current user is teaching in * @return array */ public static function list_teaching_studyplans() { global $USER; $userid = $USER->id; \external_api::validate_context(\context_system::instance()); $studyplans = teachingfinder::list_my_plans(); $list = []; foreach ($studyplans as $studyplan) { $list[] = $studyplan->simple_model($userid); } return $list; } /*************************** * * * list_coaching_studyplans * * * ***************************/ /** * Parameter description for webservice function list_teaching_studyplans */ public static function list_coaching_studyplans_parameters(): \external_function_parameters { return new \external_function_parameters( [] ); } /** * Return value description for webservice function list_teaching_studyplans */ public static function list_coaching_studyplans_returns(): \external_description { return new \external_multiple_structure( studyplan::simple_structure() ); } /** * Get all studyplans the current user is coaching * @return array */ public static function list_coaching_studyplans() { global $USER, $DB; $userid = $USER->id; \external_api::validate_context(\context_system::instance()); // Return empty list if coach role not enabled. if (! (premium::enabled() && \get_config("local_treestudyplan", "enablecoach"))) { return []; } $records = $DB->get_records("local_treestudyplan_coach", ["user_id" => $userid]); $list = []; foreach ($records as $r) { try { $studyplan = studyplan::find_by_id($r->studyplan_id); if (has_capability(self::CAP_COACH, $studyplan->context(), $USER)) { $list[] = $studyplan->simple_model_coach(); } } catch (\Exception $x) { $studyplan = null; } } return $list; } /*************************** * * * get_teaching_studyplan * * * ***************************/ /** * Parameter description for webservice function get_teaching_studyplan */ public static function get_teaching_studyplan_parameters(): \external_function_parameters { return new \external_function_parameters( [ "studyplanid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide', VALUE_DEFAULT), ] ); } /** * Return value description for webservice function get_teaching_studyplan */ public static function get_teaching_studyplan_returns(): \external_description { return studyplan::editor_structure(); } /** * Get all or one studyplan the current user is teaching in * @param int $studyplanid ID of studyplan to retrieve * @return array */ public static function get_teaching_studyplan($studyplanid) { global $USER; $userid = $USER->id; \external_api::validate_context(\context_system::instance()); $studyplan = studyplan::find_by_id($studyplanid); if (teachingfinder::am_teaching_studyplan($studyplan)) { return $studyplan->editor_model(); } else { throw new \moodle_exception("You are not teaching in this studyplan"); } } /*************************** * * * get_teaching_page * * * ***************************/ /** * Parameter description for webservice function get_teaching_page */ public static function get_teaching_page_parameters(): \external_function_parameters { return new \external_function_parameters( [ "pageid" => new \external_value(PARAM_INT, 'id of specific studyplan page to provide', VALUE_DEFAULT), ] ); } /** * Return value description for webservice function get_teaching_page */ public static function get_teaching_page_returns(): \external_description { return studyplanpage::editor_structure(); } /** * Get one studyplan page if the current user is teaching in it * @param int $pageid ID of studyplan to retrieve * @return array * @throws moodle_exception if current user is not teaching in this studyplan */ public static function get_teaching_page($pageid) { \external_api::validate_context(\context_system::instance()); $page = studyplanpage::find_by_id($pageid); $studyplan = $page->studyplan(); if (teachingfinder::am_teaching_studyplan($studyplan)) { return $page->editor_model(); } else { throw new \moodle_exception("You are not teaching in this studyplan"); } } /*************************** * * * line_enrol_self * * * ***************************/ /** * Parameter description for webservice function get_teaching_page */ public static function line_enrol_self_parameters(): \external_function_parameters { return new \external_function_parameters( [ "id" => new \external_value(PARAM_INT, 'id of specific studyline to enrol into'), ] ); } /** * Return value description for webservice function get_teaching_page */ public static function line_enrol_self_returns(): \external_description { return studyline::enrol_info_structure(); } /** * Get all or one studyplan the current user is teaching in * @param int $id ID of studyplan to retrieve * @return array */ public static function line_enrol_self($id) { global $USER; $userid = $USER->id; $o = studyline::find_by_id($id); if ($o->can_enrol($userid)) { $o->enrol($userid); } // Trigger immediate cohort synchronization for this line only. autocohortsync::syncline($o); return $o->enrol_info_model($userid); } }