See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
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 * Defines classes used for plugin info. 19 * 20 * @package core 21 * @copyright 2011 David Mudrak <david@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core\plugininfo; 25 26 use moodle_url, part_of_admin_tree, admin_settingpage; 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 /** 31 * Class for activity modules 32 */ 33 class mod extends base { 34 /** 35 * Finds all enabled plugins, the result may include missing plugins. 36 * @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown 37 */ 38 public static function get_enabled_plugins() { 39 global $DB; 40 return $DB->get_records_menu('modules', array('visible'=>1), 'name ASC', 'name, name AS val'); 41 } 42 43 public static function enable_plugin(string $pluginname, int $enabled): bool { 44 global $DB; 45 46 if (!$module = $DB->get_record('modules', ['name' => $pluginname])) { 47 throw new \moodle_exception('moduledoesnotexist', 'error'); 48 } 49 50 $haschanged = false; 51 52 // Only set visibility if it's different from the current value. 53 if ($module->visible != $enabled) { 54 if ($enabled && component_callback_exists("mod_{$pluginname}", 'pre_enable_plugin_actions')) { 55 // This callback may be used to perform actions that must be completed prior to enabling a plugin. 56 // Example of this may include: 57 // - making a configuration change 58 // - adding an alert 59 // - checking a pre-requisite 60 // 61 // If the return value is falsy, then the change will be prevented. 62 if (!component_callback("mod_{$pluginname}", 'pre_enable_plugin_actions')) { 63 return false; 64 } 65 } 66 // Set module visibility. 67 $DB->set_field('modules', 'visible', $enabled, ['id' => $module->id]); 68 $haschanged = true; 69 70 if ($enabled) { 71 // Revert the previous saved visible state for the course module. 72 $DB->set_field('course_modules', 'visible', '1', ['visibleold' => 1, 'module' => $module->id]); 73 74 // Increment course.cacherev for courses where we just made something visible. 75 // This will force cache rebuilding on the next request. 76 increment_revision_number('course', 'cacherev', 77 "id IN (SELECT DISTINCT course 78 FROM {course_modules} 79 WHERE visible = 1 AND module = ?)", 80 [$module->id] 81 ); 82 } else { 83 // Remember the visibility status in visibleold and hide. 84 $sql = "UPDATE {course_modules} 85 SET visibleold = visible, visible = 0 86 WHERE module = ?"; 87 $DB->execute($sql, [$module->id]); 88 // Increment course.cacherev for courses where we just made something invisible. 89 // This will force cache rebuilding on the next request. 90 increment_revision_number('course', 'cacherev', 91 'id IN (SELECT DISTINCT course 92 FROM {course_modules} 93 WHERE visibleold = 1 AND module = ?)', 94 [$module->id] 95 ); 96 } 97 98 // Include this information into config changes table. 99 add_to_config_log('mod_visibility', $module->visible, $enabled, $pluginname); 100 \core_plugin_manager::reset_caches(); 101 } 102 103 return $haschanged; 104 } 105 106 /** 107 * Magic method getter, redirects to read only values. 108 * 109 * For module plugins we pretend the object has 'visible' property for compatibility 110 * with plugins developed for Moodle version below 2.4 111 * 112 * @param string $name 113 * @return mixed 114 */ 115 public function __get($name) { 116 if ($name === 'visible') { 117 debugging('This is now an instance of plugininfo_mod, please use $module->is_enabled() instead of $module->visible', DEBUG_DEVELOPER); 118 return ($this->is_enabled() !== false); 119 } 120 return parent::__get($name); 121 } 122 123 public function init_display_name() { 124 if (get_string_manager()->string_exists('pluginname', $this->component)) { 125 $this->displayname = get_string('pluginname', $this->component); 126 } else { 127 $this->displayname = get_string('modulename', $this->component); 128 } 129 } 130 131 public function get_settings_section_name() { 132 return 'modsetting' . $this->name; 133 } 134 135 public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { 136 global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them. 137 $ADMIN = $adminroot; // May be used in settings.php. 138 $plugininfo = $this; // Also can be used inside settings.php. 139 $module = $this; // Also can be used inside settings.php. 140 141 if (!$this->is_installed_and_upgraded()) { 142 return; 143 } 144 145 if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) { 146 return; 147 } 148 149 $section = $this->get_settings_section_name(); 150 151 $settings = new admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false); 152 include($this->full_path('settings.php')); // This may also set $settings to null. 153 154 if ($settings) { 155 $ADMIN->add($parentnodename, $settings); 156 } 157 } 158 159 /** 160 * Allow all activity modules but Forum to be uninstalled. 161 * 162 * This exception for the Forum has been hard-coded in Moodle since ages, 163 * we may want to re-think it one day. 164 */ 165 public function is_uninstall_allowed() { 166 if ($this->name === 'forum') { 167 return false; 168 } else { 169 return true; 170 } 171 } 172 173 /** 174 * Return URL used for management of plugins of this type. 175 * @return moodle_url 176 */ 177 public static function get_manage_url() { 178 return new moodle_url('/admin/modules.php'); 179 } 180 181 /** 182 * Return warning with number of activities and number of affected courses. 183 * 184 * @return string 185 */ 186 public function get_uninstall_extra_warning() { 187 global $DB; 188 189 if (!$module = $DB->get_record('modules', array('name'=>$this->name))) { 190 return ''; 191 } 192 193 if (!$count = $DB->count_records('course_modules', array('module'=>$module->id))) { 194 return ''; 195 } 196 197 $sql = "SELECT COUNT('x') 198 FROM ( 199 SELECT course 200 FROM {course_modules} 201 WHERE module = :mid 202 GROUP BY course 203 ) c"; 204 $courses = $DB->count_records_sql($sql, array('mid'=>$module->id)); 205 206 return '<p>'.get_string('uninstallextraconfirmmod', 'core_plugin', array('instances'=>$count, 'courses'=>$courses)).'</p>'; 207 } 208 209 /** 210 * Pre-uninstall hook. 211 * 212 * This is intended for disabling of plugin, some DB table purging, etc. 213 * 214 * NOTE: to be called from uninstall_plugin() only. 215 * @private 216 */ 217 public function uninstall_cleanup() { 218 global $DB, $CFG; 219 220 if (!$module = $DB->get_record('modules', array('name' => $this->name))) { 221 parent::uninstall_cleanup(); 222 return; 223 } 224 225 // Delete all the relevant instances from all course sections. 226 if ($coursemods = $DB->get_records('course_modules', array('module' => $module->id))) { 227 foreach ($coursemods as $coursemod) { 228 // Do not verify results, there is not much we can do anyway. 229 delete_mod_from_section($coursemod->id, $coursemod->section); 230 } 231 } 232 233 // Increment course.cacherev for courses that used this module. 234 // This will force cache rebuilding on the next request. 235 increment_revision_number('course', 'cacherev', 236 "id IN (SELECT DISTINCT course 237 FROM {course_modules} 238 WHERE module=?)", 239 array($module->id)); 240 241 // Delete all the course module records. 242 $DB->delete_records('course_modules', array('module' => $module->id)); 243 244 // Delete module contexts. 245 if ($coursemods) { 246 foreach ($coursemods as $coursemod) { 247 \context_helper::delete_instance(CONTEXT_MODULE, $coursemod->id); 248 } 249 } 250 251 // Delete the module entry itself. 252 $DB->delete_records('modules', array('name' => $module->name)); 253 254 // Cleanup the gradebook. 255 require_once($CFG->libdir.'/gradelib.php'); 256 grade_uninstalled_module($module->name); 257 258 // Do not look for legacy $module->name . '_uninstall any more, 259 // they should have migrated to db/uninstall.php by now. 260 261 parent::uninstall_cleanup(); 262 } 263 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body