Skip to content

Commit

Permalink
MDL-66489 enrol: Send all form data to WS and do all busines logic there
Browse files Browse the repository at this point in the history
It is discouraged to use JS Date functions. We should pass all raw data to PHP.
  • Loading branch information
rezaies committed Sep 11, 2019
1 parent 310d690 commit 2d4ce64
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 45 deletions.
79 changes: 79 additions & 0 deletions enrol/externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ public static function get_course_enrolment_methods_returns() {
/**
* Returns description of edit_user_enrolment() parameters
*
* @deprecated since 3.8
* @return external_function_parameters
*/
public static function edit_user_enrolment_parameters() {
Expand All @@ -936,6 +937,7 @@ public static function edit_user_enrolment_parameters() {
/**
* External function that updates a given user enrolment.
*
* @deprecated since 3.8
* @param int $courseid The course ID.
* @param int $ueid The user enrolment ID.
* @param int $status The enrolment status.
Expand Down Expand Up @@ -1002,6 +1004,7 @@ public static function edit_user_enrolment($courseid, $ueid, $status, $timestart
/**
* Returns description of edit_user_enrolment() result value
*
* @deprecated since 3.8
* @return external_description
*/
public static function edit_user_enrolment_returns() {
Expand All @@ -1020,6 +1023,82 @@ public static function edit_user_enrolment_returns() {
);
}

/**
* Mark the edit_user_enrolment web service as deprecated.
*
* @return bool
*/
public static function edit_user_enrolment_is_deprecated() {
return true;
}

/**
* Returns description of submit_user_enrolment_form parameters.
*
* @return external_function_parameters.
*/
public static function submit_user_enrolment_form_parameters() {
return new external_function_parameters([
'formdata' => new external_value(PARAM_RAW, 'The data from the event form'),
]);
}

/**
* External function that handles the user enrolment form submission.
*
* @param string $formdata The user enrolment form data in s URI encoded param string
* @return array An array consisting of the processing result and error flag, if available
*/
public static function submit_user_enrolment_form($formdata) {
global $CFG, $DB, $PAGE;

// Parameter validation.
$params = self::validate_parameters(self::submit_user_enrolment_form_parameters(), ['formdata' => $formdata]);

$data = [];
parse_str($params['formdata'], $data);

$userenrolment = $DB->get_record('user_enrolments', ['id' => $data['ue']], '*', MUST_EXIST);
$instance = $DB->get_record('enrol', ['id' => $userenrolment->enrolid], '*', MUST_EXIST);
$plugin = enrol_get_plugin($instance->enrol);
$course = get_course($instance->courseid);
$context = context_course::instance($course->id);
self::validate_context($context);

require_once("$CFG->dirroot/enrol/editenrolment_form.php");
$customformdata = [
'ue' => $userenrolment,
'modal' => true,
'enrolinstancename' => $plugin->get_instance_name($instance)
];
$mform = new enrol_user_enrolment_form(null, $customformdata, 'post', '', null, true, $data);

if ($validateddata = $mform->get_data()) {
if (!empty($validateddata->duration) && $validateddata->timeend == 0) {
$validateddata->timeend = $validateddata->timestart + $validateddata->duration;
}
require_once($CFG->dirroot . '/enrol/locallib.php');
$manager = new course_enrolment_manager($PAGE, $course);
$result = $manager->edit_enrolment($userenrolment, $validateddata);

return ['result' => $result];
} else {
return ['result' => false, 'validationerror' => true];
}
}

/**
* Returns description of submit_user_enrolment_form() result value
*
* @return external_description
*/
public static function submit_user_enrolment_form_returns() {
return new external_single_structure([
'result' => new external_value(PARAM_BOOL, 'True if the user\'s enrolment was successfully updated'),
'validationerror' => new external_value(PARAM_BOOL, 'Indicates invalid form data', VALUE_DEFAULT, false),
]);
}

/**
* Returns description of unenrol_user_enrolment() parameters
*
Expand Down
149 changes: 149 additions & 0 deletions enrol/tests/externallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,155 @@ public function test_edit_user_enrolment() {
$this->assertEquals(ENROL_USER_SUSPENDED, $ue->status);
}

/**
* dataProvider for test_submit_user_enrolment_form().
*/
public function submit_user_enrolment_form_provider() {
$now = new DateTime();

$nextmonth = clone($now);
$nextmonth->add(new DateInterval('P1M'));

return [
'Invalid data' => [
'customdata' => [
'status' => ENROL_USER_ACTIVE,
'timestart' => [
'day' => $now->format('j'),
'month' => $now->format('n'),
'year' => $now->format('Y'),
'hour' => $now->format('G'),
'minute' => 0,
'enabled' => 1,
],
'timeend' => [
'day' => $now->format('j'),
'month' => $now->format('n'),
'year' => $now->format('Y'),
'hour' => $now->format('G'),
'minute' => 0,
'enabled' => 1,
],
],
'expectedresult' => false,
'validationerror' => true,
],
'Valid data' => [
'customdata' => [
'status' => ENROL_USER_ACTIVE,
'timestart' => [
'day' => $now->format('j'),
'month' => $now->format('n'),
'year' => $now->format('Y'),
'hour' => $now->format('G'),
'minute' => 0,
'enabled' => 1,
],
'timeend' => [
'day' => $nextmonth->format('j'),
'month' => $nextmonth->format('n'),
'year' => $nextmonth->format('Y'),
'hour' => $nextmonth->format('G'),
'minute' => 0,
'enabled' => 1,
],
],
'expectedresult' => true,
'validationerror' => false
],
'Suspend user' => [
'customdata' => [
'status' => ENROL_USER_SUSPENDED,
],
'expectedresult' => true,
'validationerror' => false
],
];
}

/**
* @param array $customdata The data we are providing to the webservice.
* @param bool $expectedresult The result we are expecting to receive from the webservice.
* @param bool $validationerror The validationerror we are expecting to receive from the webservice.
* @dataProvider submit_user_enrolment_form_provider
*/
public function test_submit_user_enrolment_form($customdata, $expectedresult, $validationerror) {
global $CFG, $DB;

$this->resetAfterTest(true);
$datagen = $this->getDataGenerator();

/** @var enrol_manual_plugin $manualplugin */
$manualplugin = enrol_get_plugin('manual');

$studentroleid = $DB->get_field('role', 'id', ['shortname' => 'student'], MUST_EXIST);
$teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher'], MUST_EXIST);
$course = $datagen->create_course();
$user = $datagen->create_user();
$teacher = $datagen->create_user();

$instanceid = null;
$instances = enrol_get_instances($course->id, true);
foreach ($instances as $inst) {
if ($inst->enrol == 'manual') {
$instanceid = (int)$inst->id;
break;
}
}
if (empty($instanceid)) {
$instanceid = $manualplugin->add_default_instance($course);
if (empty($instanceid)) {
$instanceid = $manualplugin->add_instance($course);
}
}
$this->assertNotNull($instanceid);

$instance = $DB->get_record('enrol', ['id' => $instanceid], '*', MUST_EXIST);
$manualplugin->enrol_user($instance, $user->id, $studentroleid, 0, 0, ENROL_USER_ACTIVE);
$manualplugin->enrol_user($instance, $teacher->id, $teacherroleid, 0, 0, ENROL_USER_ACTIVE);
$ueid = (int) $DB->get_field(
'user_enrolments',
'id',
['enrolid' => $instance->id, 'userid' => $user->id],
MUST_EXIST
);

// Login as teacher.
$teacher->ignoresesskey = true;
$this->setUser($teacher);

$formdata = [
'ue' => $ueid,
'ifilter' => 0,
'status' => null,
'timestart' => null,
'duration' => null,
'timeend' => null,
];

$formdata = array_merge($formdata, $customdata);

require_once("$CFG->dirroot/enrol/editenrolment_form.php");
$formdata = enrol_user_enrolment_form::mock_generate_submit_keys($formdata);

$querystring = http_build_query($formdata, '', '&');

$result = external_api::clean_returnvalue(
core_enrol_external::submit_user_enrolment_form_returns(),
core_enrol_external::submit_user_enrolment_form($querystring)
);

$this->assertEquals(
['result' => $expectedresult, 'validationerror' => $validationerror],
$result,
'', 0.0, 10, true);

if ($result['result']) {
$ue = $DB->get_record('user_enrolments', ['id' => $ueid], '*', MUST_EXIST);
$this->assertEquals($formdata['status'], $ue->status);
}
}

/**
* Test for core_enrol_external::unenrol_user_enrolment().
*/
Expand Down
11 changes: 10 additions & 1 deletion lib/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,16 @@
'classname' => 'core_enrol_external',
'methodname' => 'edit_user_enrolment',
'classpath' => 'enrol/externallib.php',
'description' => 'External function that updates a given user enrolment',
'description' => '** DEPRECATED ** Please do not call this function any more.
External function that updates a given user enrolment',
'type' => 'write',
'ajax' => true,
),
'core_enrol_submit_user_enrolment_form' => array(
'classname' => 'core_enrol_external',
'methodname' => 'submit_user_enrolment_form',
'classpath' => 'enrol/externallib.php',
'description' => 'Submit form data for enrolment form',
'type' => 'write',
'ajax' => true,
),
Expand Down
1 change: 1 addition & 0 deletions lib/upgrade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ validation against and defaults to null (so, no user needed) if not provided.
* Following behat steps have been removed from core:
- I go to "<gradepath_string>" in the course gradebook
* A new admin setting widget 'core_admin\local\settings\filesize' is added.
* The core_enrol_edit_user_enrolment webservice has been deprecated. Please use core_enrol_submit_user_enrolment_form instead.

=== 3.7 ===

Expand Down
2 changes: 1 addition & 1 deletion user/amd/build/status_field.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion user/amd/build/status_field.min.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit 2d4ce64

Please sign in to comment.