MDL-84142 enrol_guest: use new template for the self enrolment widget

This commit is contained in:
Marina Glancy
2025-03-13 13:06:39 +00:00
parent 7c196005c7
commit 58a1667f92
9 changed files with 303 additions and 44 deletions
@@ -0,0 +1,7 @@
issueNumber: MDL-84142
notes:
enrol_guest:
- message: >-
Class enrol_guest_enrol_form is deprecated, use
enrol_guest\form\enrol_form instead
type: deprecated
+10
View File
@@ -0,0 +1,10 @@
define("enrol_guest/enrol_page",["exports","core_form/modalform","core/str","core/prefetch","core/url"],(function(_exports,_modalform,_str,_prefetch,_url){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Functions for the enrol_guest plugin
*
* @module enrol_guest/enrol_page
* @copyright Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.initEnrol=function(instanceId){(0,_prefetch.prefetchStrings)("moodle",["loginguest"]);const button=document.querySelector('button[type="submit"][data-instance="'+instanceId+'"]');button&&button.addEventListener("click",(e=>{e.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:button.dataset.title,large:!1},formClass:button.dataset.form,args:{id:button.dataset.id,instance:instanceId},saveButtonText:(0,_str.getString)("loginguest","moodle"),returnFocus:button});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{window.location.href=event.detail?event.detail:_url.default.relativeUrl("/course/view.php",{id:button.dataset.id})})),modalForm.show()}))},_modalform=_interopRequireDefault(_modalform),_url=_interopRequireDefault(_url)}));
//# sourceMappingURL=enrol_page.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"enrol_page.min.js","sources":["../src/enrol_page.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Functions for the enrol_guest plugin\n *\n * @module enrol_guest/enrol_page\n * @copyright Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport {getString} from 'core/str';\nimport {prefetchStrings} from 'core/prefetch';\nimport Url from 'core/url';\n\n/**\n * Initialise widget on the course enrolment page - clicking on the button should submit the form\n *\n * @param {Number} instanceId\n */\nexport function initEnrol(instanceId) {\n prefetchStrings('moodle', [\n 'loginguest',\n ]);\n\n const button = document.querySelector('button[type=\"submit\"][data-instance=\"' + instanceId + '\"]');\n if (button) {\n button.addEventListener('click', (e) => {\n e.preventDefault();\n const modalForm = new ModalForm({\n modalConfig: {\n title: button.dataset.title,\n large: false, // This is a very small form that does not need a large popup.\n },\n formClass: button.dataset.form,\n args: {id: button.dataset.id, instance: instanceId},\n saveButtonText: getString('loginguest', 'moodle'),\n returnFocus: button,\n });\n\n // Redirect to the course page when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n window.location.href = event.detail ? event.detail :\n Url.relativeUrl('/course/view.php', {id: button.dataset.id});\n });\n\n modalForm.show();\n });\n }\n}\n"],"names":["instanceId","button","document","querySelector","addEventListener","e","preventDefault","modalForm","ModalForm","modalConfig","title","dataset","large","formClass","form","args","id","instance","saveButtonText","returnFocus","events","FORM_SUBMITTED","event","window","location","href","detail","Url","relativeUrl","show"],"mappings":";;;;;;;yFAiC0BA,0CACN,SAAU,CACtB,qBAGEC,OAASC,SAASC,cAAc,wCAA0CH,WAAa,MACzFC,QACAA,OAAOG,iBAAiB,SAAUC,IAC9BA,EAAEC,uBACIC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,MAAOT,OAAOU,QAAQD,MACtBE,OAAO,GAEXC,UAAWZ,OAAOU,QAAQG,KAC1BC,KAAM,CAACC,GAAIf,OAAOU,QAAQK,GAAIC,SAAUjB,YACxCkB,gBAAgB,kBAAU,aAAc,UACxCC,YAAalB,SAIjBM,UAAUH,iBAAiBG,UAAUa,OAAOC,gBAAgBC,QACxDC,OAAOC,SAASC,KAAOH,MAAMI,OAASJ,MAAMI,OACxCC,aAAIC,YAAY,mBAAoB,CAACZ,GAAIf,OAAOU,QAAQK,QAGhET,UAAUsB"}
+63
View File
@@ -0,0 +1,63 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Functions for the enrol_guest plugin
*
* @module enrol_guest/enrol_page
* @copyright Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
import {getString} from 'core/str';
import {prefetchStrings} from 'core/prefetch';
import Url from 'core/url';
/**
* Initialise widget on the course enrolment page - clicking on the button should submit the form
*
* @param {Number} instanceId
*/
export function initEnrol(instanceId) {
prefetchStrings('moodle', [
'loginguest',
]);
const button = document.querySelector('button[type="submit"][data-instance="' + instanceId + '"]');
if (button) {
button.addEventListener('click', (e) => {
e.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: button.dataset.title,
large: false, // This is a very small form that does not need a large popup.
},
formClass: button.dataset.form,
args: {id: button.dataset.id, instance: instanceId},
saveButtonText: getString('loginguest', 'moodle'),
returnFocus: button,
});
// Redirect to the course page when the form is submitted.
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {
window.location.href = event.detail ? event.detail :
Url.relativeUrl('/course/view.php', {id: button.dataset.id});
});
modalForm.show();
});
}
}
+150
View File
@@ -0,0 +1,150 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace enrol_guest\form;
use core\context\course as context_course;
use core_form\dynamic_form;
use core_text;
use moodle_url;
/**
* Form for entering password for guest enrolment
*
* @package enrol_guest
* @copyright Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class enrol_form extends dynamic_form {
/** @var \stdClass */
protected $instance;
/**
* Returns the instance of the enrolment method
*
* @throws \moodle_exception
* @return \stdClass
*/
protected function get_instance(): \stdClass {
global $DB, $CFG;
require_once($CFG->dirroot . '/lib/enrollib.php');
if ($this->instance === null) {
$courseid = $this->optional_param('id', 0, PARAM_INT);
$instanceid = $this->optional_param('instance', 0, PARAM_INT);
// We need enrol_get_instances() to validate that the enrolment method is enabled.
$instances = enrol_get_instances($courseid, true);
if (empty($instances[$instanceid]) || $instances[$instanceid]->enrol !== 'guest') {
throw new \moodle_exception('invalidenrolinstance', 'enrol');
}
$this->instance = $instances[$instanceid] ?? null;
}
return $this->instance;
}
#[\Override]
public function definition() {
$mform = $this->_form;
$mform->addElement('password', 'guestpassword', get_string('password', 'enrol_guest'));
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'instance');
$mform->setType('instance', PARAM_INT);
}
#[\Override]
public function validation($data, $files) {
global $DB, $CFG;
$errors = parent::validation($data, $files);
$instance = $this->get_instance();
if ($instance->password !== '') {
if ($data['guestpassword'] !== $instance->password) {
$plugin = enrol_get_plugin('guest');
if ($plugin->get_config('showhint')) {
$hint = core_text::substr($instance->password, 0, 1);
$errors['guestpassword'] = get_string('passwordinvalidhint', 'enrol_guest', $hint);
} else {
$errors['guestpassword'] = get_string('passwordinvalid', 'enrol_guest');
}
}
}
return $errors;
}
#[\Override]
protected function check_access_for_dynamic_submission(): void {
global $USER, $CFG;
$courseid = $this->get_instance()->courseid;
$course = get_course($courseid);
$context = context_course::instance($this->get_instance()->courseid);
if (!\core_course_category::can_view_course_info($course) && !is_enrolled($context, $USER, '', true)) {
throw new \moodle_exception('coursehidden', '', $CFG->wwwroot . '/');
}
}
#[\Override]
protected function get_context_for_dynamic_submission(): \context {
// This form is used for users who are not yet enrolled in the course and do not have access to the course.
// For the purpose of permission checks they must be able to access the course category for this course.
return context_course::instance($this->get_instance()->courseid)->get_parent_context();
}
#[\Override]
protected function get_page_url_for_dynamic_submission(): moodle_url {
$instance = $this->get_instance();
return new moodle_url('/enrol/index.php', ['id' => $instance->courseid, 'instance' => $instance->id]);
}
/**
* Process the form submission, used if form was submitted via AJAX
*
* Enrols the user in the course and returns the URL to redirect to
*
* @return string
*/
public function process_dynamic_submission() {
global $USER, $CFG, $SESSION;
/** @var \enrol_guest_plugin $enrol */
$enrol = enrol_get_plugin('guest');
$instance = $this->get_instance();
$enrol->mark_user_as_enrolled($instance, $this->get_data()->guestpassword);
// Go to the originally requested page.
if (!empty($SESSION->wantsurl)) {
$destination = $SESSION->wantsurl;
unset($SESSION->wantsurl);
} else {
require_once($CFG->dirroot . '/course/lib.php');
$destination = course_get_url($instance->courseid);
}
return $destination;
}
#[\Override]
public function set_data_for_dynamic_submission(): void {
$instance = $this->get_instance();
$this->set_data(['id' => $instance->courseid, 'instance' => $instance->id]);
}
}
+1
View File
@@ -31,6 +31,7 @@ $string['password_help'] = 'A password allows guest access to the course to be r
$string['passwordinvalid'] = 'Incorrect access password, please try again';
$string['passwordinvalidhint'] = 'That access password was incorrect, please try again<br />
(Here\'s a hint - it starts with \'{$a}\')';
$string['passwordrequired'] = 'A password will be required';
$string['pluginname'] = 'Guest access';
$string['pluginname_desc'] = 'Guest access plugin is only granting temporary access to courses, it is not actually enrolling users.';
$string['requirepassword'] = 'Require guest access password';
+41 -36
View File
@@ -25,7 +25,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
use core\output\single_button;
use core_enrol\output\enrol_page;
/**
* Class enrol_guest_plugin
@@ -148,14 +149,28 @@ class enrol_guest_plugin extends enrol_plugin {
}
/**
* Creates course enrol form, checks if form submitted
* and enrols user if necessary. It can also redirect.
* Enrol a user using the guest enrolment method
*
* @param stdClass $instance
* @return string html text, usually a form in a text box
* @param string $guestpassword
* @return void
*/
public function mark_user_as_enrolled(stdClass $instance, string $guestpassword): void {
global $USER, $CFG;
// Add guest role.
$context = \core\context\course::instance($instance->courseid);
$USER->enrol_guest_passwords[$instance->id] = $guestpassword;
if (isset($USER->enrol['tempguest'][$instance->courseid])) {
remove_temp_course_roles($context);
}
load_temp_course_role($context, $CFG->guestroleid);
$USER->enrol['tempguest'][$instance->courseid] = ENROL_MAX_TIMESTAMP;
}
#[\Override]
public function enrol_page_hook(stdClass $instance) {
global $CFG, $OUTPUT, $SESSION, $USER;
global $CFG, $OUTPUT, $SESSION, $USER, $PAGE;
if ($instance->password === '') {
return null;
@@ -166,37 +181,27 @@ class enrol_guest_plugin extends enrol_plugin {
return null;
}
require_once("$CFG->dirroot/enrol/guest/locallib.php");
$form = new enrol_guest_enrol_form(NULL, $instance);
$instanceid = optional_param('instance', 0, PARAM_INT);
if ($instance->id == $instanceid) {
if ($data = $form->get_data()) {
// add guest role
$context = context_course::instance($instance->courseid);
$USER->enrol_guest_passwords[$instance->id] = $data->guestpassword; // this is a hack, ideally we should not add stuff to $USER...
if (isset($USER->enrol['tempguest'][$instance->courseid])) {
remove_temp_course_roles($context);
}
load_temp_course_role($context, $CFG->guestroleid);
$USER->enrol['tempguest'][$instance->courseid] = ENROL_MAX_TIMESTAMP;
// go to the originally requested page
if (!empty($SESSION->wantsurl)) {
$destination = $SESSION->wantsurl;
unset($SESSION->wantsurl);
} else {
$destination = "$CFG->wwwroot/course/view.php?id=$instance->courseid";
}
redirect($destination);
}
}
ob_start();
$form->display();
$output = ob_get_clean();
return $OUTPUT->box($output, 'generalbox');
$title = $this->get_instance_name($instance);
$notification = new \core\output\notification(get_string('passwordrequired', 'enrol_guest'), 'info', false);
$notification->set_extra_classes(['mb-0']);
$button = new single_button(
$PAGE->url,
get_string('loginguest', 'moodle'),
'get',
single_button::BUTTON_PRIMARY,
[
'data-id' => $instance->courseid,
'data-instance' => $instance->id,
'data-form' => enrol_guest\form\enrol_form::class,
'data-title' => $title,
]);
$PAGE->requires->js_call_amd('enrol_guest/enrol_page', 'initEnrol', [$instance->id]);
$enrolpage = new enrol_page(
instance: $instance,
header: $title,
body: $OUTPUT->render($notification),
buttons: [$button]);
return $OUTPUT->render($enrolpage);
}
/**
+27 -7
View File
@@ -14,21 +14,41 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Guest access plugin implementation.
*
* @package enrol_guest
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once("$CFG->libdir/formslib.php");
/**
* Guest access plugin implementation.
*
* @deprecated since Moodle 5.0 - please use {@see enrol_guest\form\enrol_form}
*
* @package enrol_guest
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\core\attribute\deprecated(replacement: enrol_guest\form\enrol_form::class, since: '5.0', reason: 'Now a dynamic form is used')]
class enrol_guest_enrol_form extends moodleform {
protected $instance;
/**
* Constructor
*
* @param mixed $action
* @param mixed $customdata
* @param string $method
* @param string $target
* @param mixed $attributes
* @param bool $editable
* @param array $ajaxformdata
*/
public function __construct($action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true,
$ajaxformdata=null) {
\core\deprecation::emit_deprecation_if_present([$this, __FUNCTION__]);
parent::__construct($action, $customdata, $method, $target, $attributes, $editable, $ajaxformdata);
}
public function definition() {
$mform = $this->_form;
$instance = $this->_customdata;
+3 -1
View File
@@ -30,6 +30,7 @@ Feature: Guest users can auto-enrol themself in courses where guest access is al
When I am on the "Test forum name" "forum activity" page logged in as student1
Then I should not see "Subscribe to this forum"
@javascript
Scenario: Allow guest access with password
Given I click on "Edit" "link" in the "Guest access" "table_row"
And I set the following fields to these values:
@@ -38,7 +39,8 @@ Feature: Guest users can auto-enrol themself in courses where guest access is al
And I press "Save changes"
When I am on the "Course 1" course page logged in as student1
Then I should see "Guest access"
And I press "Access as a guest"
And I set the following fields to these values:
| Password | moodle_rules |
And I press "Submit"
And I click on "Access as a guest" "button" in the "Guest access" "dialogue"
And I should see "Test forum name"