MDL-73483 course: add callbacks to extend course form

This commit is contained in:
Dmitrii Metelkin 2023-12-05 11:07:22 +11:00
parent d3ad77e476
commit 95eea308cd
8 changed files with 461 additions and 1 deletions

View File

@ -0,0 +1,94 @@
<?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/>.
namespace core_course\hook;
use core\hook\described_hook;
use course_edit_form;
use MoodleQuickForm;
/**
* Allows plugins to extend course form definition and add/remove/update form elements.
*
* @see course_edit_form::definition()
*
* @package core
* @copyright 2023 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_form_definition implements described_hook {
/**
* Course form wrapper.
*
* @var course_edit_form
*/
protected $formwrapper;
/**
* Form to be extended.
*
* @var \MoodleQuickForm
*/
protected $mform;
/**
* Creates new hook.
*
* @param course_edit_form $formwrapper Course form wrapper.
* @param MoodleQuickForm $mform Form to be extended.
*/
public function __construct(course_edit_form $formwrapper, MoodleQuickForm $mform) {
$this->formwrapper = $formwrapper;
$this->mform = $mform;
}
/**
* Returns form.
*
* @return MoodleQuickForm
*/
public function get_mform(): MoodleQuickForm {
return $this->mform;
}
/**
* Returns form wrapper instance.
*
* @return course_edit_form
*/
public function get_formwrapper(): course_edit_form {
return $this->formwrapper;
}
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allows plugins to extend course editing form';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['course'];
}
}

View File

@ -0,0 +1,94 @@
<?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/>.
namespace core_course\hook;
use core\hook\described_hook;
use course_edit_form;
use MoodleQuickForm;
/**
* Allows plugins to extend course form after data is set.
*
* @see course_edit_form::definition_after_data()
*
* @package core
* @copyright 2023 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_form_definition_after_data implements described_hook {
/**
* Course form wrapper.
*
* @var course_edit_form
*/
protected $formwrapper;
/**
* Form to be extended.
*
* @var \MoodleQuickForm
*/
protected $mform;
/**
* Creates new hook.
*
* @param course_edit_form $formwrapper Course form wrapper..
* @param MoodleQuickForm $mform Form to be extended.
*/
public function __construct(course_edit_form $formwrapper, MoodleQuickForm $mform) {
$this->formwrapper = $formwrapper;
$this->mform = $mform;
}
/**
* Returns form.
*
* @return MoodleQuickForm
*/
public function get_mform(): MoodleQuickForm {
return $this->mform;
}
/**
* Returns form wrapper instance.
*
* @return course_edit_form
*/
public function get_formwrapper(): course_edit_form {
return $this->formwrapper;
}
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allows plugins to extend course editing form after data is set';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['course'];
}
}

View File

@ -0,0 +1,94 @@
<?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/>.
namespace core_course\hook;
use core\hook\described_hook;
use stdClass;
/**
* Allows plugins to extend course form submission.
*
* @see create_course()
* @see update_course()
*
* @package core
* @copyright 2023 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_form_submission implements described_hook {
/**
* Submitted data.
*
* @var stdClass
*/
protected $data;
/**
* Is it a new course ?
*
* @var bool
*/
protected $isnewcourse = false;
/**
* Creates new hook.
*
* @param stdClass $data Submitted data.
* @param bool $isnewcourse Is it a new course?
*/
public function __construct(stdClass $data, bool $isnewcourse = false) {
$this->data = $data;
$this->isnewcourse = $isnewcourse;
}
/**
* Returns submitted data.
*
* @return stdClass
*/
public function get_data(): stdClass {
return $this->data;
}
/**
* Informs callbacks if a hook called for a new course.
*
* @return bool
*/
public function is_new_course(): bool {
return $this->isnewcourse;
}
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allows plugins to extend saving of the course editing form';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['course'];
}
}

View File

