return new external_single_structure($structure);
}
+
+ /**
+ * Describes the parameters for get_user_plan.
+ *
+ * @return external_external_function_parameters
+ * @since Moodle 3.4
+ */
+ public static function get_user_plan_parameters() {
+ return new external_function_parameters (
+ array(
+ 'workshopid' => new external_value(PARAM_INT, 'Workshop instance id.'),
+ 'userid' => new external_value(PARAM_INT, 'User id (empty or 0 for current user).', VALUE_DEFAULT, 0),
+ )
+ );
+ }
+
+ /**
+ * Return the planner information for the given user.
+ *
+ * @param int $workshopid workshop instance id
+ * @param int $userid user id
+ * @return array of warnings and the user plan
+ * @since Moodle 3.4
+ * @throws moodle_exception
+ */
+ public static function get_user_plan($workshopid, $userid = 0) {
+ global $USER;
+
+ $params = array(
+ 'workshopid' => $workshopid,
+ 'userid' => $userid,
+ );
+ $params = self::validate_parameters(self::get_user_plan_parameters(), $params);
+
+ list($workshop, $course, $cm, $context) = self::validate_workshop($params['workshopid']);
+
+ // Extra checks so only users with permissions can view other users plans.
+ if (empty($params['userid']) || $params['userid'] == $USER->id) {
+ $userid = $USER->id;
+ } else {
+ require_capability('moodle/course:manageactivities', $context);
+ $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
+ core_user::require_active_user($user);
+ if (!$workshop->check_group_membership($user->id)) {
+ throw new moodle_exception('notingroup');
+ }
+ $userid = $user->id;
+ }
+
+ // Get the user plan information ready for external functions.
+ $userplan = new workshop_user_plan($workshop, $userid);
+ $userplan = array('phases' => $userplan->phases, 'examples' => $userplan->get_examples());
+ foreach ($userplan['phases'] as $phasecode => $phase) {
+ $phase->code = $phasecode;
+ $userplan['phases'][$phasecode] = (array) $phase;
+ foreach ($userplan['phases'][$phasecode]['tasks'] as $taskcode => $task) {
+ $task->code = $taskcode;
+ if ($task->link instanceof moodle_url) {
+ $task->link = $task->link->out(false);
+ }
+ $userplan['phases'][$phasecode]['tasks'][$taskcode] = (array) $task;
+ }
+ foreach ($userplan['phases'][$phasecode]['actions'] as $actioncode => $action) {
+ if ($action->url instanceof moodle_url) {
+ $action->url = $action->url->out(false);
+ }
+ $userplan['phases'][$phasecode]['actions'][$actioncode] = (array) $action;
+ }
+ }
+
+ $result['userplan'] = $userplan;
+ $result['warnings'] = array();
+ return $result;
+ }
+
+ /**
+ * Describes the get_user_plan return value.
+ *
+ * @return external_single_structure
+ * @since Moodle 3.4
+ */
+ public static function get_user_plan_returns() {
+ return new external_single_structure(
+ array(
+ 'userplan' => new external_single_structure(
+ array(
+ 'phases' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'code' => new external_value(PARAM_INT, 'Phase code.'),
+ 'title' => new external_value(PARAM_NOTAGS, 'Phase title.'),
+ 'active' => new external_value(PARAM_BOOL, 'Whether is the active task.'),
+ 'tasks' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'code' => new external_value(PARAM_ALPHA, 'Task code.'),
+ 'title' => new external_value(PARAM_RAW, 'Task title.'),
+ 'link' => new external_value(PARAM_URL, 'Link to task.'),
+ 'details' => new external_value(PARAM_RAW, 'Task details.', VALUE_OPTIONAL),
+ 'completed' => new external_value(PARAM_NOTAGS,
+ 'Completion information (maybe empty, maybe a boolean or generic info.'),
+ )
+ )
+ ),
+ 'actions' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'type' => new external_value(PARAM_ALPHA, 'Action type.', VALUE_OPTIONAL),
+ 'label' => new external_value(PARAM_RAW, 'Action label.', VALUE_OPTIONAL),
+ 'url' => new external_value(PARAM_URL, 'Link to action.'),
+ 'method' => new external_value(PARAM_ALPHA, 'Get or post.', VALUE_OPTIONAL),
+ )
+ )
+ ),
+ )
+ )
+ ),
+ 'examples' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'Example submission id.'),
+ 'title' => new external_value(PARAM_RAW, 'Example submission title.'),
+ 'assessmentid' => new external_value(PARAM_INT, 'Example submission assessment id.'),
+ 'grade' => new external_value(PARAM_FLOAT, 'The submission grade.'),
+ 'gradinggrade' => new external_value(PARAM_FLOAT, 'The assessment grade.'),
+ )
+ )
+ ),
+ )
+ ),
+ 'warnings' => new external_warnings(),
+ )
+ );
+ }
}
$this->assertFalse($result['assessingallowed']);
$this->assertFalse($result['assessingexamplesallowed']);
}
+
+ /**
+ * Test mod_workshop_get_user_plan for students.
+ */
+ public function test_mod_workshop_get_user_plan_student() {
+
+ self::setUser($this->student);
+ $result = mod_workshop_external::get_user_plan($this->workshop->id);
+ $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
+
+ $this->assertCount(0, $result['userplan']['examples']); // No examples given.
+ $this->assertCount(5, $result['userplan']['phases']); // Always 5 phases.
+ $this->assertEquals(workshop::PHASE_SETUP, $result['userplan']['phases'][0]['code']); // First phase always setup.
+ $this->assertTrue($result['userplan']['phases'][0]['active']); // First phase "Setup" active in new workshops.
+
+ // Switch phase.
+ $workshop = new workshop($this->workshop, $this->cm, $this->course);
+ $workshop->switch_phase(workshop::PHASE_SUBMISSION);
+
+ $result = mod_workshop_external::get_user_plan($this->workshop->id);
+ $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
+
+ $this->assertEquals(workshop::PHASE_SUBMISSION, $result['userplan']['phases'][1]['code']);
+ $this->assertTrue($result['userplan']['phases'][1]['active']); // We are now in submission phase.
+ }
+
+ /**
+ * Test mod_workshop_get_user_plan for teachers.
+ */
+ public function test_mod_workshop_get_user_plan_teacher() {
+ global $DB;
+
+ self::setUser($this->teacher);
+ $result = mod_workshop_external::get_user_plan($this->workshop->id);
+ $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
+
+ $this->assertCount(0, $result['userplan']['examples']); // No examples given.
+ $this->assertCount(5, $result['userplan']['phases']); // Always 5 phases.
+ $this->assertEquals(workshop::PHASE_SETUP, $result['userplan']['phases'][0]['code']); // First phase always setup.
+ $this->assertTrue($result['userplan']['phases'][0]['active']); // First phase "Setup" active in new workshops.
+ $this->assertCount(4, $result['userplan']['phases'][0]['tasks']); // For new empty workshops, always 4 tasks.
+
+ foreach ($result['userplan']['phases'][0]['tasks'] as $task) {
+ if ($task['code'] == 'intro' || $task['code'] == 'instructauthors') {
+ $this->assertEquals(1, $task['completed']);
+ } else {
+ $this->assertEmpty($task['completed']);
+ }
+ }
+
+ // Do some of the tasks asked - switch phase.
+ $workshop = new workshop($this->workshop, $this->cm, $this->course);
+ $workshop->switch_phase(workshop::PHASE_SUBMISSION);
+
+ $result = mod_workshop_external::get_user_plan($this->workshop->id);
+ $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
+ foreach ($result['userplan']['phases'][0]['tasks'] as $task) {
+ if ($task['code'] == 'intro' || $task['code'] == 'instructauthors' || $task['code'] == 'switchtonextphase') {
+ $this->assertEquals(1, $task['completed']);
+ } else {
+ $this->assertEmpty($task['completed']);
+ }
+ }
+
+ $result = mod_workshop_external::get_user_plan($this->workshop->id);
+ $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
+
+ $this->assertEquals(workshop::PHASE_SUBMISSION, $result['userplan']['phases'][1]['code']);
+ $this->assertTrue($result['userplan']['phases'][1]['active']); // We are now in submission phase.
+ }
}