diff --git a/mod/workshop/classes/external.php b/mod/workshop/classes/external.php index caaf27d88c1..52fe32af5c1 100644 --- a/mod/workshop/classes/external.php +++ b/mod/workshop/classes/external.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die; require_once("$CFG->libdir/externallib.php"); +require_once($CFG->dirroot . '/mod/workshop/locallib.php'); use mod_workshop\external\workshop_summary_exporter; @@ -126,4 +127,108 @@ class mod_workshop_external extends external_api { ) ); } + + /** + * Utility function for validating a workshop. + * + * @param int $workshopid workshop instance id + * @return array array containing the workshop object, course, context and course module objects + * @since Moodle 3.4 + */ + protected static function validate_workshop($workshopid) { + global $DB, $USER; + + // Request and permission validation. + $workshop = $DB->get_record('workshop', array('id' => $workshopid), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($workshop, 'workshop'); + + $context = context_module::instance($cm->id); + self::validate_context($context); + + $workshop = new workshop($workshop, $cm, $course); + + return array($workshop, $course, $cm, $context); + } + + + /** + * Describes the parameters for get_workshop_access_information. + * + * @return external_external_function_parameters + * @since Moodle 3.4 + */ + public static function get_workshop_access_information_parameters() { + return new external_function_parameters ( + array( + 'workshopid' => new external_value(PARAM_INT, 'Workshop instance id.') + ) + ); + } + + /** + * Return access information for a given workshop. + * + * @param int $workshopid workshop instance id + * @return array of warnings and the access information + * @since Moodle 3.4 + * @throws moodle_exception + */ + public static function get_workshop_access_information($workshopid) { + global $USER; + + $params = self::validate_parameters(self::get_workshop_access_information_parameters(), array('workshopid' => $workshopid)); + + list($workshop, $course, $cm, $context) = self::validate_workshop($params['workshopid']); + + $result = array(); + // Return all the available capabilities. + $capabilities = load_capability_def('mod_workshop'); + foreach ($capabilities as $capname => $capdata) { + // Get fields like cansubmit so it is consistent with the access_information function implemented in other modules. + $field = 'can' . str_replace('mod/workshop:', '', $capname); + $result[$field] = has_capability($capname, $context); + } + + // Now, specific features access information. + $result['creatingsubmissionallowed'] = $workshop->creating_submission_allowed($USER->id); + $result['modifyingsubmissionallowed'] = $workshop->modifying_submission_allowed($USER->id); + $result['assessingallowed'] = $workshop->assessing_allowed($USER->id); + $result['assessingexamplesallowed'] = $workshop->assessing_examples_allowed(); + if (is_null($result['assessingexamplesallowed'])) { + $result['assessingexamplesallowed'] = false; + } + + $result['warnings'] = array(); + return $result; + } + + /** + * Describes the get_workshop_access_information return value. + * + * @return external_single_structure + * @since Moodle 3.4 + */ + public static function get_workshop_access_information_returns() { + + $structure = array( + 'creatingsubmissionallowed' => new external_value(PARAM_BOOL, + 'Is the given user allowed to create their submission?'), + 'modifyingsubmissionallowed' => new external_value(PARAM_BOOL, + 'Is the user allowed to modify his existing submission?'), + 'assessingallowed' => new external_value(PARAM_BOOL, + 'Is the user allowed to create/edit his assessments?'), + 'assessingexamplesallowed' => new external_value(PARAM_BOOL, + 'Are reviewers allowed to create/edit their assessments of the example submissions?.'), + 'warnings' => new external_warnings() + ); + + $capabilities = load_capability_def('mod_workshop'); + foreach ($capabilities as $capname => $capdata) { + // Get fields like cansubmit so it is consistent with the access_information function implemented in other modules. + $field = 'can' . str_replace('mod/workshop:', '', $capname); + $structure[$field] = new external_value(PARAM_BOOL, 'Whether the user has the capability ' . $capname . ' allowed.'); + } + + return new external_single_structure($structure); + } } diff --git a/mod/workshop/db/services.php b/mod/workshop/db/services.php index e44e7cb7c95..0da25d271be 100644 --- a/mod/workshop/db/services.php +++ b/mod/workshop/db/services.php @@ -37,4 +37,12 @@ $functions = array( 'capabilities' => 'mod/workshop:view', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'mod_workshop_get_workshop_access_information' => array( + 'classname' => 'mod_workshop_external', + 'methodname' => 'get_workshop_access_information', + 'description' => 'Return access information for a given workshop.', + 'type' => 'read', + 'capabilities' => 'mod/workshop:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + ), ); diff --git a/mod/workshop/tests/external_test.php b/mod/workshop/tests/external_test.php index 63e8fd0d66a..0156a3e0b7d 100644 --- a/mod/workshop/tests/external_test.php +++ b/mod/workshop/tests/external_test.php @@ -180,4 +180,104 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase { $this->assertEquals('1', $result['warnings'][0]['warningcode']); $this->assertEquals($course2->id, $result['warnings'][0]['itemid']); } + + /** + * Test mod_workshop_get_workshop_access_information for students. + */ + public function test_mod_workshop_get_workshop_access_information_student() { + + self::setUser($this->student); + $result = mod_workshop_external::get_workshop_access_information($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result); + // Check default values for capabilities. + $enabledcaps = array('canpeerassess', 'cansubmit', 'canview', 'canviewauthornames', 'canviewauthorpublished', + 'canviewpublishedsubmissions', 'canexportsubmissions'); + + foreach ($result as $capname => $capvalue) { + if (strpos($capname, 'can') !== 0) { + continue; + } + if (in_array($capname, $enabledcaps)) { + $this->assertTrue($capvalue); + } else { + $this->assertFalse($capvalue); + } + } + // Now, unassign some capabilities. + unassign_capability('mod/workshop:peerassess', $this->studentrole->id); + unassign_capability('mod/workshop:submit', $this->studentrole->id); + unset($enabledcaps[0]); + unset($enabledcaps[1]); + accesslib_clear_all_caches_for_unit_testing(); + + $result = mod_workshop_external::get_workshop_access_information($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result); + foreach ($result as $capname => $capvalue) { + if (strpos($capname, 'can') !== 0) { + continue; + } + if (in_array($capname, $enabledcaps)) { + $this->assertTrue($capvalue); + } else { + $this->assertFalse($capvalue); + } + } + + // Now, specific functionalities. + $this->assertFalse($result['creatingsubmissionallowed']); + $this->assertFalse($result['modifyingsubmissionallowed']); + $this->assertFalse($result['assessingallowed']); + $this->assertFalse($result['assessingexamplesallowed']); + + // Switch phase. + $workshop = new workshop($this->workshop, $this->cm, $this->course); + $workshop->switch_phase(workshop::PHASE_SUBMISSION); + $result = mod_workshop_external::get_workshop_access_information($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result); + + $this->assertTrue($result['creatingsubmissionallowed']); + $this->assertTrue($result['modifyingsubmissionallowed']); + $this->assertFalse($result['assessingallowed']); + $this->assertFalse($result['assessingexamplesallowed']); + + // Switch to next (to assessment). + $workshop = new workshop($this->workshop, $this->cm, $this->course); + $workshop->switch_phase(workshop::PHASE_ASSESSMENT); + $result = mod_workshop_external::get_workshop_access_information($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result); + + $this->assertFalse($result['creatingsubmissionallowed']); + $this->assertFalse($result['modifyingsubmissionallowed']); + $this->assertTrue($result['assessingallowed']); + $this->assertFalse($result['assessingexamplesallowed']); + } + + /** + * Test mod_workshop_get_workshop_access_information for teachers. + */ + public function test_mod_workshop_get_workshop_access_information_teacher() { + + self::setUser($this->teacher); + $result = mod_workshop_external::get_workshop_access_information($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result); + // Check default values. + $disabledcaps = array('canpeerassess', 'cansubmit'); + + foreach ($result as $capname => $capvalue) { + if (strpos($capname, 'can') !== 0) { + continue; + } + if (in_array($capname, $disabledcaps)) { + $this->assertFalse($capvalue); + } else { + $this->assertTrue($capvalue); + } + } + + // Now, specific functionalities. + $this->assertFalse($result['creatingsubmissionallowed']); + $this->assertFalse($result['modifyingsubmissionallowed']); + $this->assertFalse($result['assessingallowed']); + $this->assertFalse($result['assessingexamplesallowed']); + } } diff --git a/mod/workshop/version.php b/mod/workshop/version.php index b35c6fdf53c..1de474ef1d2 100644 --- a/mod/workshop/version.php +++ b/mod/workshop/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2017051501; // The current module version (YYYYMMDDXX) +$plugin->version = 2017051502; // The current module version (YYYYMMDDXX) $plugin->requires = 2017050500; // Requires this Moodle version. $plugin->component = 'mod_workshop'; $plugin->cron = 60; // Give as a chance every minute.