. /** * Webservice class for handling studyplan reports * @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(); use local_treestudyplan\local\helpers\webservicehelper; use local_treestudyplan\period; use local_treestudyplan\studyplan; use local_treestudyplan\studyplanpage; require_once($CFG->libdir.'/externallib.php'); /** * Webservice class for handling studyplan reports */ class reportservice extends \external_api { /** * Capability required to view studyplans (for other users) * @var string */ const CAP_VIEW = "local/treestudyplan:viewuserreports"; /** * Parameter description for webservice function */ public static function get_report_structure_parameters(): \external_function_parameters { return new \external_function_parameters([ "pageid" => new \external_value(PARAM_INT, 'id of studyplan page'), "firstperiod" => new \external_value(PARAM_INT, 'first period to include in report', VALUE_DEFAULT), "lastperiod" => new \external_value(PARAM_INT, 'last period to include in report', VALUE_DEFAULT), ]); } /** * Return value description for webservice function list_user_studyplans */ public static function get_report_structure_returns(): \external_description { return new \external_single_structure([ "periods" => new \external_multiple_structure(new \external_single_structure([ "period" => period::structure(), "lines" => new \external_multiple_structure(new \external_single_structure([ "line" => studyline::simple_structure(), "items" => new \external_multiple_structure(studyitem::editor_structure(), "Information per studyitem"), ])), ])), "firstperiod" => new \external_value(PARAM_INT, 'first period included in report'), "lastperiod" => new \external_value(PARAM_INT, 'last period included in report'), "studyplan" => studyplan::simple_structure(), "page" => studyplanpage::simple_structure(), ]); } /** * Get studyplan page structure for a report * @param int $pageid ID of user to check specific info for * @param int|null $firstperiod First period to include in report * @param int|null $lastperiod Last period to include in report * @return object */ public static function get_report_structure($pageid, $firstperiod=null, $lastperiod=null) { $page = studyplanpage::find_by_id($pageid); webservicehelper::require_capabilities(self::CAP_VIEW, $page->studyplan()->context()); $plan = $page->studyplan(); if (empty($firstperiod)) { $firstperiod = 1; } if (empty($lastperiod)) { // Index for periods starts at 1, so the period count is same as length. $lastperiod = $page->periods(); } $model = [ "studyplan" => $plan->simple_model(), "page" => $page->simple_model(), "firstperiod" => $firstperiod, "lastperiod" => $lastperiod, "periods" => [], ]; // Find all relevant parts in this order. for ($i = $firstperiod; $i <= $lastperiod; $i++) { $period = period::find($page, $i); $pmodel = [ 'period' => $period->model(), 'lines' => [], ]; $lines = studyline::find_page_children($page); foreach ($lines as $line) { $lmodel = [ "line" => $line->simple_model(), "items" => [], ]; $items = studyitem::search_studyline_children($line, $i, studyitem::COURSE); if (count($items) > 0) { foreach ($items as $item) { $lmodel["items"][] = $item->editor_model(); } // Only include the line if it has actual children - saves us from muddying up the report. $pmodel['lines'][] = $lmodel; } } $model["periods"][] = $pmodel; } return $model; } /** * Parameter description for webservice function */ public static function get_report_data_parameters(): \external_function_parameters { return new \external_function_parameters([ "pageid" => new \external_value(PARAM_INT, 'id of studyplan page'), "userid" => new \external_value(PARAM_INT, 'id of user'), "firstperiod" => new \external_value(PARAM_INT, 'first period to include in report', VALUE_DEFAULT), "lastperiod" => new \external_value(PARAM_INT, 'last period to include in report', VALUE_DEFAULT), ]); } /** * Return value description for webservice function list_user_studyplans */ public static function get_report_data_returns(): \external_description { return new \external_multiple_structure(studyitem::user_structure(), "Information per studyitem"); } /** * Webservice function get_report data * @param int $pageid Id of the studyplan page to build the report for * @param int $userid ID ofthe user to gather the report for * @param int|null $firstperiod First period of the page to include in the report (first of page if left empty) * @param int|null $lastperiod Last period of the page to include in the report (last of page if left empty) */ public static function get_report_data($pageid, $userid, $firstperiod=null, $lastperiod=null) { $page = studyplanpage::find_by_id($pageid); webservicehelper::require_capabilities(self::CAP_VIEW, $page->studyplan()->context()); $plan = $page->studyplan(); if (!$plan->has_linked_user($userid)) { throw new \moodle_exception("error:usernotassociated", "local_treestudyplan"); } if (empty($firstperiod)) { $firstperiod = 1; } if (empty($lastperiod)) { // Index for periods starts at 1, so the period count is same as length. $lastperiod = $page->periods(); } $model = []; for ($i = $firstperiod; $i <= $lastperiod; $i++) { $lines = studyline::find_page_children($page); foreach ($lines as $line) { $items = studyitem::search_studyline_children($line, $i, studyitem::COURSE); if (count($items) > 0) { foreach ($items as $item) { $model[] = $item->user_model($userid); } } } } return $model; } /** * Parameter description for webservice function */ public static function get_report_details_parameters(): \external_function_parameters { return new \external_function_parameters([ "itemid" => new \external_value(PARAM_INT, 'id of studyitem'), "userid" => new \external_value(PARAM_INT, 'id of user'), ]); } /** * Return value description for webservice function list_user_studyplans */ public static function get_report_details_returns(): \external_description { return studyitem::user_structure(); } /** * Get study item details for a user * @param int $itemid ID of study item * @param int $userid ID of user to check specific info for * @return array */ public static function get_report_details($itemid, $userid) { $item = studyitem::find_by_id($itemid); $plan = $item->studyline()->studyplan(); webservicehelper::require_capabilities(self::CAP_VIEW, $plan->context()); if (!$plan->has_linked_user($userid)) { throw new \moodle_exception("error:usernotassociated", "local_treestudyplan"); } return $item->user_model($userid); } }