Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [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 * New role XML processing. 19 * 20 * @package core_role 21 * @copyright 2013 Petr Skoda {@link http://skodak.org} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 /** 28 * XML role file manipulation class. 29 * 30 * @package core_role 31 * @copyright 2013 Petr Skoda {@link http://skodak.org} 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class core_role_preset { 35 36 /** 37 * Send role export xml file to browser. 38 * 39 * @param int $roleid 40 * @return void does not return, send the file to output 41 */ 42 public static function send_export_xml($roleid) { 43 global $CFG, $DB; 44 require_once($CFG->libdir . '/filelib.php'); 45 46 $role = $DB->get_record('role', array('id'=>$roleid), '*', MUST_EXIST); 47 48 if ($role->shortname) { 49 $filename = $role->shortname.'.xml'; 50 } else { 51 $filename = 'role.xml'; 52 } 53 $xml = self::get_export_xml($roleid); 54 send_file($xml, $filename, 0, false, true, true); 55 die(); 56 } 57 58 /** 59 * Generate role export xml file. 60 * 61 * @param $roleid 62 * @return string 63 */ 64 public static function get_export_xml($roleid) { 65 global $DB; 66 67 $role = $DB->get_record('role', array('id'=>$roleid), '*', MUST_EXIST); 68 69 $dom = new DOMDocument('1.0', 'UTF-8'); 70 $top = $dom->createElement('role'); 71 $dom->appendChild($top); 72 73 $top->appendChild($dom->createElement('shortname', $role->shortname)); 74 $top->appendChild($dom->createElement('name', htmlspecialchars($role->name, ENT_COMPAT | ENT_HTML401, 'UTF-8'))); 75 $top->appendChild($dom->createElement('description', htmlspecialchars($role->description, ENT_COMPAT | ENT_HTML401, 76 'UTF-8'))); 77 $top->appendChild($dom->createElement('archetype', $role->archetype)); 78 79 $contextlevels = $dom->createElement('contextlevels'); 80 $top->appendChild($contextlevels); 81 foreach (get_role_contextlevels($roleid) as $level) { 82 $name = context_helper::get_class_for_level($level); 83 if (strpos($name, 'core\\context\\') === 0) { 84 // Use short names of standard contexts for backwards compatibility. 85 $value = preg_replace('/^core\\\\context\\\\/', '', $name); 86 } else { 87 // Must be a custom plugin level, use numbers to work around 88 // potential duplicate short names of contexts in add-ons. 89 $value = $level; 90 } 91 $contextlevels->appendChild($dom->createElement('level', $value)); 92 } 93 94 foreach (array('assign', 'override', 'switch', 'view') as $type) { 95 $allows = $dom->createElement('allow'.$type); 96 $top->appendChild($allows); 97 $records = $DB->get_records('role_allow_'.$type, array('roleid'=>$roleid), "allow$type ASC"); 98 foreach ($records as $record) { 99 if (!$ar = $DB->get_record('role', array('id'=>$record->{'allow'.$type}))) { 100 continue; 101 } 102 $allows->appendChild($dom->createElement('shortname', $ar->shortname)); 103 } 104 } 105 106 $permissions = $dom->createElement('permissions'); 107 $top->appendChild($permissions); 108 109 $capabilities = $DB->get_records_sql_menu( 110 "SELECT capability, permission 111 FROM {role_capabilities} 112 WHERE contextid = :syscontext AND roleid = :roleid 113 ORDER BY capability ASC", 114 array('syscontext'=>context_system::instance()->id, 'roleid'=>$roleid)); 115 116 $allcapabilities = $DB->get_records('capabilities', array(), 'name ASC'); 117 foreach ($allcapabilities as $cap) { 118 if (!isset($capabilities[$cap->name])) { 119 $permissions->appendChild($dom->createElement('inherit', $cap->name)); 120 } 121 } 122 123 foreach ($capabilities as $capability => $permission) { 124 if ($permission == CAP_ALLOW) { 125 $permissions->appendChild($dom->createElement('allow', $capability)); 126 } 127 } 128 foreach ($capabilities as $capability => $permission) { 129 if ($permission == CAP_PREVENT) { 130 $permissions->appendChild($dom->createElement('prevent', $capability)); 131 } 132 } 133 foreach ($capabilities as $capability => $permission) { 134 if ($permission == CAP_PROHIBIT) { 135 $permissions->appendChild($dom->createElement('prohibit', $capability)); 136 } 137 } 138 139 return $dom->saveXML(); 140 } 141 142 /** 143 * Is this XML valid role preset? 144 * 145 * @param string $xml 146 * @return bool 147 */ 148 public static function is_valid_preset($xml) { 149 $dom = new DOMDocument(); 150 if (!$dom->loadXML($xml)) { 151 return false; 152 } else { 153 $val = @$dom->schemaValidate(__DIR__.'/../role_schema.xml'); 154 if (!$val) { 155 return false; 156 } 157 } 158 return true; 159 } 160 161 /** 162 * Parse role preset xml file. 163 * 164 * @param string $xml 165 * @return array role info, null on error 166 */ 167 public static function parse_preset($xml) { 168 global $DB; 169 170 $info = array(); 171 172 if (!self::is_valid_preset($xml)) { 173 return null; 174 } 175 176 $dom = new DOMDocument(); 177 $dom->loadXML($xml); 178 179 $info['shortname'] = self::get_node_value($dom, '/role/shortname'); 180 if (isset($info['shortname'])) { 181 $info['shortname'] = strtolower(clean_param($info['shortname'], PARAM_ALPHANUMEXT)); 182 } 183 184 $info['name'] = self::get_node_value($dom, '/role/name'); 185 if (isset($value)) { 186 $info['name'] = clean_param($info['name'], PARAM_TEXT); 187 } 188 189 $info['description'] = self::get_node_value($dom, '/role/description'); 190 if (isset($value)) { 191 $info['description'] = clean_param($info['description'], PARAM_CLEANHTML); 192 } 193 194 $info['archetype'] = self::get_node_value($dom, '/role/archetype'); 195 if (isset($value)) { 196 $archetypes = get_role_archetypes(); 197 if (!isset($archetypes[$info['archetype']])) { 198 $info['archetype'] = null; 199 } 200 } 201 202 $values = self::get_node_children_values($dom, '/role/contextlevels', 'level'); 203 if (isset($values)) { 204 $info['contextlevels'] = array(); 205 $levelmap = array_flip(context_helper::get_all_levels()); 206 foreach ($values as $value) { 207 // Numbers and short names are supported since Moodle 4.2. 208 $classname = \core\context_helper::parse_external_level($value); 209 if ($classname) { 210 $cl = $classname::LEVEL; 211 $info['contextlevels'][$cl] = $cl; 212 } 213 } 214 } 215 216 foreach (array('assign', 'override', 'switch', 'view') as $type) { 217 $values = self::get_node_children_values($dom, '/role/allow'.$type, 'shortname'); 218 if (!isset($values)) { 219 $info['allow'.$type] = null; 220 continue; 221 } 222 $info['allow'.$type] = array(); 223 foreach ($values as $value) { 224 if ($value === $info['shortname']) { 225 array_unshift($info['allow'.$type], -1); // Means self. 226 } 227 if ($role = $DB->get_record('role', array('shortname'=>$value))) { 228 $info['allow'.$type][] = $role->id; 229 continue; 230 } 231 } 232 } 233 234 $info['permissions'] = array(); 235 $values = self::get_node_children_values($dom, '/role/permissions', 'inherit'); 236 if (isset($values)) { 237 foreach ($values as $value) { 238 if ($value = clean_param($value, PARAM_CAPABILITY)) { 239 $info['permissions'][$value] = CAP_INHERIT; 240 } 241 } 242 } 243 $values = self::get_node_children_values($dom, '/role/permissions', 'allow'); 244 if (isset($values)) { 245 foreach ($values as $value) { 246 if ($value = clean_param($value, PARAM_CAPABILITY)) { 247 $info['permissions'][$value] = CAP_ALLOW; 248 } 249 } 250 } 251 $values = self::get_node_children_values($dom, '/role/permissions', 'prevent'); 252 if (isset($values)) { 253 foreach ($values as $value) { 254 if ($value = clean_param($value, PARAM_CAPABILITY)) { 255 $info['permissions'][$value] = CAP_PREVENT; 256 } 257 } 258 } 259 $values = self::get_node_children_values($dom, '/role/permissions', 'prohibit'); 260 if (isset($values)) { 261 foreach ($values as $value) { 262 if ($value = clean_param($value, PARAM_CAPABILITY)) { 263 $info['permissions'][$value] = CAP_PROHIBIT; 264 } 265 } 266 } 267 268 return $info; 269 } 270 271 protected static function get_node(DOMDocument $dom, $path) { 272 $parts = explode('/', $path); 273 $elname = end($parts); 274 275 $nodes = $dom->getElementsByTagName($elname); 276 277 if ($nodes->length == 0) { 278 return null; 279 } 280 281 foreach ($nodes as $node) { 282 if ($node->getNodePath() === $path) { 283 return $node; 284 } 285 } 286 287 return null; 288 } 289 290 protected static function get_node_value(DOMDocument $dom, $path) { 291 if (!$node = self::get_node($dom, $path)) { 292 return null; 293 } 294 return $node->nodeValue; 295 } 296 297 protected static function get_node_children(DOMDocument $dom, $path, $tagname) { 298 if (!$node = self::get_node($dom, $path)) { 299 return null; 300 } 301 302 $return = array(); 303 foreach ($node->childNodes as $child) { 304 if ($child->nodeName === $tagname) { 305 $return[] = $child; 306 } 307 } 308 return $return; 309 } 310 311 protected static function get_node_children_values(DOMDocument $dom, $path, $tagname) { 312 $children = self::get_node_children($dom, $path, $tagname); 313 314 if ($children === null) { 315 return null; 316 } 317 $return = array(); 318 foreach ($children as $child) { 319 $return[] = $child->nodeValue; 320 } 321 return $return; 322 } 323 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body