See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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. 13 // 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/>. 16 17 /** 18 * Course handler for custom fields 19 * 20 * @package core_course 21 * @copyright 2018 David Matamoros <davidmc@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_course\customfield; 26 27 defined('MOODLE_INTERNAL') || die; 28 29 use core_customfield\api; 30 use core_customfield\field_controller; 31 32 /** 33 * Course handler for custom fields 34 * 35 * @package core_course 36 * @copyright 2018 David Matamoros <davidmc@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class course_handler extends \core_customfield\handler { 40 41 /** 42 * @var course_handler 43 */ 44 static protected $singleton; 45 46 /** 47 * @var \context 48 */ 49 protected $parentcontext; 50 51 /** @var int Field is displayed in the course listing, visible to everybody */ 52 const VISIBLETOALL = 2; 53 /** @var int Field is displayed in the course listing but only for teachers */ 54 const VISIBLETOTEACHERS = 1; 55 /** @var int Field is not displayed in the course listing */ 56 const NOTVISIBLE = 0; 57 58 /** 59 * Returns a singleton 60 * 61 * @param int $itemid 62 * @return \core_course\customfield\course_handler 63 */ 64 public static function create(int $itemid = 0) : \core_customfield\handler { 65 if (static::$singleton === null) { 66 self::$singleton = new static(0); 67 } 68 return self::$singleton; 69 } 70 71 /** 72 * Run reset code after unit tests to reset the singleton usage. 73 */ 74 public static function reset_caches(): void { 75 if (!PHPUNIT_TEST) { 76 throw new \coding_exception('This feature is only intended for use in unit tests'); 77 } 78 79 static::$singleton = null; 80 } 81 82 /** 83 * The current user can configure custom fields on this component. 84 * 85 * @return bool true if the current can configure custom fields, false otherwise 86 */ 87 public function can_configure() : bool { 88 return has_capability('moodle/course:configurecustomfields', $this->get_configuration_context()); 89 } 90 91 /** 92 * The current user can edit custom fields on the given course. 93 * 94 * @param field_controller $field 95 * @param int $instanceid id of the course to test edit permission 96 * @return bool true if the current can edit custom fields, false otherwise 97 */ 98 public function can_edit(field_controller $field, int $instanceid = 0) : bool { 99 if ($instanceid) { 100 $context = $this->get_instance_context($instanceid); 101 return (!$field->get_configdata_property('locked') || 102 has_capability('moodle/course:changelockedcustomfields', $context)); 103 } else { 104 $context = $this->get_parent_context(); 105 if ($context->contextlevel == CONTEXT_SYSTEM) { 106 return (!$field->get_configdata_property('locked') || 107 has_capability('moodle/course:changelockedcustomfields', $context)); 108 } else { 109 return (!$field->get_configdata_property('locked') || 110 guess_if_creator_will_have_course_capability('moodle/course:changelockedcustomfields', $context)); 111 } 112 } 113 } 114 115 /** 116 * The current user can view custom fields on the given course. 117 * 118 * @param field_controller $field 119 * @param int $instanceid id of the course to test edit permission 120 * @return bool true if the current can edit custom fields, false otherwise 121 */ 122 public function can_view(field_controller $field, int $instanceid) : bool { 123 $visibility = $field->get_configdata_property('visibility'); 124 if ($visibility == self::NOTVISIBLE) { 125 return false; 126 } else if ($visibility == self::VISIBLETOTEACHERS) { 127 return has_capability('moodle/course:update', $this->get_instance_context($instanceid)); 128 } else { 129 return true; 130 } 131 } 132 133 /** 134 * Sets parent context for the course 135 * 136 * This may be needed when course is being created, there is no course context but we need to check capabilities 137 * 138 * @param \context $context 139 */ 140 public function set_parent_context(\context $context) { 141 $this->parentcontext = $context; 142 } 143 144 /** 145 * Returns the parent context for the course 146 * 147 * @return \context 148 */ 149 protected function get_parent_context() : \context { 150 global $PAGE; 151 if ($this->parentcontext) { 152 return $this->parentcontext; 153 } else if ($PAGE->context && $PAGE->context instanceof \context_coursecat) { 154 return $PAGE->context; 155 } 156 return \context_system::instance(); 157 } 158 159 /** 160 * Context that should be used for new categories created by this handler 161 * 162 * @return \context the context for configuration 163 */ 164 public function get_configuration_context() : \context { 165 return \context_system::instance(); 166 } 167 168 /** 169 * URL for configuration of the fields on this handler. 170 * 171 * @return \moodle_url The URL to configure custom fields for this component 172 */ 173 public function get_configuration_url() : \moodle_url { 174 return new \moodle_url('/course/customfield.php'); 175 } 176 177 /** 178 * Returns the context for the data associated with the given instanceid. 179 * 180 * @param int $instanceid id of the record to get the context for 181 * @return \context the context for the given record 182 */ 183 public function get_instance_context(int $instanceid = 0) : \context { 184 if ($instanceid > 0) { 185 return \context_course::instance($instanceid); 186 } else { 187 return \context_system::instance(); 188 } 189 } 190 191 /** 192 * Allows to add custom controls to the field configuration form that will be saved in configdata 193 * 194 * @param \MoodleQuickForm $mform 195 */ 196 public function config_form_definition(\MoodleQuickForm $mform) { 197 $mform->addElement('header', 'course_handler_header', get_string('customfieldsettings', 'core_course')); 198 $mform->setExpanded('course_handler_header', true); 199 200 // If field is locked. 201 $mform->addElement('selectyesno', 'configdata[locked]', get_string('customfield_islocked', 'core_course')); 202 $mform->addHelpButton('configdata[locked]', 'customfield_islocked', 'core_course'); 203 204 // Field data visibility. 205 $visibilityoptions = [self::VISIBLETOALL => get_string('customfield_visibletoall', 'core_course'), 206 self::VISIBLETOTEACHERS => get_string('customfield_visibletoteachers', 'core_course'), 207 self::NOTVISIBLE => get_string('customfield_notvisible', 'core_course')]; 208 $mform->addElement('select', 'configdata[visibility]', get_string('customfield_visibility', 'core_course'), 209 $visibilityoptions); 210 $mform->addHelpButton('configdata[visibility]', 'customfield_visibility', 'core_course'); 211 } 212 213 /** 214 * Creates or updates custom field data. 215 * 216 * @param \restore_task $task 217 * @param array $data 218 */ 219 public function restore_instance_data_from_backup(\restore_task $task, array $data) { 220 $courseid = $task->get_courseid(); 221 $context = $this->get_instance_context($courseid); 222 $editablefields = $this->get_editable_fields($courseid); 223 $records = api::get_instance_fields_data($editablefields, $courseid); 224 $target = $task->get_target(); 225 $override = ($target != \backup::TARGET_CURRENT_ADDING && $target != \backup::TARGET_EXISTING_ADDING); 226 227 foreach ($records as $d) { 228 $field = $d->get_field(); 229 if ($field->get('shortname') === $data['shortname'] && $field->get('type') === $data['type']) { 230 if (!$d->get('id') || $override) { 231 $d->set($d->datafield(), $data['value']); 232 $d->set('value', $data['value']); 233 $d->set('valueformat', $data['valueformat']); 234 $d->set('contextid', $context->id); 235 $d->save(); 236 } 237 return; 238 } 239 } 240 } 241 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body