Merge branch 'MDL-81457-main' of https://github.com/andrewnicols/moodle
[moodle.git] / customfield / classes / field_config_form.php
blob53d1b5f54a1dd2b3869a0affcdfa87be3cc7e648
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Customfield package
20 * @package core_customfield
21 * @copyright 2018 David Matamoros <davidmc@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core_customfield;
27 defined('MOODLE_INTERNAL') || die;
29 /**
30 * Class field_config_form
32 * @package core_customfield
33 * @copyright 2018 David Matamoros <davidmc@moodle.com>
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 class field_config_form extends \core_form\dynamic_form {
38 /** @var field_controller */
39 protected $field;
41 /**
42 * Class definition
44 * @throws \coding_exception
46 public function definition() {
47 $mform = $this->_form;
49 $field = $this->get_field();
50 $handler = $field->get_handler();
52 $mform->addElement('header', '_commonsettings', get_string('commonsettings', 'core_customfield'));
54 $mform->addElement('text', 'name', get_string('fieldname', 'core_customfield'), 'size="50"');
55 $mform->addRule('name', null, 'required', null, 'client');
56 $mform->setType('name', PARAM_TEXT);
58 // Accepted values for 'shortname' would follow [a-z0-9_] pattern,
59 // but we are accepting any PARAM_TEXT value here,
60 // and checking [a-zA-Z0-9_] pattern in validation() function to throw an error when needed.
61 $mform->addElement('text', 'shortname', get_string('fieldshortname', 'core_customfield'), 'size=20');
62 $mform->addHelpButton('shortname', 'shortname', 'core_customfield');
63 $mform->addRule('shortname', null, 'required', null, 'client');
64 $mform->setType('shortname', PARAM_TEXT);
66 $desceditoroptions = $handler->get_description_text_options();
67 $mform->addElement('editor', 'description_editor', get_string('description', 'core_customfield'), null, $desceditoroptions);
68 $mform->addHelpButton('description_editor', 'description', 'core_customfield');
70 // If field is required.
71 $mform->addElement('selectyesno', 'configdata[required]', get_string('isfieldrequired', 'core_customfield'));
72 $mform->addHelpButton('configdata[required]', 'isfieldrequired', 'core_customfield');
73 $mform->setType('configdata[required]', PARAM_BOOL);
75 // If field data is unique.
76 $mform->addElement('selectyesno', 'configdata[uniquevalues]', get_string('isdataunique', 'core_customfield'));
77 $mform->addHelpButton('configdata[uniquevalues]', 'isdataunique', 'core_customfield');
78 $mform->setType('configdata[uniquevalues]', PARAM_BOOL);
80 // Field specific settings from field type.
81 $field->config_form_definition($mform);
83 // Handler/component settings.
84 $handler->config_form_definition($mform);
86 // We add hidden fields.
87 $mform->addElement('hidden', 'categoryid');
88 $mform->setType('categoryid', PARAM_INT);
90 $mform->addElement('hidden', 'type');
91 $mform->setType('type', PARAM_COMPONENT);
93 $mform->addElement('hidden', 'id');
94 $mform->setType('id', PARAM_INT);
96 // This form is only used inside modal dialogues and never needs action buttons.
99 /**
100 * Field data validation
102 * @param array $data
103 * @param array $files
104 * @return array
106 public function validation($data, $files = array()) {
107 global $DB;
109 $errors = array();
110 $field = $this->get_field();
111 $handler = $field->get_handler();
113 // Check the shortname is specified and is unique for this component-area-itemid combination.
114 if (!preg_match('/^[a-z0-9_]+$/', $data['shortname'])) {
115 // Check allowed pattern (numbers, letters and underscore).
116 $errors['shortname'] = get_string('invalidshortnameerror', 'core_customfield');
117 } else if ($DB->record_exists_sql('SELECT 1 FROM {customfield_field} f ' .
118 'JOIN {customfield_category} c ON c.id = f.categoryid ' .
119 'WHERE f.shortname = ? AND f.id <> ? AND c.component = ? AND c.area = ? AND c.itemid = ?',
120 [$data['shortname'], $data['id'],
121 $handler->get_component(), $handler->get_area(), $handler->get_itemid()])) {
122 $errors['shortname'] = get_string('formfieldcheckshortname', 'core_customfield');
125 $errors = array_merge($errors, $field->config_form_validation($data, $files));
127 return $errors;
131 * Get field
133 * @return field_controller
134 * @throws \moodle_exception
136 protected function get_field(): field_controller {
137 if ($this->field === null) {
138 if (!empty($this->_ajaxformdata['id'])) {
139 $this->field = \core_customfield\field_controller::create((int)$this->_ajaxformdata['id']);
140 } else if (!empty($this->_ajaxformdata['categoryid']) && !empty($this->_ajaxformdata['type'])) {
141 $category = \core_customfield\category_controller::create((int)$this->_ajaxformdata['categoryid']);
142 $type = clean_param($this->_ajaxformdata['type'], PARAM_PLUGIN);
143 $this->field = \core_customfield\field_controller::create(0, (object)['type' => $type], $category);
144 } else {
145 throw new \moodle_exception('fieldnotfound', 'core_customfield');
148 return $this->field;
152 * Check if current user has access to this form, otherwise throw exception
154 * Sometimes permission check may depend on the action and/or id of the entity.
155 * If necessary, form data is available in $this->_ajaxformdata
157 protected function check_access_for_dynamic_submission(): void {
158 $field = $this->get_field();
159 $handler = $field->get_handler();
160 if (!$handler->can_configure()) {
161 throw new \moodle_exception('nopermissionconfigure', 'core_customfield');
166 * Load in existing data as form defaults
168 * Can be overridden to retrieve existing values from db by entity id and also
169 * to preprocess editor and filemanager elements
171 * Example:
172 * $this->set_data(get_entity($this->_ajaxformdata['id']));
174 public function set_data_for_dynamic_submission(): void {
175 $this->set_data(api::prepare_field_for_config_form($this->get_field()));
179 * Process the form submission
181 * This method can return scalar values or arrays that can be json-encoded, they will be passed to the caller JS.
183 * @return mixed
185 public function process_dynamic_submission() {
186 $data = $this->get_data();
187 $field = $this->get_field();
188 $handler = $field->get_handler();
189 $handler->save_field_configuration($field, $data);
190 return null;
194 * Form context
195 * @return \context
197 protected function get_context_for_dynamic_submission(): \context {
198 return $this->get_field()->get_handler()->get_configuration_context();
202 * Page url
203 * @return \moodle_url
205 protected function get_page_url_for_dynamic_submission(): \moodle_url {
206 $field = $this->get_field();
207 if ($field->get('id')) {
208 $params = ['action' => 'editfield', 'id' => $field->get('id')];
209 } else {
210 $params = ['action' => 'addfield', 'categoryid' => $field->get('categoryid'), 'type' => $field->get('type')];
212 return new \moodle_url($field->get_handler()->get_configuration_url(), $params);