@ -0,0 +1,137 @@
<?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/>.
namespace core_course\hook;
use core\hook\described_hook;
use course_edit_form;
/**
* Allows plugins to extend course form validation.
*
* @see course_edit_form::validation()
*
* @package core
* @copyright 2023 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class after_form_validation implements described_hook {
/**
* Course form wrapper.
*
* @var course_edit_form
*/
protected $formwrapper;
/**
* Submitted data.
*
* @var array
*/
protected $data = [];
/**
* Submitted files.
*
* @var array
*/
protected $files = [];
/**
* Plugin errors.
*
* @var array
*/
protected $errors = [];
/**
* Creates new hook.
*
* @param course_edit_form $formwrapper Course form wrapper..
* @param array $data Submitted data.
* @param array $files Submitted files.
*/
public function __construct(course_edit_form $formwrapper, array $data, array $files = []) {
$this->formwrapper = $formwrapper;
$this->data = $data;
$this->files = $files;
}
/**
* Returns form wrapper instance.
*
* @return course_edit_form
*/
public function get_formwrapper(): course_edit_form {
return $this->formwrapper;
}
/**
* Returns submitted data.
*
* @return array
*/
public function get_data(): array {
return $this->data;
}
/**
* Returns submitted files.
*
* @return array
*/
public function get_files(): array {
return $this->files;
}
/**
* Return plugin generated errors.
*
* @return array
*/
public function get_errors(): array {
return $this->errors;
}
/**
* Plugins implementing a callback can add validation errors.
*
* @param array $errors Validation errors generated by a plugin.
* @return void
*/
public function add_errors(array $errors): void {
$this->errors = array_merge($this->errors, $errors);
}
/**
* Describes the hook purpose.
*
* @return string
*/
public static function get_hook_description(): string {
return 'Allows plugins to extend a validation of the course editing form';
}
/**
* List of tags that describe this hook.
*
* @return string[]
*/
public static function get_hook_tags(): array {
return ['course'];
}
}

View File

@ -418,6 +418,8 @@ class course_edit_form extends moodleform {
$handler->set_parent_context($categorycontext); // For course handler only.
$handler->instance_form_definition($mform, empty($course->id) ? 0 : $course->id);
$hook = new \core_course\hook\after_form_definition($this, $mform);
\core\hook\manager::get_instance()->dispatch($hook);
// When two elements we need a group.
$buttonarray = array();
@ -488,6 +490,9 @@ class course_edit_form extends moodleform {
// Tweak the form with values provided by custom fields in use.
$handler = core_course\customfield\course_handler::create();
$handler->instance_form_definition_after_data($mform, empty($courseid) ? 0 : $courseid);
$hook = new \core_course\hook\after_form_definition_after_data($this, $mform);
\core\hook\manager::get_instance()->dispatch($hook);
}
/**
@ -534,6 +539,31 @@ class course_edit_form extends moodleform {
$handler = core_course\customfield\course_handler::create();
$errors = array_merge($errors, $handler->instance_form_validation($data, $files));
$hook = new \core_course\hook\after_form_validation($this, $data, $files);
\core\hook\manager::get_instance()->dispatch($hook);
$pluginerrors = $hook->get_errors();
if (!empty($pluginerrors)) {
$errors = array_merge($errors, $pluginerrors);
}
return $errors;
}
/**
* Returns course object.
*
* @return \stdClass
*/
public function get_course(): stdClass {
return $this->course;
}
/**
* Returns context.
*
* @return \core\context
*/
public function get_context(): \core\context {
return $this->context;
}
}

View File

@ -2177,6 +2177,9 @@ function create_course($data, $editoroptions = NULL) {
$data->id = $course->id;
$handler->instance_form_save($data, true);
$hook = new \core_course\hook\after_form_submission($data, true);
\core\hook\manager::get_instance()->dispatch($hook);
return $course;
}
@ -2425,6 +2428,9 @@ function update_course($data, $editoroptions = NULL) {
$handler = core_course\customfield\course_handler::create();
$handler->instance_form_save($data);
$hook = new \core_course\hook\after_form_submission($data);
\core\hook\manager::get_instance()->dispatch($hook);
// Update with the new data
$DB->update_record('course', $data);
// make sure the modinfo cache is reset

View File

@ -22,6 +22,11 @@ information provided here is intended especially for developers.
* New format actions classes. Those classes will eventually replace all course/lib.php content editing functions.
All new methods are distributed in three classes formats can extend. Method can be accessed using static
methods (see doc block of core_courseformat\formatactions for more information).
* New hooks for extending course form:
- core_course\hook\after_form_definition
- core_course\hook\after_form_definition_after_data
- core_course\hook\after_form_validation
- core_course\hook\after_form_submission
=== 4.3 ===
* The `core_course_renderer::course_section_cm_completion` method has been removed, and can no longer be used

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2024021500.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2024021500.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.4dev (Build: 20240215)'; // Human-friendly version name