a4e10845 |
1 | <?php |
88a7228a |
2 | |
3 | /** |
4 | * adminlib.php - Contains functions that only administrators will ever need to use |
5 | * |
a4e10845 |
6 | * @author Martin Dougiamas and many others |
88a7228a |
7 | * @version $Id$ |
8 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
9 | * @package moodlecore |
10 | */ |
11 | |
12 | /** |
ead29342 |
13 | * Upgrade plugins |
88a7228a |
14 | * |
15 | * @uses $db |
16 | * @uses $CFG |
ead29342 |
17 | * @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype') |
18 | * @param string $dir The directory where the plugins are located (e.g. 'question/questiontypes') |
19 | * @param string $return The url to prompt the user to continue to |
eef868d1 |
20 | */ |
ead29342 |
21 | function upgrade_plugins($type, $dir, $return) { |
e69ef14b |
22 | global $CFG, $db; |
173cc1c3 |
23 | |
ead29342 |
24 | if (!$plugs = get_list_of_plugins($dir) ) { |
25 | error('No '.$type.' plugins installed!'); |
173cc1c3 |
26 | } |
27 | |
583fad99 |
28 | $updated_plugins = false; |
29 | $strpluginsetup = get_string('pluginsetup'); |
30 | |
ead29342 |
31 | foreach ($plugs as $plug) { |
173cc1c3 |
32 | |
ead29342 |
33 | $fullplug = $CFG->dirroot .'/'.$dir.'/'. $plug; |
173cc1c3 |
34 | |
ead29342 |
35 | unset($plugin); |
173cc1c3 |
36 | |
bbbf2d40 |
37 | if (is_readable($fullplug .'/version.php')) { |
ead29342 |
38 | include_once($fullplug .'/version.php'); // defines $plugin with version etc |
173cc1c3 |
39 | } else { |
40 | continue; // Nothing to do. |
41 | } |
42 | |
e79a09a2 |
43 | $oldupgrade = false; |
44 | $newupgrade = false; |
7c006e34 |
45 | if (is_readable($fullplug . '/db/'. $CFG->dbtype . '.php')) { |
46 | include_once($fullplug . '/db/'. $CFG->dbtype . '.php'); // defines old upgrading function |
e79a09a2 |
47 | $oldupgrade = true; |
48 | } |
db8bd7a6 |
49 | if (is_readable($fullplug . '/db/upgrade.php')) { |
7c006e34 |
50 | include_once($fullplug . '/db/upgrade.php'); // defines new upgrading function |
e79a09a2 |
51 | $newupgrade = true; |
52 | } |
53 | |
ead29342 |
54 | if (!isset($plugin)) { |
173cc1c3 |
55 | continue; |
56 | } |
57 | |
ead29342 |
58 | if (!empty($plugin->requires)) { |
59 | if ($plugin->requires > $CFG->version) { |
acdd790f |
60 | $info = new object(); |
ead29342 |
61 | $info->pluginname = $plug; |
62 | $info->pluginversion = $plugin->version; |
173cc1c3 |
63 | $info->currentmoodle = $CFG->version; |
ead29342 |
64 | $info->requiremoodle = $plugin->requires; |
583fad99 |
65 | if (!$updated_plugins) { |
eef868d1 |
66 | print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '', |
371a32e3 |
67 | upgrade_get_javascript(), false, ' ', ' '); |
583fad99 |
68 | } |
69 | upgrade_log_start(); |
ead29342 |
70 | notify(get_string('pluginrequirementsnotmet', 'error', $info)); |
583fad99 |
71 | $updated_plugins = true; |
173cc1c3 |
72 | continue; |
73 | } |
74 | } |
75 | |
ead29342 |
76 | $plugin->name = $plug; // The name MUST match the directory |
173cc1c3 |
77 | |
ead29342 |
78 | $pluginversion = $type.'_'.$plug.'_version'; |
173cc1c3 |
79 | |
ead29342 |
80 | if (!isset($CFG->$pluginversion)) { |
81 | set_config($pluginversion, 0); |
173cc1c3 |
82 | } |
eef868d1 |
83 | |
ead29342 |
84 | if ($CFG->$pluginversion == $plugin->version) { |
173cc1c3 |
85 | // do nothing |
ead29342 |
86 | } else if ($CFG->$pluginversion < $plugin->version) { |
583fad99 |
87 | if (!$updated_plugins) { |
eef868d1 |
88 | print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '', |
371a32e3 |
89 | upgrade_get_javascript(), false, ' ', ' '); |
173cc1c3 |
90 | } |
e79a09a2 |
91 | $updated_plugins = true; |
583fad99 |
92 | upgrade_log_start(); |
ead29342 |
93 | print_heading($plugin->name .' plugin needs upgrading'); |
e79a09a2 |
94 | $db->debug = true; |
95 | @set_time_limit(0); // To allow slow databases to complete the long SQL |
96 | |
d87a9d73 |
97 | if ($CFG->$pluginversion == 0) { // It's a new install of this plugin |
e79a09a2 |
98 | /// Both old .sql files and new install.xml are supported |
99 | /// but we priorize install.xml (XMLDB) if present |
100 | $status = false; |
db8bd7a6 |
101 | if (file_exists($fullplug . '/db/install.xml')) { |
450cf307 |
102 | $status = install_from_xmldb_file($fullplug . '/db/install.xml'); //New method |
e79a09a2 |
103 | } else if (file_exists($fullplug .'/db/'. $CFG->dbtype .'.sql')) { |
104 | $status = modify_database($fullplug .'/db/'. $CFG->dbtype .'.sql'); //Old method |
eef868d1 |
105 | } else { |
7c006e34 |
106 | $status = true; |
d87a9d73 |
107 | } |
e79a09a2 |
108 | |
109 | $db->debug = false; |
eef868d1 |
110 | /// Continue with the instalation, roles and other stuff |
e79a09a2 |
111 | if ($status) { |
112 | // OK so far, now update the plugins record |
113 | set_config($pluginversion, $plugin->version); |
ae628043 |
114 | if (!update_capabilities($type.'/'.$plug)) { |
e79a09a2 |
115 | error('Could not set up the capabilities for '.$module->name.'!'); |
116 | } |
117 | notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess'); |
118 | } else { |
119 | notify('Installing '. $plugin->name .' FAILED!'); |
120 | } |
d87a9d73 |
121 | } else { // Upgrade existing install |
e79a09a2 |
122 | /// Run de old and new upgrade functions for the module |
123 | $oldupgrade_function = $type.'_'.$plugin->name .'_upgrade'; |
124 | $newupgrade_function = 'xmldb_' . $type.'_'.$plugin->name .'_upgrade'; |
125 | |
126 | /// First, the old function if exists |
127 | $oldupgrade_status = true; |
128 | if ($oldupgrade && function_exists($oldupgrade_function)) { |
129 | $db->debug = true; |
130 | $oldupgrade_status = $oldupgrade_function($CFG->$pluginversion); |
131 | } else if ($oldupgrade) { |
132 | notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' . |
133 | $fullplug . '/db/' . $CFG->dbtype . '.php'); |
134 | } |
135 | |
136 | /// Then, the new function if exists and the old one was ok |
137 | $newupgrade_status = true; |
138 | if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) { |
139 | $db->debug = true; |
140 | $newupgrade_status = $newupgrade_function($CFG->$pluginversion); |
141 | } else if ($newupgrade) { |
142 | notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' . |
143 | $fullplug . '/db/upgrade.php'); |
144 | } |
145 | |
146 | $db->debug=false; |
147 | /// Now analyze upgrade results |
148 | if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed |
149 | // OK so far, now update the plugins record |
150 | set_config($pluginversion, $plugin->version); |
ae628043 |
151 | if (!update_capabilities($type.'/'.$plug)) { |
e79a09a2 |
152 | error('Could not update '.$plugin->name.' capabilities!'); |
d87a9d73 |
153 | } |
e79a09a2 |
154 | notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess'); |
155 | } else { |
156 | notify('Upgrading '. $plugin->name .' from '. $CFG->$pluginversion .' to '. $plugin->version .' FAILED!'); |
173cc1c3 |
157 | } |
158 | } |
d87a9d73 |
159 | echo '<hr />'; |
173cc1c3 |
160 | } else { |
583fad99 |
161 | upgrade_log_start(); |
ead29342 |
162 | error('Version mismatch: '. $plugin->name .' can\'t downgrade '. $CFG->$pluginversion .' -> '. $plugin->version .' !'); |
173cc1c3 |
163 | } |
164 | } |
165 | |
583fad99 |
166 | upgrade_log_finish(); |
167 | |
168 | if ($updated_plugins) { |
173cc1c3 |
169 | print_continue($return); |
acdd790f |
170 | print_footer('none'); |
173cc1c3 |
171 | die; |
172 | } |
173 | } |
174 | |
88a7228a |
175 | /** |
176 | * Find and check all modules and load them up or upgrade them if necessary |
177 | * |
178 | * @uses $db |
179 | * @uses $CFG |
180 | * @param string $return The url to prompt the user to continue to |
181 | * @todo Finish documenting this function |
eef868d1 |
182 | */ |
173cc1c3 |
183 | function upgrade_activity_modules($return) { |
173cc1c3 |
184 | |
e69ef14b |
185 | global $CFG, $db; |
173cc1c3 |
186 | |
88a7228a |
187 | if (!$mods = get_list_of_plugins('mod') ) { |
188 | error('No modules installed!'); |
173cc1c3 |
189 | } |
190 | |
583fad99 |
191 | $updated_modules = false; |
192 | $strmodulesetup = get_string('modulesetup'); |
193 | |
173cc1c3 |
194 | foreach ($mods as $mod) { |
195 | |
88a7228a |
196 | if ($mod == 'NEWMODULE') { // Someone has unzipped the template, ignore it |
173cc1c3 |
197 | continue; |
198 | } |
199 | |
88a7228a |
200 | $fullmod = $CFG->dirroot .'/mod/'. $mod; |
173cc1c3 |
201 | |
202 | unset($module); |
203 | |
88a7228a |
204 | if ( is_readable($fullmod .'/version.php')) { |
205 | include_once($fullmod .'/version.php'); // defines $module with version etc |
173cc1c3 |
206 | } else { |
88a7228a |
207 | notify('Module '. $mod .': '. $fullmod .'/version.php was not readable'); |
173cc1c3 |
208 | continue; |
209 | } |
210 | |
d6eb06b6 |
211 | $oldupgrade = false; |
212 | $newupgrade = false; |
7c006e34 |
213 | if ( is_readable($fullmod .'/db/' . $CFG->dbtype . '.php')) { |
214 | include_once($fullmod .'/db/' . $CFG->dbtype . '.php'); // defines old upgrading function |
d6eb06b6 |
215 | $oldupgrade = true; |
216 | } |
db8bd7a6 |
217 | if ( is_readable($fullmod . '/db/upgrade.php')) { |
7c006e34 |
218 | include_once($fullmod . '/db/upgrade.php'); // defines new upgrading function |
d6eb06b6 |
219 | $newupgrade = true; |
173cc1c3 |
220 | } |
221 | |
222 | if (!isset($module)) { |
223 | continue; |
224 | } |
225 | |
226 | if (!empty($module->requires)) { |
227 | if ($module->requires > $CFG->version) { |
acdd790f |
228 | $info = new object(); |
173cc1c3 |
229 | $info->modulename = $mod; |
230 | $info->moduleversion = $module->version; |
231 | $info->currentmoodle = $CFG->version; |
232 | $info->requiremoodle = $module->requires; |
583fad99 |
233 | if (!$updated_modules) { |
eef868d1 |
234 | print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', |
371a32e3 |
235 | upgrade_get_javascript(), false, ' ', ' '); |
583fad99 |
236 | } |
237 | upgrade_log_start(); |
173cc1c3 |
238 | notify(get_string('modulerequirementsnotmet', 'error', $info)); |
583fad99 |
239 | $updated_modules = true; |
173cc1c3 |
240 | continue; |
241 | } |
242 | } |
243 | |
244 | $module->name = $mod; // The name MUST match the directory |
eef868d1 |
245 | |
88a7228a |
246 | if ($currmodule = get_record('modules', 'name', $module->name)) { |
173cc1c3 |
247 | if ($currmodule->version == $module->version) { |
248 | // do nothing |
249 | } else if ($currmodule->version < $module->version) { |
d6eb06b6 |
250 | /// If versions say that we need to upgrade but no upgrade files are available, notify and continue |
251 | if (!$oldupgrade && !$newupgrade) { |
252 | notify('Upgrade files ' . $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php or ' . |
253 | $fullmod . '/db/upgrade.php were not readable'); |
254 | continue; |
255 | } |
583fad99 |
256 | if (!$updated_modules) { |
eef868d1 |
257 | print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', |
371a32e3 |
258 | upgrade_get_javascript(), false, ' ', ' '); |
173cc1c3 |
259 | } |
583fad99 |
260 | upgrade_log_start(); |
88a7228a |
261 | print_heading($module->name .' module needs upgrading'); |
d6eb06b6 |
262 | |
263 | /// Run de old and new upgrade functions for the module |
264 | $oldupgrade_function = $module->name . '_upgrade'; |
265 | $newupgrade_function = 'xmldb_' . $module->name . '_upgrade'; |
266 | |
267 | /// First, the old function if exists |
268 | $oldupgrade_status = true; |
269 | if ($oldupgrade && function_exists($oldupgrade_function)) { |
270 | $db->debug = true; |
271 | $oldupgrade_status = $oldupgrade_function($currmodule->version, $module); |
ba05965e |
272 | } else if ($oldupgrade) { |
d6eb06b6 |
273 | notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' . |
274 | $mod . ': ' . $fullmod . '/db/' . $CFG->dbtype . '.php'); |
d6eb06b6 |
275 | } |
276 | |
277 | /// Then, the new function if exists and the old one was ok |
278 | $newupgrade_status = true; |
ba05965e |
279 | if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) { |
d6eb06b6 |
280 | $db->debug = true; |
281 | $newupgrade_status = $newupgrade_function($currmodule->version, $module); |
ba05965e |
282 | } else if ($newupgrade) { |
d6eb06b6 |
283 | notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' . |
284 | $mod . ': ' . $fullmod . '/db/upgrade.php'); |
d6eb06b6 |
285 | } |
286 | |
e79a09a2 |
287 | $db->debug=false; |
d6eb06b6 |
288 | /// Now analyze upgrade results |
668896e5 |
289 | if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed |
d6eb06b6 |
290 | // OK so far, now update the modules record |
291 | $module->id = $currmodule->id; |
292 | if (! update_record('modules', $module)) { |
293 | error('Could not update '. $module->name .' record in modules table!'); |
173cc1c3 |
294 | } |
d6eb06b6 |
295 | remove_dir($CFG->dataroot . '/cache', true); // flush cache |
296 | notify(get_string('modulesuccess', '', $module->name), 'notifysuccess'); |
297 | echo '<hr />'; |
298 | } else { |
d6eb06b6 |
299 | notify('Upgrading '. $module->name .' from '. $currmodule->version .' to '. $module->version .' FAILED!'); |
173cc1c3 |
300 | } |
bbbf2d40 |
301 | |
d6eb06b6 |
302 | /// Update the capabilities table? |
bbbf2d40 |
303 | if (!update_capabilities('mod/'.$module->name)) { |
304 | error('Could not update '.$module->name.' capabilities!'); |
305 | } |
306 | |
173cc1c3 |
307 | $updated_modules = true; |
eef868d1 |
308 | |
173cc1c3 |
309 | } else { |
583fad99 |
310 | upgrade_log_start(); |
88a7228a |
311 | error('Version mismatch: '. $module->name .' can\'t downgrade '. $currmodule->version .' -> '. $module->version .' !'); |
173cc1c3 |
312 | } |
eef868d1 |
313 | |
173cc1c3 |
314 | } else { // module not installed yet, so install it |
583fad99 |
315 | if (!$updated_modules) { |
eef868d1 |
316 | print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', |
371a32e3 |
317 | upgrade_get_javascript(), false, ' ', ' '); |
173cc1c3 |
318 | } |
583fad99 |
319 | upgrade_log_start(); |
173cc1c3 |
320 | print_heading($module->name); |
321 | $updated_modules = true; |
322 | $db->debug = true; |
323 | @set_time_limit(0); // To allow slow databases to complete the long SQL |
d6eb06b6 |
324 | |
325 | /// Both old .sql files and new install.xml are supported |
326 | /// but we priorize install.xml (XMLDB) if present |
db8bd7a6 |
327 | if (file_exists($fullmod . '/db/install.xml')) { |
d6eb06b6 |
328 | $status = install_from_xmldb_file($fullmod . '/db/install.xml'); //New method |
329 | } else { |
330 | $status = modify_database($fullmod .'/db/'. $CFG->dbtype .'.sql'); //Old method |
331 | } |
332 | |
e79a09a2 |
333 | $db->debug = false; |
d6eb06b6 |
334 | /// Continue with the instalation, roles and other stuff |
335 | if ($status) { |
88a7228a |
336 | if ($module->id = insert_record('modules', $module)) { |
bbbf2d40 |
337 | if (!update_capabilities('mod/'.$module->name)) { |
338 | error('Could not set up the capabilities for '.$module->name.'!'); |
339 | } |
a8f68426 |
340 | notify(get_string('modulesuccess', '', $module->name), 'notifysuccess'); |
88a7228a |
341 | echo '<hr />'; |
173cc1c3 |
342 | } else { |
88a7228a |
343 | error($module->name .' module could not be added to the module list!'); |
173cc1c3 |
344 | } |
eef868d1 |
345 | } else { |
88a7228a |
346 | error($module->name .' tables could NOT be set up successfully!'); |
173cc1c3 |
347 | } |
348 | } |
e5bd4e58 |
349 | |
350 | /// Check submodules of this module if necessary |
351 | |
352 | include_once($fullmod.'/lib.php'); // defines upgrading function |
353 | |
354 | $submoduleupgrade = $module->name.'_upgrade_submodules'; |
355 | if (function_exists($submoduleupgrade)) { |
356 | $submoduleupgrade(); |
357 | } |
358 | |
359 | |
360 | /// Run any defaults or final code that is necessary for this module |
361 | |
a5c0990e |
362 | if ( is_readable($fullmod .'/defaults.php')) { |
363 | // Insert default values for any important configuration variables |
9e6e7502 |
364 | unset($defaults); |
eef868d1 |
365 | include_once($fullmod .'/defaults.php'); |
f9a2e515 |
366 | if (!empty($defaults)) { |
367 | foreach ($defaults as $name => $value) { |
368 | if (!isset($CFG->$name)) { |
369 | set_config($name, $value); |
370 | } |
a5c0990e |
371 | } |
372 | } |
373 | } |
173cc1c3 |
374 | } |
375 | |
583fad99 |
376 | upgrade_log_finish(); // finish logging if started |
377 | |
378 | if ($updated_modules) { |
173cc1c3 |
379 | print_continue($return); |
acdd790f |
380 | print_footer('none'); |
173cc1c3 |
381 | die; |
382 | } |
383 | } |
384 | |
eef868d1 |
385 | /** |
f3221af9 |
386 | * This function will return FALSE if the lock fails to be set (ie, if it's already locked) |
80be7ee3 |
387 | * |
388 | * @param string $name ? |
389 | * @param bool $value ? |
390 | * @param int $staleafter ? |
391 | * @param bool $clobberstale ? |
392 | * @todo Finish documenting this function |
f3221af9 |
393 | */ |
394 | function set_cron_lock($name,$value=true,$staleafter=7200,$clobberstale=false) { |
395 | |
396 | if (empty($name)) { |
397 | mtrace("Tried to get a cron lock for a null fieldname"); |
398 | return false; |
399 | } |
400 | |
401 | if (empty($value)) { |
402 | set_config($name,0); |
403 | return true; |
404 | } |
405 | |
406 | if ($config = get_record('config','name',$name)) { |
407 | if (empty($config->value)) { |
408 | set_config($name,time()); |
409 | } else { |
410 | // check for stale. |
411 | if ((time() - $staleafter) > $config->value) { |
412 | mtrace("STALE LOCKFILE FOR $name - was $config->value"); |
413 | if (!empty($clobberstale)) { |
414 | set_config($name,time()); |
415 | return true; |
416 | } |
417 | } else { |
418 | return false; // was not stale - ie, we're ok to still be running. |
419 | } |
420 | } |
421 | } |
422 | else { |
423 | set_config($name,time()); |
424 | } |
425 | return true; |
426 | } |
a597f8a8 |
427 | |
fb06b255 |
428 | function print_progress($done, $total, $updatetime=5, $sleeptime=1, $donetext='') { |
a597f8a8 |
429 | static $starttime; |
430 | static $lasttime; |
431 | |
26ea4888 |
432 | if ($total < 2) { // No need to show anything |
433 | return; |
434 | } |
435 | |
a597f8a8 |
436 | if (empty($starttime)) { |
437 | $starttime = $lasttime = time(); |
438 | $lasttime = $starttime - $updatetime; |
439 | echo '<table width="500" cellpadding="0" cellspacing="0" align="center"><tr><td width="500">'; |
72da5046 |
440 | echo '<div id="bar'.$total.'" style="border-style:solid;border-width:1px;width:500px;height:50px;">'; |
441 | echo '<div id="slider'.$total.'" style="border-style:solid;border-width:1px;height:48px;width:10px;background-color:green;"></div>'; |
a597f8a8 |
442 | echo '</div>'; |
72da5046 |
443 | echo '<div id="text'.$total.'" align="center" style="width:500px;"></div>'; |
a597f8a8 |
444 | echo '</td></tr></table>'; |
445 | echo '</div>'; |
446 | } |
447 | |
a597f8a8 |
448 | $now = time(); |
449 | |
450 | if ($done && (($now - $lasttime) >= $updatetime)) { |
451 | $elapsedtime = $now - $starttime; |
452 | $projectedtime = (int)(((float)$total / (float)$done) * $elapsedtime) - $elapsedtime; |
453 | $percentage = format_float((float)$done / (float)$total, 2); |
454 | $width = (int)(500 * $percentage); |
455 | |
fb06b255 |
456 | if ($projectedtime > 10) { |
457 | $projectedtext = ' Ending: '.format_time($projectedtime); |
458 | } else { |
459 | $projectedtext = ''; |
460 | } |
461 | |
a597f8a8 |
462 | echo '<script>'; |
aae37b63 |
463 | echo 'document.getElementById("text'.$total.'").innerHTML = "'.addslashes($donetext).' ('.$done.'/'.$total.') '.$projectedtext.'";'."\n"; |
464 | echo 'document.getElementById("slider'.$total.'").style.width = \''.$width.'px\';'."\n"; |
a597f8a8 |
465 | echo '</script>'; |
466 | |
467 | $lasttime = $now; |
468 | sleep($sleeptime); |
469 | } |
470 | } |
583fad99 |
471 | |
371a32e3 |
472 | function upgrade_get_javascript() { |
473 | global $CFG; |
474 | |
475 | if (!empty($_SESSION['installautopilot'])) { |
476 | $linktoscrolltoerrors = '<script type="text/javascript">var installautopilot = true;</script>'."\n"; |
477 | } else { |
478 | $linktoscrolltoerrors = '<script type="text/javascript">var installautopilot = false;</script>'."\n"; |
479 | } |
480 | $linktoscrolltoerrors .= '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>'; |
481 | |
482 | return $linktoscrolltoerrors; |
483 | } |
ad6226fb |
484 | |
485 | function create_admin_user() { |
486 | global $CFG, $USER; |
487 | |
488 | if (empty($CFG->rolesactive)) { // No admin user yet. |
489 | |
490 | $user = new object(); |
491 | $user->auth = 'manual'; |
492 | $user->firstname = get_string('admin'); |
493 | $user->lastname = get_string('user'); |
494 | $user->username = 'admin'; |
495 | $user->password = hash_internal_user_password('admin'); |
496 | $user->email = 'root@localhost'; |
497 | $user->confirmed = 1; |
498 | $user->mnethostid = $CFG->mnet_localhost_id; |
499 | $user->lang = $CFG->lang; |
500 | $user->maildisplay = 1; |
501 | $user->timemodified = time(); |
502 | |
503 | if (!$user->id = insert_record('user', $user)) { |
504 | error('SERIOUS ERROR: Could not create admin user record !!!'); |
505 | } |
506 | |
507 | if (!$user = get_record('user', 'id', $user->id)) { // Double check. |
508 | error('User ID was incorrect (can\'t find it)'); |
509 | } |
510 | |
511 | // Assign the default admin roles to the new user. |
512 | if (!$adminroles = get_roles_with_capability('moodle/legacy:admin', CAP_ALLOW)) { |
513 | error('No admin role could be found'); |
514 | } |
84c8ede0 |
515 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); |
ad6226fb |
516 | foreach ($adminroles as $adminrole) { |
517 | role_assign($adminrole->id, $user->id, 0, $sitecontext->id); |
518 | } |
519 | |
520 | set_config('rolesactive', 1); |
521 | |
522 | // Log the user in. |
523 | $USER = get_complete_user_data('username', 'admin'); |
524 | $USER->newadminuser = 1; |
525 | load_all_capabilities(); |
526 | |
527 | redirect("$CFG->wwwroot/user/editadvanced.php?id=$user->id"); // Edit thyself |
528 | } else { |
529 | error('Can not create admin!'); |
530 | } |
531 | } |
532 | |
583fad99 |
533 | //////////////////////////////////////////////// |
534 | /// upgrade logging functions |
535 | //////////////////////////////////////////////// |
536 | |
537 | $upgradeloghandle = false; |
26c91c73 |
538 | $upgradelogbuffer = ''; |
539 | // I did not find out how to use static variable in callback function, |
540 | // the problem was that I could not flush the static buffer :-( |
541 | global $upgradeloghandle, $upgradelogbuffer; |
583fad99 |
542 | |
543 | /** |
544 | * Check if upgrade is already running. |
545 | * |
546 | * If anything goes wrong due to missing call to upgrade_log_finish() |
547 | * just restart the browser. |
548 | * |
549 | * @param string warning message indicating upgrade is already running |
550 | * @param int page reload timeout |
551 | */ |
552 | function upgrade_check_running($message, $timeout) { |
553 | if (!empty($_SESSION['upgraderunning'])) { |
554 | print_header(); |
555 | redirect(me(), $message, $timeout); |
556 | } |
557 | } |
558 | |
559 | /** |
560 | * Start logging of output into file (if not disabled) and |
561 | * prevent aborting and concurrent execution of upgrade script. |
562 | * |
563 | * Please note that you can not write into session variables after calling this function! |
564 | * |
565 | * This function may be called repeatedly. |
566 | */ |
567 | function upgrade_log_start() { |
426a369b |
568 | global $CFG, $upgradeloghandle; |
583fad99 |
569 | |
570 | if (!empty($_SESSION['upgraderunning'])) { |
571 | return; // logging already started |
572 | } |
573 | |
574 | @ignore_user_abort(true); // ignore if user stops or otherwise aborts page loading |
575 | $_SESSION['upgraderunning'] = 1; // set upgrade indicator |
426a369b |
576 | if (empty($CFG->dbsessions)) { // workaround for bug in adodb, db session can not be restarted |
577 | session_write_close(); // from now on user can reload page - will be displayed warning |
578 | } |
583fad99 |
579 | make_upload_directory('upgradelogs'); |
580 | ob_start('upgrade_log_callback', 2); // function for logging to disk; flush each line of text ASAP |
dedb2304 |
581 | register_shutdown_function('upgrade_log_finish'); // in case somebody forgets to stop logging |
583fad99 |
582 | } |
583 | |
584 | /** |
585 | * Terminate logging of output, flush all data, allow script aborting |
586 | * and reopen session for writing. Function error() does terminate the logging too. |
587 | * |
588 | * Please make sure that each upgrade_log_start() is properly terminated by |
589 | * this function or error(). |
590 | * |
591 | * This function may be called repeatedly. |
592 | */ |
593 | function upgrade_log_finish() { |
426a369b |
594 | global $CFG, $upgradeloghandle, $upgradelogbuffer; |
583fad99 |
595 | |
596 | if (empty($_SESSION['upgraderunning'])) { |
597 | return; // logging already terminated |
598 | } |
599 | |
600 | @ob_end_flush(); |
26c91c73 |
601 | if ($upgradelogbuffer !== '') { |
602 | @fwrite($upgradeloghandle, $upgradelogbuffer); |
40896537 |
603 | $upgradelogbuffer = ''; |
26c91c73 |
604 | } |
605 | if ($upgradeloghandle and ($upgradeloghandle !== 'error')) { |
606 | @fclose($upgradeloghandle); |
40896537 |
607 | $upgradeloghandle = false; |
26c91c73 |
608 | } |
426a369b |
609 | if (empty($CFG->dbsessions)) { |
610 | @session_start(); // ignore header errors, we only need to reopen session |
611 | } |
583fad99 |
612 | $_SESSION['upgraderunning'] = 0; // clear upgrade indicator |
613 | if (connection_aborted()) { |
614 | die; |
615 | } |
616 | @ignore_user_abort(false); |
617 | } |
618 | |
619 | /** |
620 | * Callback function for logging into files. Not more than one file is created per minute, |
621 | * upgrade session (terminated by upgrade_log_finish()) is always stored in one file. |
622 | * |
623 | * This function must not output any characters or throw warnigns and errors! |
624 | */ |
625 | function upgrade_log_callback($string) { |
26c91c73 |
626 | global $CFG, $upgradeloghandle, $upgradelogbuffer; |
583fad99 |
627 | |
628 | if (empty($CFG->disableupgradelogging) and ($string != '') and ($upgradeloghandle !== 'error')) { |
629 | if ($upgradeloghandle or ($upgradeloghandle = @fopen($CFG->dataroot.'/upgradelogs/upg_'.date('Ymd-Hi').'.html', 'a'))) { |
26c91c73 |
630 | $upgradelogbuffer .= $string; |
631 | if (strlen($upgradelogbuffer) > 2048) { // 2kB write buffer |
632 | @fwrite($upgradeloghandle, $upgradelogbuffer); |
633 | $upgradelogbuffer = ''; |
634 | } |
583fad99 |
635 | } else { |
636 | $upgradeloghandle = 'error'; |
637 | } |
638 | } |
639 | return $string; |
640 | } |
641 | |
57e35f32 |
642 | /** |
643 | * Try to verify that dataroot is not accessible from web. |
644 | * It is not 100% correct but might help to reduce number of vulnerable sites. |
645 | * |
646 | * Protection from httpd.conf and .htaccess is not detected properly. |
647 | */ |
648 | function is_dataroot_insecure() { |
649 | global $CFG; |
650 | |
651 | $siteroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); // win32 backslash workaround |
652 | |
653 | $rp = preg_replace('|https?://[^/]+|i', '', $CFG->wwwroot, 1); |
654 | $rp = strrev(trim($rp, '/')); |
655 | $rp = explode('/', $rp); |
656 | foreach($rp as $r) { |
657 | if (strpos($siteroot, '/'.$r.'/') === 0) { |
658 | $siteroot = substr($siteroot, strlen($r)+1); // moodle web in subdirectory |
659 | } else { |
660 | break; // probably alias root |
661 | } |
662 | } |
663 | |
664 | $siteroot = strrev($siteroot); |
665 | $dataroot = str_replace('\\', '/', $CFG->dataroot.'/'); |
666 | |
667 | if (strpos($dataroot, $siteroot) === 0) { |
668 | return true; |
669 | } |
670 | return false; |
671 | } |
6e4dc10f |
672 | |
673 | /// ============================================================================================================= |
674 | /// administration tree classes and functions |
675 | |
676 | |
677 | // n.b. documentation is still in progress for this code |
678 | |
679 | /// INTRODUCTION |
680 | |
681 | /// This file performs the following tasks: |
682 | /// -it defines the necessary objects and interfaces to build the Moodle |
683 | /// admin hierarchy |
eef868d1 |
684 | /// -it defines the admin_externalpage_setup(), admin_externalpage_print_header(), |
6e4dc10f |
685 | /// and admin_externalpage_print_footer() functions used on admin pages |
686 | |
687 | /// ADMIN_SETTING OBJECTS |
688 | |
eef868d1 |
689 | /// Moodle settings are represented by objects that inherit from the admin_setting |
6e4dc10f |
690 | /// class. These objects encapsulate how to read a setting, how to write a new value |
691 | /// to a setting, and how to appropriately display the HTML to modify the setting. |
692 | |
693 | /// ADMIN_SETTINGPAGE OBJECTS |
694 | |
695 | /// The admin_setting objects are then grouped into admin_settingpages. The latter |
696 | /// appear in the Moodle admin tree block. All interaction with admin_settingpage |
697 | /// objects is handled by the admin/settings.php file. |
698 | |
699 | /// ADMIN_EXTERNALPAGE OBJECTS |
700 | |
701 | /// There are some settings in Moodle that are too complex to (efficiently) handle |
702 | /// with admin_settingpages. (Consider, for example, user management and displaying |
703 | /// lists of users.) In this case, we use the admin_externalpage object. This object |
704 | /// places a link to an external PHP file in the admin tree block. |
705 | |
706 | /// If you're using an admin_externalpage object for some settings, you can take |
707 | /// advantage of the admin_externalpage_* functions. For example, suppose you wanted |
708 | /// to add a foo.php file into admin. First off, you add the following line to |
709 | /// admin/settings/first.php (at the end of the file) or to some other file in |
710 | /// admin/settings: |
711 | |
eef868d1 |
712 | /// $ADMIN->add('userinterface', new admin_externalpage('foo', get_string('foo'), |
6e4dc10f |
713 | /// $CFG->wwwdir . '/' . '$CFG->admin . '/foo.php', 'some_role_permission')); |
714 | |
715 | /// Next, in foo.php, your file structure would resemble the following: |
716 | |
717 | /// require_once('.../config.php'); |
718 | /// require_once($CFG->libdir.'/adminlib.php'); |
719 | /// $adminroot = admin_get_root(); |
720 | /// admin_externalpage_setup('foo', $adminroot); |
721 | /// // functionality like processing form submissions goes here |
722 | /// admin_externalpage_print_header($adminroot); |
723 | /// // your HTML goes here |
724 | /// admin_externalpage_print_footer($adminroot); |
725 | |
726 | /// The admin_externalpage_setup() function call ensures the user is logged in, |
727 | /// and makes sure that they have the proper role permission to access the page. |
728 | |
729 | /// The admin_externalpage_print_header() function prints the header (it figures |
730 | /// out what category and subcategories the page is classified under) and ensures |
731 | /// that you're using the admin pagelib (which provides the admin tree block and |
732 | /// the admin bookmarks block). |
733 | |
734 | /// The admin_externalpage_print_footer() function properly closes the tables |
735 | /// opened up by the admin_externalpage_print_header() function and prints the |
736 | /// standard Moodle footer. |
737 | |
738 | /// ADMIN_CATEGORY OBJECTS |
739 | |
740 | /// Above and beyond all this, we have admin_category objects. These objects |
741 | /// appear as folders in the admin tree block. They contain admin_settingpage's, |
742 | /// admin_externalpage's, and other admin_category's. |
743 | |
744 | /// OTHER NOTES |
745 | |
746 | /// admin_settingpage's, admin_externalpage's, and admin_category's all inherit |
747 | /// from part_of_admin_tree (a pseudointerface). This interface insists that |
748 | /// a class has a check_access method for access permissions, a locate method |
749 | /// used to find a specific node in the admin tree, and a path method used |
750 | /// to determine the path to a specific node in the $ADMIN tree. |
751 | |
752 | /// admin_category's inherit from parentable_part_of_admin_tree. This pseudo- |
753 | /// interface ensures that the class implements a recursive add function which |
754 | /// accepts a part_of_admin_tree object and searches for the proper place to |
755 | /// put it. parentable_part_of_admin_tree implies part_of_admin_tree. |
756 | |
757 | /// Please note that the $this->name field of any part_of_admin_tree must be |
758 | /// UNIQUE throughout the ENTIRE admin tree. |
759 | |
760 | /// The $this->name field of an admin_setting object (which is *not* part_of_ |
761 | /// admin_tree) must be unique on the respective admin_settingpage where it is |
762 | /// used. |
763 | |
764 | |
765 | /// MISCELLANEOUS STUFF (used by classes defined below) /////////////////////// |
766 | include_once($CFG->dirroot . '/backup/lib.php'); |
767 | |
768 | /// CLASS DEFINITIONS ///////////////////////////////////////////////////////// |
769 | |
770 | /** |
771 | * Pseudointerface for anything appearing in the admin tree |
772 | * |
773 | * The pseudointerface that is implemented by anything that appears in the admin tree |
774 | * block. It forces inheriting classes to define a method for checking user permissions |
775 | * and methods for finding something in the admin tree. |
776 | * |
777 | * @author Vincenzo K. Marcovecchio |
778 | * @package admin |
779 | */ |
780 | class part_of_admin_tree { |
781 | |
782 | /** |
783 | * Finds a named part_of_admin_tree. |
784 | * |
785 | * Used to find a part_of_admin_tree. If a class only inherits part_of_admin_tree |
786 | * and not parentable_part_of_admin_tree, then this function should only check if |
787 | * $this->name matches $name. If it does, it should return a reference to $this, |
788 | * otherwise, it should return a reference to NULL. |
789 | * |
790 | * If a class inherits parentable_part_of_admin_tree, this method should be called |
791 | * recursively on all child objects (assuming, of course, the parent object's name |
792 | * doesn't match the search criterion). |
793 | * |
794 | * @param string $name The internal name of the part_of_admin_tree we're searching for. |
795 | * @return mixed An object reference or a NULL reference. |
796 | */ |
eef868d1 |
797 | function &locate($name) { |
798 | trigger_error('Admin class does not implement method <strong>locate()</strong>', E_USER_WARNING); |
799 | return; |
6e4dc10f |
800 | } |
4672d955 |
801 | |
802 | /** |
803 | * Removes named part_of_admin_tree. |
804 | * |
805 | * @param string $name The internal name of the part_of_admin_tree we want to remove. |
a8a66c96 |
806 | * @return bool success. |
4672d955 |
807 | */ |
808 | function prune($name) { |
eef868d1 |
809 | trigger_error('Admin class does not implement method <strong>prune()</strong>', E_USER_WARNING); |
4672d955 |
810 | return; |
eef868d1 |
811 | } |
4672d955 |
812 | |
6e4dc10f |
813 | /** |
814 | * Verifies current user's access to this part_of_admin_tree. |
815 | * |
816 | * Used to check if the current user has access to this part of the admin tree or |
817 | * not. If a class only inherits part_of_admin_tree and not parentable_part_of_admin_tree, |
818 | * then this method is usually just a call to has_capability() in the site context. |
819 | * |
820 | * If a class inherits parentable_part_of_admin_tree, this method should return the |
821 | * logical OR of the return of check_access() on all child objects. |
822 | * |
823 | * @return bool True if the user has access, false if she doesn't. |
824 | */ |
eef868d1 |
825 | function check_access() { |
826 | trigger_error('Admin class does not implement method <strong>check_access()</strong>', E_USER_WARNING); |
827 | return; |
6e4dc10f |
828 | } |
eef868d1 |
829 | |
a8a66c96 |
830 | /** |
831 | * Mostly usefull for removing of some parts of the tree in admin tree block. |
832 | * |
833 | * @return True is hidden from normal list view |
834 | */ |
835 | function is_hidden() { |
836 | trigger_error('Admin class does not implement method <strong>is_hidden()</strong>', E_USER_WARNING); |
837 | return; |
838 | } |
839 | |
6e4dc10f |
840 | /** |
841 | * Determines the path to $name in the admin tree. |
842 | * |
843 | * Used to determine the path to $name in the admin tree. If a class inherits only |
844 | * part_of_admin_tree and not parentable_part_of_admin_tree, then this method should |
845 | * check if $this->name matches $name. If it does, $name is pushed onto the $path |
846 | * array (at the end), and $path should be returned. If it doesn't, NULL should be |
847 | * returned. |
848 | * |
849 | * If a class inherits parentable_part_of_admin_tree, it should do the above, but not |
850 | * return NULL on failure. Instead, it pushes $this->name onto $path, and then |
851 | * recursively calls path() on its child objects. If any are non-NULL, it should |
852 | * return $path (being certain that the last element of $path is equal to $name). |
853 | * If they are all NULL, it returns NULL. |
854 | * |
855 | * @param string $name The internal name of the part_of_admin_tree we're searching for. |
856 | * @param array $path Not used on external calls. Defaults to empty array. |
857 | * @return mixed If found, an array containing the internal names of each part_of_admin_tree that leads to $name. If not found, NULL. |
858 | */ |
eef868d1 |
859 | function path($name, $path = array()) { |
860 | trigger_error('Admin class does not implement method <strong>path()</strong>', E_USER_WARNING); |
861 | return; |
6e4dc10f |
862 | } |
863 | } |
864 | |
865 | /** |
866 | * Pseudointerface implemented by any part_of_admin_tree that has children. |
867 | * |
868 | * The pseudointerface implemented by any part_of_admin_tree that can be a parent |
869 | * to other part_of_admin_tree's. (For now, this only includes admin_category.) Apart |
eef868d1 |
870 | * from ensuring part_of_admin_tree compliancy, it also ensures inheriting methods |
6e4dc10f |
871 | * include an add method for adding other part_of_admin_tree objects as children. |
872 | * |
873 | * @author Vincenzo K. Marcovecchio |
874 | * @package admin |
875 | */ |
876 | class parentable_part_of_admin_tree extends part_of_admin_tree { |
eef868d1 |
877 | |
6e4dc10f |
878 | /** |
879 | * Adds a part_of_admin_tree object to the admin tree. |
880 | * |
881 | * Used to add a part_of_admin_tree object to this object or a child of this |
882 | * object. $something should only be added if $destinationname matches |
883 | * $this->name. If it doesn't, add should be called on child objects that are |
884 | * also parentable_part_of_admin_tree's. |
885 | * |
886 | * @param string $destinationname The internal name of the new parent for $something. |
887 | * @param part_of_admin_tree &$something The object to be added. |
888 | * @return bool True on success, false on failure. |
889 | */ |
eef868d1 |
890 | function add($destinationname, &$something) { |
891 | trigger_error('Admin class does not implement method <strong>add()</strong>', E_USER_WARNING); |
892 | return; |
6e4dc10f |
893 | } |
eef868d1 |
894 | |
6e4dc10f |
895 | } |
896 | |
897 | /** |
898 | * The object used to represent folders (a.k.a. categories) in the admin tree block. |
eef868d1 |
899 | * |
6e4dc10f |
900 | * Each admin_category object contains a number of part_of_admin_tree objects. |
901 | * |
902 | * @author Vincenzo K. Marcovecchio |
903 | * @package admin |
904 | */ |
905 | class admin_category extends parentable_part_of_admin_tree { |
906 | |
907 | /** |
908 | * @var mixed An array of part_of_admin_tree objects that are this object's children |
909 | */ |
910 | var $children; |
eef868d1 |
911 | |
6e4dc10f |
912 | /** |
913 | * @var string An internal name for this category. Must be unique amongst ALL part_of_admin_tree objects |
914 | */ |
915 | var $name; |
eef868d1 |
916 | |
6e4dc10f |
917 | /** |
918 | * @var string The displayed name for this category. Usually obtained through get_string() |
919 | */ |
920 | var $visiblename; |
eef868d1 |
921 | |
a8a66c96 |
922 | /** |
923 | * @var bool Should this category be hidden in admin tree block? |
924 | */ |
925 | var $hidden; |
926 | |
6e4dc10f |
927 | // constructor for an empty admin category |
928 | // $name is the internal name of the category. it MUST be unique in the entire hierarchy |
929 | // $visiblename is the displayed name of the category. use a get_string for this |
930 | |
931 | /** |
932 | * Constructor for an empty admin category |
933 | * |
934 | * @param string $name The internal name for this category. Must be unique amongst ALL part_of_admin_tree objects |
935 | * @param string $visiblename The displayed named for this category. Usually obtained through get_string() |
a8a66c96 |
936 | * @param bool $hidden hide category in admin tree block |
6e4dc10f |
937 | * @return mixed Returns the new object. |
938 | */ |
a8a66c96 |
939 | function admin_category($name, $visiblename, $hidden = false) { |
6e4dc10f |
940 | $this->children = array(); |
941 | $this->name = $name; |
942 | $this->visiblename = $visiblename; |
a8a66c96 |
943 | $this->hidden = $hidden; |
6e4dc10f |
944 | } |
eef868d1 |
945 | |
6e4dc10f |
946 | /** |
947 | * Finds the path to the part_of_admin_tree called $name. |
948 | * |
949 | * @param string $name The internal name that we're searching for. |
950 | * @param array $path Used internally for recursive calls. Do not specify on external calls. Defaults to array(). |
951 | * @return mixed An array of internal names that leads to $name, or NULL if not found. |
952 | */ |
953 | function path($name, $path = array()) { |
eef868d1 |
954 | |
6e4dc10f |
955 | $path[count($path)] = $this->name; |
eef868d1 |
956 | |
6e4dc10f |
957 | if ($this->name == $name) { |
958 | return $path; |
959 | } |
eef868d1 |
960 | |
6e4dc10f |
961 | foreach($this->children as $child) { |
962 | if ($return = $child->path($name, $path)) { |
963 | return $return; |
964 | } |
965 | } |
eef868d1 |
966 | |
6e4dc10f |
967 | return NULL; |
eef868d1 |
968 | |
6e4dc10f |
969 | } |
970 | |
971 | /** |
972 | * Returns a reference to the part_of_admin_tree object with internal name $name. |
973 | * |
974 | * @param string $name The internal name of the object we want. |
975 | * @return mixed A reference to the object with internal name $name if found, otherwise a reference to NULL. |
976 | */ |
977 | function &locate($name) { |
eef868d1 |
978 | |
6e4dc10f |
979 | if ($this->name == $name) { |
980 | return $this; |
981 | } |
eef868d1 |
982 | |
6e4dc10f |
983 | foreach($this->children as $child) { |
984 | if ($return =& $child->locate($name)) { |
985 | return $return; |
986 | } |
987 | } |
988 | $return = NULL; |
989 | return $return; |
990 | } |
991 | |
4672d955 |
992 | /** |
993 | * Removes part_of_admin_tree object with internal name $name. |
994 | * |
995 | * @param string $name The internal name of the object we want to remove. |
a8a66c96 |
996 | * @return bool success |
4672d955 |
997 | */ |
998 | function prune($name) { |
999 | |
1000 | if ($this->name == $name) { |
1001 | return false; //can not remove itself |
1002 | } |
1003 | |
1004 | foreach($this->children as $precedence => $child) { |
1005 | if ($child->name == $name) { |
1006 | // found it! |
eef868d1 |
1007 | unset($this->children[$precedence]); |
4672d955 |
1008 | return true; |
1009 | } |
1010 | if ($this->children[$precedence]->prune($name)) { |
1011 | return true; |
1012 | } |
1013 | } |
1014 | return false; |
1015 | } |
1016 | |
6e4dc10f |
1017 | /** |
1018 | * Adds a part_of_admin_tree to a child or grandchild (or great-grandchild, and so forth) of this object. |
1019 | * |
1020 | * @param string $destinationame The internal name of the immediate parent that we want for &$something. |
1021 | * @param mixed &$something A part_of_admin_tree object to be added. |
1022 | * @param int $precedence The precedence of &$something when displayed. Smaller numbers mean it'll be displayed higher up in the admin menu. Defaults to '', meaning "next available position". |
1023 | * @return bool True if successfully added, false if &$something is not a part_of_admin_tree or if $name is not found. |
1024 | */ |
1025 | function add($destinationname, &$something, $precedence = '') { |
eef868d1 |
1026 | |
6e4dc10f |
1027 | if (!is_a($something, 'part_of_admin_tree')) { |
1028 | return false; |
1029 | } |
1030 | |
1031 | if ($destinationname == $this->name) { |
1032 | if ($precedence === '') { |
1033 | $this->children[] = $something; |
1034 | } else { |
1035 | if (isset($this->children[$precedence])) { // this should never, ever be triggered in a release version of moodle. |
1036 | echo ('<font style="color: red;">There is a precedence conflict in the category ' . $this->name . '. The object named ' . $something->name . ' is overwriting the object named ' . $this->children[$precedence]->name . '.</font><br />'); |
1037 | } |
1038 | $this->children[$precedence] = $something; |
1039 | } |
1040 | return true; |
1041 | } |
eef868d1 |
1042 | |
6e4dc10f |
1043 | unset($entries); |
eef868d1 |
1044 | |
6e4dc10f |
1045 | $entries = array_keys($this->children); |
eef868d1 |
1046 | |
6e4dc10f |
1047 | foreach($entries as $entry) { |
1048 | $child =& $this->children[$entry]; |
1049 | if (is_a($child, 'parentable_part_of_admin_tree')) { |
1050 | if ($child->add($destinationname, $something, $precedence)) { |
1051 | return true; |
1052 | } |
1053 | } |
1054 | } |
eef868d1 |
1055 | |
6e4dc10f |
1056 | return false; |
eef868d1 |
1057 | |
6e4dc10f |
1058 | } |
eef868d1 |
1059 | |
6e4dc10f |
1060 | /** |
1061 | * Checks if the user has access to anything in this category. |
1062 | * |
1063 | * @return bool True if the user has access to atleast one child in this category, false otherwise. |
1064 | */ |
1065 | function check_access() { |
eef868d1 |
1066 | |
6e4dc10f |
1067 | $return = false; |
1068 | foreach ($this->children as $child) { |
1069 | $return = $return || $child->check_access(); |
1070 | } |
eef868d1 |
1071 | |
6e4dc10f |
1072 | return $return; |
eef868d1 |
1073 | |
6e4dc10f |
1074 | } |
eef868d1 |
1075 | |
a8a66c96 |
1076 | /** |
1077 | * Is this category hidden in admin tree block? |
1078 | * |
1079 | * @return bool True if hidden |
1080 | */ |
1081 | function is_hidden() { |
1082 | return $this->hidden; |
1083 | } |
6e4dc10f |
1084 | } |
1085 | |
1086 | /** |
1087 | * Links external PHP pages into the admin tree. |
1088 | * |
1089 | * See detailed usage example at the top of this document (adminlib.php) |
1090 | * |
1091 | * @author Vincenzo K. Marcovecchio |
1092 | * @package admin |
1093 | */ |
1094 | class admin_externalpage extends part_of_admin_tree { |
1095 | |
eef868d1 |
1096 | /** |
6e4dc10f |
1097 | * @var string An internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects |
1098 | */ |
1099 | var $name; |
eef868d1 |
1100 | |
6e4dc10f |
1101 | /** |
1102 | * @var string The displayed name for this external page. Usually obtained through get_string(). |
1103 | */ |
1104 | var $visiblename; |
eef868d1 |
1105 | |
6e4dc10f |
1106 | /** |
1107 | * @var string The external URL that we should link to when someone requests this external page. |
1108 | */ |
1109 | var $url; |
eef868d1 |
1110 | |
6e4dc10f |
1111 | /** |
1112 | * @var string The role capability/permission a user must have to access this external page. |
1113 | */ |
2ce38b70 |
1114 | var $req_capability; |
eef868d1 |
1115 | |
84c8ede0 |
1116 | /** |
1117 | * @var object The context in which capability/permission should be checked, default is site context. |
1118 | */ |
1119 | var $context; |
1120 | |
a8a66c96 |
1121 | /** |
1122 | * @var bool hidden in admin tree block. |
1123 | */ |
1124 | var $hidden; |
1125 | |
6e4dc10f |
1126 | /** |
1127 | * Constructor for adding an external page into the admin tree. |
1128 | * |
1129 | * @param string $name The internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects. |
1130 | * @param string $visiblename The displayed name for this external page. Usually obtained through get_string(). |
1131 | * @param string $url The external URL that we should link to when someone requests this external page. |
38d2d43b |
1132 | * @param mixed $req_capability The role capability/permission a user must have to access this external page. Defaults to 'moodle/site:config'. |
6e4dc10f |
1133 | */ |
01e85af9 |
1134 | function admin_externalpage($name, $visiblename, $url, $req_capability = 'moodle/site:config', $hidden=false, $context=NULL) { |
6e4dc10f |
1135 | $this->name = $name; |
1136 | $this->visiblename = $visiblename; |
1137 | $this->url = $url; |
38d2d43b |
1138 | if (is_array($req_capability)) { |
1139 | $this->req_capability = $req_capability; |
1140 | } else { |
1141 | $this->req_capability = array($req_capability); |
1142 | } |
a8a66c96 |
1143 | $this->hidden = $hidden; |
84c8ede0 |
1144 | $this->context = $context; |
6e4dc10f |
1145 | } |
eef868d1 |
1146 | |
6e4dc10f |
1147 | /** |
1148 | * Finds the path to the part_of_admin_tree called $name. |
1149 | * |
1150 | * @param string $name The internal name that we're searching for. |
1151 | * @param array $path Used internally for recursive calls. Do not specify on external calls. Defaults to array(). |
1152 | * @return mixed An array of internal names that leads to $name, or NULL if not found. |
1153 | */ |
1154 | function path($name, $path = array()) { |
1155 | if ($name == $this->name) { |
1156 | array_push($path, $this->name); |
1157 | return $path; |
1158 | } else { |
1159 | return NULL; |
1160 | } |
1161 | } |
eef868d1 |
1162 | |
6e4dc10f |
1163 | /** |
1164 | * Returns a reference to the part_of_admin_tree object with internal name $name. |
1165 | * |
1166 | * @param string $name The internal name of the object we want. |
1167 | * @return mixed A reference to the object with internal name $name if found, otherwise a reference to NULL. |
1168 | */ |
1169 | function &locate($name) { |
1170 | $return = ($this->name == $name ? $this : NULL); |
1171 | return $return; |
1172 | } |
4672d955 |
1173 | |
1174 | function prune($name) { |
1175 | return false; |
1176 | } |
1177 | |
6e4dc10f |
1178 | /** |
2ce38b70 |
1179 | * Determines if the current user has access to this external page based on $this->req_capability. |
6e4dc10f |
1180 | * |
1181 | * @uses CONTEXT_SYSTEM |
1182 | * @uses SITEID |
1183 | * @return bool True if user has access, false otherwise. |
1184 | */ |
1185 | function check_access() { |
1186 | if (!get_site()) { |
1187 | return true; // no access check before site is fully set up |
1188 | } |
84c8ede0 |
1189 | $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; |
38d2d43b |
1190 | foreach($this->req_capability as $cap) { |
1191 | if (has_capability($cap, $context)) { |
1192 | return true; |
1193 | } |
1194 | } |
1195 | return false; |
6e4dc10f |
1196 | } |
1197 | |
a8a66c96 |
1198 | /** |
1199 | * Is this external page hidden in admin tree block? |
1200 | * |
1201 | * @return bool True if hidden |
1202 | */ |
1203 | function is_hidden() { |
1204 | return $this->hidden; |
1205 | } |
1206 | |
6e4dc10f |
1207 | } |
1208 | |
1209 | /** |
1210 | * Used to group a number of admin_setting objects into a page and add them to the admin tree. |
1211 | * |
1212 | * @author Vincenzo K. Marcovecchio |
1213 | * @package admin |
1214 | */ |
1215 | class admin_settingpage extends part_of_admin_tree { |
1216 | |
eef868d1 |
1217 | /** |
6e4dc10f |
1218 | * @var string An internal name for this external page. Must be unique amongst ALL part_of_admin_tree objects |
1219 | */ |
1220 | var $name; |
eef868d1 |
1221 | |
6e4dc10f |
1222 | /** |
1223 | * @var string The displayed name for this external page. Usually obtained through get_string(). |
1224 | */ |
1225 | var $visiblename; |
1226 | /** |
1227 | * @var mixed An array of admin_setting objects that are part of this setting page. |
1228 | */ |
1229 | var $settings; |
eef868d1 |
1230 | |
6e4dc10f |
1231 | /** |
1232 | * @var string The role capability/permission a user must have to access this external page. |
1233 | */ |
2ce38b70 |
1234 | var $req_capability; |
eef868d1 |
1235 | |
84c8ede0 |
1236 | /** |
1237 | * @var object The context in which capability/permission should be checked, default is site context. |
1238 | */ |
1239 | var $context; |
1240 | |
a8a66c96 |
1241 | /** |
1242 | * @var bool hidden in admin tree block. |
1243 | */ |
1244 | var $hidden; |
1245 | |
6e4dc10f |
1246 | // see admin_category |
1247 | function path($name, $path = array()) { |
1248 | if ($name == $this->name) { |
1249 | array_push($path, $this->name); |
1250 | return $path; |
1251 | } else { |
1252 | return NULL; |
1253 | } |
1254 | } |
eef868d1 |
1255 | |
6e4dc10f |
1256 | // see admin_category |
1257 | function &locate($name) { |
1258 | $return = ($this->name == $name ? $this : NULL); |
1259 | return $return; |
1260 | } |
4672d955 |
1261 | |
1262 | function prune($name) { |
1263 | return false; |
1264 | } |
1265 | |
6e4dc10f |
1266 | // see admin_externalpage |
01e85af9 |
1267 | function admin_settingpage($name, $visiblename, $req_capability = 'moodle/site:config', $hidden=false, $context=NULL) { |
6e4dc10f |
1268 | global $CFG; |
1269 | $this->settings = new stdClass(); |
1270 | $this->name = $name; |
1271 | $this->visiblename = $visiblename; |
38d2d43b |
1272 | if (is_array($req_capability)) { |
1273 | $this->req_capability = $req_capability; |
1274 | } else { |
1275 | $this->req_capability = array($req_capability); |
1276 | } |
a8a66c96 |
1277 | $this->hidden = false; |
84c8ede0 |
1278 | $this->context = $context; |
6e4dc10f |
1279 | } |
eef868d1 |
1280 | |
6e4dc10f |
1281 | // not the same as add for admin_category. adds an admin_setting to this admin_settingpage. settings appear (on the settingpage) in the order in which they're added |
1282 | // n.b. each admin_setting in an admin_settingpage must have a unique internal name |
1283 | // &$setting is the admin_setting object you want to add |
1284 | // returns true if successful, false if not (will fail if &$setting is an admin_setting or child thereof) |
1285 | function add(&$setting) { |
1286 | if (is_a($setting, 'admin_setting')) { |
1287 | $this->settings->{$setting->name} =& $setting; |
1288 | return true; |
1289 | } |
1290 | return false; |
1291 | } |
eef868d1 |
1292 | |
6e4dc10f |
1293 | // see admin_externalpage |
1294 | function check_access() { |
1295 | if (!get_site()) { |
1296 | return true; // no access check before site is fully set up |
1297 | } |
84c8ede0 |
1298 | $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; |
38d2d43b |
1299 | foreach($this->req_capability as $cap) { |
1300 | if (has_capability($cap, $context)) { |
1301 | return true; |
1302 | } |
1303 | } |
1304 | return false; |
6e4dc10f |
1305 | } |
eef868d1 |
1306 | |
6e4dc10f |
1307 | // outputs this page as html in a table (suitable for inclusion in an admin pagetype) |
1308 | // returns a string of the html |
1309 | function output_html() { |
15a16922 |
1310 | $return = '<fieldset>' . "\n"; |
6153cf58 |
1311 | $return .= '<div class="clearer"><!-- --></div>' . "\n"; |
6e4dc10f |
1312 | foreach($this->settings as $setting) { |
15a16922 |
1313 | $return .= $setting->output_html(); |
6e4dc10f |
1314 | } |
6153cf58 |
1315 | $return .= '</fieldset>'; |
6e4dc10f |
1316 | return $return; |
1317 | } |
1318 | |
1319 | // writes settings (the ones that have been added to this admin_settingpage) to the database, or wherever else they're supposed to be written to |
1320 | // -- calls write_setting() to each child setting, sending it only the data that matches each setting's internal name |
1321 | // $data should be the result from data_submitted() |
1322 | // returns an empty string if everything went well, otherwise returns a printable error string (that's language-specific) |
1323 | function write_settings($data) { |
1324 | $return = ''; |
1325 | foreach($this->settings as $setting) { |
1326 | if (isset($data['s_' . $setting->name])) { |
1327 | $return .= $setting->write_setting($data['s_' . $setting->name]); |
1328 | } else { |
1329 | $return .= $setting->write_setting(''); |
1330 | } |
1331 | } |
1332 | return $return; |
1333 | } |
1334 | |
a8a66c96 |
1335 | /** |
1336 | * Is this settigns page hidden in admin tree block? |
1337 | * |
1338 | * @return bool True if hidden |
1339 | */ |
1340 | function is_hidden() { |
1341 | return $this->hidden; |
1342 | } |
1343 | |
6e4dc10f |
1344 | } |
1345 | |
1346 | |
1347 | // read & write happens at this level; no authentication |
1348 | class admin_setting { |
1349 | |
1350 | var $name; |
1351 | var $visiblename; |
1352 | var $description; |
1353 | var $defaultsetting; |
1354 | |
1355 | function admin_setting($name, $visiblename, $description, $defaultsetting) { |
1356 | $this->name = $name; |
1357 | $this->visiblename = $visiblename; |
1358 | $this->description = $description; |
1359 | $this->defaultsetting = $defaultsetting; |
1360 | } |
eef868d1 |
1361 | |
6e4dc10f |
1362 | function get_setting() { |
1363 | return NULL; // has to be overridden |
1364 | } |
eef868d1 |
1365 | |
6e4dc10f |
1366 | function write_setting($data) { |
1367 | return; // has to be overridden |
1368 | } |
eef868d1 |
1369 | |
6e4dc10f |
1370 | function output_html() { |
1371 | return; // has to be overridden |
1372 | } |
eef868d1 |
1373 | |
6e4dc10f |
1374 | } |
1375 | |
1376 | |
1377 | class admin_setting_configtext extends admin_setting { |
1378 | |
1379 | var $paramtype; |
1380 | |
50999a0b |
1381 | function admin_setting_configtext($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW) { |
6e4dc10f |
1382 | $this->paramtype = $paramtype; |
1383 | parent::admin_setting($name, $visiblename, $description, $defaultsetting); |
1384 | } |
1385 | |
cc73de71 |
1386 | // returns a string or NULL |
6e4dc10f |
1387 | function get_setting() { |
1388 | global $CFG; |
c8218a42 |
1389 | return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL); |
6e4dc10f |
1390 | } |
eef868d1 |
1391 | |
cc73de71 |
1392 | // $data is a string |
6e4dc10f |
1393 | function write_setting($data) { |
9e24fbd1 |
1394 | if (!$this->validate($data)) { |
1395 | return get_string('validateerror', 'admin') . $this->visiblename . '<br />'; |
c235598d |
1396 | } |
6e4dc10f |
1397 | return (set_config($this->name,$data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1398 | } |
1399 | |
c235598d |
1400 | function validate($data) { |
9e24fbd1 |
1401 | if (is_string($this->paramtype)) { |
1402 | return preg_match($this->paramtype, $data); |
1403 | } else if ($this->paramtype === PARAM_RAW) { |
1404 | return true; |
1405 | } else { |
1406 | $cleaned = clean_param($data, $this->paramtype); |
1407 | return ("$data" == "$cleaned"); // implicit conversion to string is needed to do exact comparison |
1408 | } |
c235598d |
1409 | } |
1410 | |
6e4dc10f |
1411 | function output_html() { |
c8218a42 |
1412 | if ($this->get_setting() === NULL) { |
1413 | $current = $this->defaultsetting; |
1414 | } else { |
1415 | $current = $this->get_setting(); |
1416 | } |
9e24fbd1 |
1417 | return format_admin_setting($this->name, $this->visiblename, |
5259d5d8 |
1418 | '<input type="text" class="form-text" id="id_s_'.$this->name.'" name="s_'.$this->name.'" value="'.s($current).'" />', |
6153cf58 |
1419 | $this->description); |
6e4dc10f |
1420 | } |
1421 | |
1422 | } |
1423 | |
1424 | class admin_setting_configcheckbox extends admin_setting { |
1425 | |
1426 | function admin_setting_configcheckbox($name, $visiblename, $description, $defaultsetting) { |
1427 | parent::admin_setting($name, $visiblename, $description, $defaultsetting); |
1428 | } |
1429 | |
1430 | function get_setting() { |
1431 | global $CFG; |
1432 | return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL); |
1433 | } |
eef868d1 |
1434 | |
6e4dc10f |
1435 | function write_setting($data) { |
1436 | if ($data == '1') { |
1437 | return (set_config($this->name,1) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1438 | } else { |
1439 | return (set_config($this->name,0) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1440 | } |
1441 | } |
1442 | |
1443 | function output_html() { |
c8218a42 |
1444 | if ($this->get_setting() === NULL) { |
1445 | $current = $this->defaultsetting; |
1446 | } else { |
1447 | $current = $this->get_setting(); |
1448 | } |
9e24fbd1 |
1449 | return format_admin_setting($this->name, $this->visiblename, |
3c6f7a78 |
1450 | '<input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'" name="s_'. $this->name .'" value="1" ' . ($current == true ? 'checked="checked"' : '') . ' />', |
6153cf58 |
1451 | $this->description); |
6e4dc10f |
1452 | } |
1453 | |
1454 | } |
1455 | |
1456 | class admin_setting_configselect extends admin_setting { |
1457 | |
1458 | var $choices; |
eef868d1 |
1459 | |
6e4dc10f |
1460 | function admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices) { |
1461 | $this->choices = $choices; |
1462 | parent::admin_setting($name, $visiblename, $description, $defaultsetting); |
1463 | } |
1464 | |
1465 | function get_setting() { |
1466 | global $CFG; |
1467 | return (isset($CFG->{$this->name}) ? $CFG->{$this->name} : NULL); |
1468 | } |
eef868d1 |
1469 | |
6e4dc10f |
1470 | function write_setting($data) { |
1471 | // check that what we got was in the original choices |
1472 | // or that the data is the default setting - needed during install when choices can not be constructed yet |
1473 | if ($data != $this->defaultsetting and ! in_array($data, array_keys($this->choices))) { |
1474 | return 'Error setting ' . $this->visiblename . '<br />'; |
1475 | } |
eef868d1 |
1476 | |
6e4dc10f |
1477 | return (set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1478 | } |
eef868d1 |
1479 | |
6e4dc10f |
1480 | function output_html() { |
c8218a42 |
1481 | if ($this->get_setting() === NULL) { |
1482 | $current = $this->defaultsetting; |
1483 | } else { |
1484 | $current = $this->get_setting(); |
1485 | } |
afee9864 |
1486 | $return = '<select class="form-select" id="id_s_'.$this->name.'" name="s_' . $this->name .'">'; |
6e4dc10f |
1487 | foreach ($this->choices as $key => $value) { |
a1069b07 |
1488 | // the string cast is needed because key may be integer - 0 is equal to most strings! |
1489 | $return .= '<option value="'.$key.'"'.((string)$key==$current ? ' selected="selected"' : '').'>'.$value.'</option>'; |
6e4dc10f |
1490 | } |
6153cf58 |
1491 | $return .= '</select>'; |
1492 | |
fc52aa6e |
1493 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description); |
6e4dc10f |
1494 | } |
1495 | |
1496 | } |
1497 | |
1498 | // this is a liiitle bit messy. we're using two selects, but we're returning them as an array named after $name (so we only use $name2 |
1499 | // internally for the setting) |
1500 | class admin_setting_configtime extends admin_setting { |
1501 | |
1502 | var $name2; |
1503 | var $choices; |
1504 | var $choices2; |
6e4dc10f |
1505 | |
1506 | function admin_setting_configtime($hoursname, $minutesname, $visiblename, $description, $defaultsetting) { |
1507 | $this->name2 = $minutesname; |
1508 | $this->choices = array(); |
1509 | for ($i = 0; $i < 24; $i++) { |
1510 | $this->choices[$i] = $i; |
1511 | } |
1512 | $this->choices2 = array(); |
1513 | for ($i = 0; $i < 60; $i += 5) { |
1514 | $this->choices2[$i] = $i; |
1515 | } |
1516 | parent::admin_setting($hoursname, $visiblename, $description, $defaultsetting); |
1517 | } |
1518 | |
1519 | function get_setting() { |
1520 | global $CFG; |
cc73de71 |
1521 | return (isset($CFG->{$this->name}) && isset($CFG->{$this->name2}) ? array('h' => $CFG->{$this->name}, 'm' => $CFG->{$this->name2}) : NULL); |
6e4dc10f |
1522 | } |
eef868d1 |
1523 | |
6e4dc10f |
1524 | function write_setting($data) { |
1525 | // check that what we got was in the original choices |
1526 | if (!(in_array($data['h'], array_keys($this->choices)) && in_array($data['m'], array_keys($this->choices2)))) { |
1527 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
1528 | } |
eef868d1 |
1529 | |
6e4dc10f |
1530 | return (set_config($this->name, $data['h']) && set_config($this->name2, $data['m']) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1531 | } |
eef868d1 |
1532 | |
6e4dc10f |
1533 | function output_html() { |
cc73de71 |
1534 | if ($this->get_setting() === NULL) { |
1535 | $currentsetting = $this->defaultsetting; |
1536 | } else { |
1537 | $currentsetting = $this->get_setting(); |
6e4dc10f |
1538 | } |
2e0c11dd |
1539 | $return = '<div class="form-group">'. |
1540 | '<select class="form-select" id="id_s_'.$this->name.'h" name="s_' . $this->name .'[h]">'; |
6e4dc10f |
1541 | foreach ($this->choices as $key => $value) { |
cc73de71 |
1542 | $return .= '<option value="' . $key . '"' . ($key == $currentsetting['h'] ? ' selected="selected"' : '') . '>' . $value . '</option>'; |
6e4dc10f |
1543 | } |
2e0c11dd |
1544 | $return .= '</select>:<select class="form-select" id="id_s_'.$this->name.'m" name="s_' . $this->name . '[m]">'; |
6e4dc10f |
1545 | foreach ($this->choices2 as $key => $value) { |
cc73de71 |
1546 | $return .= '<option value="' . $key . '"' . ($key == $currentsetting['m'] ? ' selected="selected"' : '') . '>' . $value . '</option>'; |
eef868d1 |
1547 | } |
2e0c11dd |
1548 | $return .= '</select></div>'; |
fbe31d22 |
1549 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
6e4dc10f |
1550 | } |
1551 | |
1552 | } |
1553 | |
1554 | class admin_setting_configmultiselect extends admin_setting_configselect { |
1555 | |
1556 | function admin_setting_configmultiselect($name, $visiblename, $description, $defaultsetting, $choices) { |
1557 | parent::admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices); |
1558 | } |
1559 | |
1560 | function get_setting() { |
1561 | global $CFG; |
d7933a55 |
1562 | if (isset($CFG->{$this->name})) { |
1563 | if ($CFG->{$this->name}) { |
1564 | return explode(',', $CFG->{$this->name}); |
1565 | } else { |
1566 | return array(); |
1567 | } |
1568 | } else { |
1569 | return NULL; |
1570 | } |
6e4dc10f |
1571 | } |
eef868d1 |
1572 | |
6e4dc10f |
1573 | function write_setting($data) { |
d7933a55 |
1574 | if (empty($data)) { |
1575 | $data = array(); |
1576 | } |
6e4dc10f |
1577 | foreach ($data as $datum) { |
1578 | if (! in_array($datum, array_keys($this->choices))) { |
1579 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
1580 | } |
1581 | } |
eef868d1 |
1582 | |
6e4dc10f |
1583 | return (set_config($this->name, implode(',',$data)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1584 | } |
eef868d1 |
1585 | |
6e4dc10f |
1586 | function output_html() { |
cc73de71 |
1587 | if ($this->get_setting() === NULL) { |
1588 | $currentsetting = $this->defaultsetting; |
0b0f7c00 |
1589 | if (!$currentsetting) { |
1590 | $currentsetting = array(); |
1591 | } |
cc73de71 |
1592 | } else { |
1593 | $currentsetting = $this->get_setting(); |
6e4dc10f |
1594 | } |
afee9864 |
1595 | $return = '<select class="form-select" id="id_s_'.$this->name.'" name="s_' . $this->name .'[]" size="10" multiple="multiple">'; |
6e4dc10f |
1596 | foreach ($this->choices as $key => $value) { |
1597 | $return .= '<option value="' . $key . '"' . (in_array($key,$currentsetting) ? ' selected="selected"' : '') . '>' . $value . '</option>'; |
1598 | } |
6153cf58 |
1599 | $return .= '</select>'; |
fc52aa6e |
1600 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description); |
6e4dc10f |
1601 | } |
1602 | |
1603 | } |
1604 | |
1605 | class admin_setting_special_adminseesall extends admin_setting_configcheckbox { |
eef868d1 |
1606 | |
6e4dc10f |
1607 | function admin_setting_special_adminseesall() { |
1608 | $name = 'calendar_adminseesall'; |
1609 | $visiblename = get_string('adminseesall', 'admin'); |
1610 | $description = get_string('helpadminseesall', 'admin'); |
1611 | parent::admin_setting($name, $visiblename, $description, 0); |
1612 | } |
1613 | |
1614 | function write_setting($data) { |
1615 | global $SESSION; |
1616 | unset($SESSION->cal_courses_shown); |
1617 | parent::write_setting($data); |
1618 | } |
1619 | } |
1620 | |
1621 | class admin_setting_sitesetselect extends admin_setting_configselect { |
1622 | |
1623 | var $id; |
1624 | |
1625 | function admin_setting_sitesetselect($name, $visiblename, $description, $defaultsetting, $choices) { |
1626 | |
1627 | $this->id = SITEID; |
1628 | parent::admin_setting_configselect($name, $visiblename, $description, $defaultsetting, $choices); |
eef868d1 |
1629 | |
6e4dc10f |
1630 | } |
eef868d1 |
1631 | |
6e4dc10f |
1632 | function get_setting() { |
1633 | $site = get_site(); |
1634 | return (isset($site->{$this->name}) ? $site->{$this->name} : NULL); |
1635 | } |
eef868d1 |
1636 | |
6e4dc10f |
1637 | function write_setting($data) { |
1638 | if (!in_array($data, array_keys($this->choices))) { |
1639 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
1640 | } |
1641 | $record = new stdClass(); |
1642 | $record->id = $this->id; |
1643 | $temp = $this->name; |
1644 | $record->$temp = $data; |
1645 | $record->timemodified = time(); |
1646 | return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1647 | } |
eef868d1 |
1648 | |
6e4dc10f |
1649 | } |
1650 | |
1651 | |
e0f6e995 |
1652 | class admin_setting_courselist_frontpage extends admin_setting_configselect { |
6e4dc10f |
1653 | |
e0f6e995 |
1654 | function admin_setting_courselist_frontpage($loggedin) { |
6e4dc10f |
1655 | global $CFG; |
1656 | require_once($CFG->dirroot . '/course/lib.php'); |
1657 | $name = 'frontpage' . ($loggedin ? 'loggedin' : ''); |
1658 | $visiblename = get_string('frontpage' . ($loggedin ? 'loggedin' : ''),'admin'); |
1659 | $description = get_string('configfrontpage' . ($loggedin ? 'loggedin' : ''),'admin'); |
1660 | $choices = array(FRONTPAGENEWS => get_string('frontpagenews'), |
1661 | FRONTPAGECOURSELIST => get_string('frontpagecourselist'), |
1662 | FRONTPAGECATEGORYNAMES => get_string('frontpagecategorynames'), |
1663 | FRONTPAGECATEGORYCOMBO => get_string('frontpagecategorycombo'), |
1664 | '' => get_string('none')); |
9fec4e33 |
1665 | if (!$loggedin and count_records("course") > FRONTPAGECOURSELIMIT) { |
6e4dc10f |
1666 | unset($choices[FRONTPAGECOURSELIST]); |
1667 | } |
4672d955 |
1668 | $defaults = FRONTPAGECOURSELIST.',,,'; |
e0f6e995 |
1669 | parent::admin_setting_configselect($name, $visiblename, $description, $defaults, $choices); |
6e4dc10f |
1670 | } |
eef868d1 |
1671 | |
6e4dc10f |
1672 | function get_setting() { |
1673 | global $CFG; |
1c1e7af4 |
1674 | return (isset($CFG->{$this->name}) ? explode(',', $CFG->{$this->name}) : ',1,,'); |
6e4dc10f |
1675 | } |
eef868d1 |
1676 | |
6e4dc10f |
1677 | function write_setting($data) { |
1678 | if (empty($data)) { |
1679 | $data = array(); |
e0f6e995 |
1680 | } if (!is_array($data)) { |
1681 | $data = explode(',', $data); |
6e4dc10f |
1682 | } |
1683 | foreach($data as $datum) { |
1684 | if (! in_array($datum, array_keys($this->choices))) { |
1685 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
1686 | } |
1687 | } |
1688 | return (set_config($this->name, implode(',', $data)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1689 | } |
eef868d1 |
1690 | |
6e4dc10f |
1691 | function output_html() { |
cc73de71 |
1692 | if ($this->get_setting() === NULL) { |
1693 | $currentsetting = $this->defaultsetting; |
1694 | } else { |
1695 | $currentsetting = $this->get_setting(); |
6e4dc10f |
1696 | } |
1697 | for ($i = 0; $i < count($this->choices) - 1; $i++) { |
1698 | if (!isset($currentsetting[$i])) { |
1699 | $currentsetting[$i] = 0; |
1700 | } |
1701 | } |
0a7e84c3 |
1702 | $return = '<div class="form-group">'; |
6e4dc10f |
1703 | for ($i = 0; $i < count($this->choices) - 1; $i++) { |
a1d52643 |
1704 | $return .='<select class="form-select" id="id_s_'.$this->name.$i.'" name="s_' . $this->name .'[]">'; |
6e4dc10f |
1705 | foreach ($this->choices as $key => $value) { |
1706 | $return .= '<option value="' . $key . '"' . ($key == $currentsetting[$i] ? ' selected="selected"' : '') . '>' . $value . '</option>'; |
1707 | } |
1708 | $return .= '</select>'; |
1709 | if ($i !== count($this->choices) - 2) { |
975211bb |
1710 | $return .= '<br />'; |
6e4dc10f |
1711 | } |
1712 | } |
0a7e84c3 |
1713 | $return .= '</div>'; |
1714 | |
fbe31d22 |
1715 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
6e4dc10f |
1716 | } |
1717 | } |
1718 | |
1719 | class admin_setting_sitesetcheckbox extends admin_setting_configcheckbox { |
1720 | |
1721 | var $id; |
1722 | |
1723 | function admin_setting_sitesetcheckbox($name, $visiblename, $description, $defaultsetting) { |
1724 | |
1725 | $this->id = SITEID; |
1726 | parent::admin_setting_configcheckbox($name, $visiblename, $description, $defaultsetting); |
eef868d1 |
1727 | |
6e4dc10f |
1728 | } |
eef868d1 |
1729 | |
6e4dc10f |
1730 | function get_setting() { |
1731 | $site = get_site(); |
1732 | return (isset($site->{$this->name}) ? $site->{$this->name} : NULL); |
1733 | } |
eef868d1 |
1734 | |
6e4dc10f |
1735 | function write_setting($data) { |
1736 | $record = new stdClass(); |
1737 | $record->id = $this->id; |
1738 | $temp = $this->name; |
1739 | $record->$temp = ($data == '1' ? 1 : 0); |
1740 | $record->timemodified = time(); |
1741 | return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1742 | } |
eef868d1 |
1743 | |
6e4dc10f |
1744 | } |
1745 | |
1746 | class admin_setting_sitesettext extends admin_setting_configtext { |
1747 | |
1748 | var $id; |
1749 | |
b89639f9 |
1750 | function admin_setting_sitesettext($name, $visiblename, $description, $defaultsetting) { |
6e4dc10f |
1751 | |
1752 | $this->id = SITEID; |
b89639f9 |
1753 | parent::admin_setting_configtext($name, $visiblename, $description, $defaultsetting); |
eef868d1 |
1754 | |
6e4dc10f |
1755 | } |
eef868d1 |
1756 | |
6e4dc10f |
1757 | function get_setting() { |
1758 | $site = get_site(); |
1759 | return (isset($site->{$this->name}) ? $site->{$this->name} : NULL); |
1760 | } |
90cfbd0a |
1761 | |
b89639f9 |
1762 | function validate($data) { |
1763 | $cleaned = clean_param($data, PARAM_NOTAGS); |
1764 | if ($cleaned == '') { |
1765 | return false; // can not be empty |
1766 | } |
1767 | return ("$data" == "$cleaned"); // implicit conversion to string is needed to do exact comparison |
1768 | } |
1769 | |
6e4dc10f |
1770 | function write_setting($data) { |
b89639f9 |
1771 | $data = trim($data); |
9e24fbd1 |
1772 | if (!$this->validate($data)) { |
1773 | return get_string('validateerror', 'admin') . $this->visiblename . '<br />'; |
90cfbd0a |
1774 | } |
eef868d1 |
1775 | |
6e4dc10f |
1776 | $record = new stdClass(); |
1777 | $record->id = $this->id; |
87fa8a17 |
1778 | $record->{$this->name} = addslashes($data); |
6e4dc10f |
1779 | $record->timemodified = time(); |
23a97d83 |
1780 | return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
6e4dc10f |
1781 | } |
90cfbd0a |
1782 | |
6e4dc10f |
1783 | } |
1784 | |
1785 | class admin_setting_special_frontpagedesc extends admin_setting { |
1786 | |
1787 | var $id; |
eef868d1 |
1788 | |
6e4dc10f |
1789 | function admin_setting_special_frontpagedesc() { |
1790 | $this->id = SITEID; |
1791 | $name = 'summary'; |
1792 | $visiblename = get_string('frontpagedescription'); |
1793 | $description = get_string('frontpagedescriptionhelp'); |
1794 | parent::admin_setting($name, $visiblename, $description, ''); |
1795 | } |
1796 | |
1797 | function output_html() { |
eef868d1 |
1798 | |
fa040029 |
1799 | global $CFG; |
1800 | |
cc73de71 |
1801 | if ($this->get_setting() === NULL) { |
1802 | $currentsetting = $this->defaultsetting; |
1803 | } else { |
1804 | $currentsetting = $this->get_setting(); |
1805 | } |
eef868d1 |
1806 | |
fa040029 |
1807 | $CFG->adminusehtmleditor = can_use_html_editor(); |
eef868d1 |
1808 | |
fa040029 |
1809 | $return = print_textarea($CFG->adminusehtmleditor, 15, 60, 0, 0, 's_' . $this->name, $currentsetting, 0, true); |
eef868d1 |
1810 | |
fbe31d22 |
1811 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
6e4dc10f |
1812 | } |
eef868d1 |
1813 | |
6e4dc10f |
1814 | function get_setting() { |
eef868d1 |
1815 | |
6e4dc10f |
1816 | $site = get_site(); |
1817 | return (isset($site->{$this->name}) ? $site->{$this->name} : NULL); |
eef868d1 |
1818 | |
6e4dc10f |
1819 | } |
eef868d1 |
1820 | |
6e4dc10f |
1821 | function write_setting($data) { |
eef868d1 |
1822 | |
6e4dc10f |
1823 | $data = addslashes(clean_param($data, PARAM_CLEANHTML)); |
eef868d1 |
1824 | |
6e4dc10f |
1825 | $record = new stdClass(); |
1826 | $record->id = $this->id; |
1827 | $temp = $this->name; |
1828 | $record->$temp = $data; |
1829 | $record->timemodified = time(); |
eef868d1 |
1830 | |
6e4dc10f |
1831 | return(update_record('course', $record) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
eef868d1 |
1832 | |
6e4dc10f |
1833 | } |
1834 | |
1835 | } |
1836 | |
1837 | |
1838 | class admin_setting_special_editorfontlist extends admin_setting { |
1839 | |
1840 | var $items; |
1841 | |
1842 | function admin_setting_special_editorfontlist() { |
1843 | global $CFG; |
1844 | $name = 'editorfontlist'; |
1845 | $visiblename = get_string('editorfontlist', 'admin'); |
1846 | $description = get_string('configeditorfontlist', 'admin'); |
6e4dc10f |
1847 | $defaults = array('k0' => 'Trebuchet', |
1848 | 'v0' => 'Trebuchet MS,Verdana,Arial,Helvetica,sans-serif', |
1849 | 'k1' => 'Arial', |
1850 | 'v1' => 'arial,helvetica,sans-serif', |
1851 | 'k2' => 'Courier New', |
1852 | 'v2' => 'courier new,courier,monospace', |
1853 | 'k3' => 'Georgia', |
1854 | 'v3' => 'georgia,times new roman,times,serif', |
1855 | 'k4' => 'Tahoma', |
1856 | 'v4' => 'tahoma,arial,helvetica,sans-serif', |
1857 | 'k5' => 'Times New Roman', |
1858 | 'v5' => 'times new roman,times,serif', |
1859 | 'k6' => 'Verdana', |
1860 | 'v6' => 'verdana,arial,helvetica,sans-serif', |
1861 | 'k7' => 'Impact', |
1862 | 'v7' => 'impact', |
1863 | 'k8' => 'Wingdings', |
1864 | 'v8' => 'wingdings'); |
1865 | parent::admin_setting($name, $visiblename, $description, $defaults); |
1866 | } |
eef868d1 |
1867 | |
6e4dc10f |
1868 | function get_setting() { |
cc73de71 |
1869 | global $CFG; |
1870 | if (isset($CFG->editorfontlist)) { |
1871 | $i = 0; |
1872 | $currentsetting = array(); |
1873 | $items = explode(';', $CFG->editorfontlist); |
1874 | foreach ($items as $item) { |
1875 | $item = explode(':', $item); |
1876 | $currentsetting['k' . $i] = $item[0]; |
1877 | $currentsetting['v' . $i] = $item[1]; |
1878 | $i++; |
1879 | } |
1880 | return $currentsetting; |
1881 | } else { |
1882 | return NULL; |
1883 | } |
6e4dc10f |
1884 | } |
eef868d1 |
1885 | |
6e4dc10f |
1886 | function write_setting($data) { |
eef868d1 |
1887 | |
6e4dc10f |
1888 | // there miiight be an easier way to do this :) |
1889 | // if this is changed, make sure the $defaults array above is modified so that this |
1890 | // function processes it correctly |
eef868d1 |
1891 | |
6e4dc10f |
1892 | $keys = array(); |
1893 | $values = array(); |
eef868d1 |
1894 | |
6e4dc10f |
1895 | foreach ($data as $key => $value) { |
1896 | if (substr($key,0,1) == 'k') { |
1897 | $keys[substr($key,1)] = $value; |
1898 | } elseif (substr($key,0,1) == 'v') { |
1899 | $values[substr($key,1)] = $value; |
1900 | } |
1901 | } |
eef868d1 |
1902 | |
6e4dc10f |
1903 | $result = ''; |
1904 | for ($i = 0; $i < count($keys); $i++) { |
1905 | if (($keys[$i] !== '') && ($values[$i] !== '')) { |
1906 | $result .= clean_param($keys[$i],PARAM_NOTAGS) . ':' . clean_param($values[$i], PARAM_NOTAGS) . ';'; |
1907 | } |
1908 | } |
eef868d1 |
1909 | |
6e4dc10f |
1910 | $result = substr($result, 0, -1); // trim the last semicolon |
eef868d1 |
1911 | |
6e4dc10f |
1912 | return (set_config($this->name, $result) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
1913 | } |
eef868d1 |
1914 | |
6e4dc10f |
1915 | function output_html() { |
eef868d1 |
1916 | |
cc73de71 |
1917 | if ($this->get_setting() === NULL) { |
1918 | $currentsetting = $this->defaultsetting; |
1919 | } else { |
1920 | $currentsetting = $this->get_setting(); |
6e4dc10f |
1921 | } |
eef868d1 |
1922 | |
1beed35f |
1923 | $return = '<div class="form-group">'; |
cc73de71 |
1924 | for ($i = 0; $i < count($currentsetting) / 2; $i++) { |
3c6f7a78 |
1925 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[k' . $i . ']" value="' . $currentsetting['k' . $i] . '" />'; |
6e4dc10f |
1926 | $return .= ' '; |
3c6f7a78 |
1927 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[v' . $i . ']" value="' . $currentsetting['v' . $i] . '" /><br />'; |
6e4dc10f |
1928 | } |
3c6f7a78 |
1929 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[k' . $i . ']" value="" />'; |
6e4dc10f |
1930 | $return .= ' '; |
3c6f7a78 |
1931 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[v' . $i . ']" value="" /><br />'; |
1932 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[k' . ($i + 1) . ']" value="" />'; |
6e4dc10f |
1933 | $return .= ' '; |
3c6f7a78 |
1934 | $return .= '<input type="text" class="form-text" name="s_editorfontlist[v' . ($i + 1) . ']" value="" />'; |
1beed35f |
1935 | $return .= '</div>'; |
6153cf58 |
1936 | |
60a9a6ea |
1937 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
6e4dc10f |
1938 | } |
eef868d1 |
1939 | |
6e4dc10f |
1940 | } |
1941 | |
1942 | class admin_setting_special_editordictionary extends admin_setting_configselect { |
1943 | |
1944 | function admin_setting_special_editordictionary() { |
1945 | $name = 'editordictionary'; |
1946 | $visiblename = get_string('editordictionary','admin'); |
1947 | $description = get_string('configeditordictionary', 'admin'); |
1948 | $choices = $this->editor_get_dictionaries(); |
1949 | if (! is_array($choices)) { |
1950 | $choices = array(''); |
1951 | } |
eef868d1 |
1952 | |
6e4dc10f |
1953 | parent::admin_setting_configselect($name, $visiblename, $description, '', $choices); |
1954 | } |
1955 | |
1956 | // function borrowed from the old moodle/admin/editor.php, slightly modified |
1957 | function editor_get_dictionaries () { |
1958 | /// Get all installed dictionaries in the system |
1959 | |
1960 | global $CFG; |
eef868d1 |
1961 | |
6e4dc10f |
1962 | // error_reporting(E_ALL); // for debug, final version shouldn't have this... |
1963 | clearstatcache(); |
1964 | |
1965 | // If aspellpath isn't set don't even bother ;-) |
1966 | if (empty($CFG->aspellpath)) { |
1967 | return 'Empty aspell path!'; |
1968 | } |
1969 | |
1970 | // Do we have access to popen function? |
1971 | if (!function_exists('popen')) { |
1972 | return 'Popen function disabled!'; |
1973 | } |
eef868d1 |
1974 | |
6e4dc10f |
1975 | $cmd = $CFG->aspellpath; |
1976 | $output = ''; |
1977 | $dictionaries = array(); |
1978 | $dicts = array(); |
1979 | |
1980 | if(!($handle = @popen(escapeshellarg($cmd) .' dump dicts', 'r'))) { |
1981 | return 'Couldn\'t create handle!'; |
1982 | } |
1983 | |
1984 | while(!feof($handle)) { |
1985 | $output .= fread($handle, 1024); |
1986 | } |
1987 | @pclose($handle); |
1988 | |
1989 | $dictionaries = explode(chr(10), $output); |
1990 | |
1991 | // Get rid of possible empty values |
1992 | if (is_array($dictionaries)) { |
1993 | |
1994 | $cnt = count($dictionaries); |
1995 | |
1996 | for ($i = 0; $i < $cnt; $i++) { |
1997 | if (!empty($dictionaries[$i])) { |
2c41b2d7 |
1998 | $dicts[$dictionaries[$i]] = $dictionaries[$i]; |
6e4dc10f |
1999 | } |
2000 | } |
2001 | } |
2002 | |
2003 | if (count($dicts) >= 1) { |
2004 | return $dicts; |
2005 | } |
2006 | |
2007 | return 'Error! Check your aspell installation!'; |
2008 | } |
2009 | |
eef868d1 |
2010 | |
6e4dc10f |
2011 | |
2012 | } |
2013 | |
2014 | |
2015 | class admin_setting_special_editorhidebuttons extends admin_setting { |
2016 | |
2017 | var $name; |
2018 | var $visiblename; |
2019 | var $description; |
2020 | var $items; |
2021 | |
2022 | function admin_setting_special_editorhidebuttons() { |
2023 | $this->name = 'editorhidebuttons'; |
2024 | $this->visiblename = get_string('editorhidebuttons', 'admin'); |
2025 | $this->description = get_string('confeditorhidebuttons', 'admin'); |
2026 | $this->defaultsetting = array(); |
2027 | // weird array... buttonname => buttonimage (assume proper path appended). if you leave buttomimage blank, text will be printed instead |
2028 | $this->items = array('fontname' => '', |
2029 | 'fontsize' => '', |
2030 | 'formatblock' => '', |
2031 | 'bold' => 'ed_format_bold.gif', |
2032 | 'italic' => 'ed_format_italic.gif', |
2033 | 'underline' => 'ed_format_underline.gif', |
2034 | 'strikethrough' => 'ed_format_strike.gif', |
2035 | 'subscript' => 'ed_format_sub.gif', |
2036 | 'superscript' => 'ed_format_sup.gif', |
2037 | 'copy' => 'ed_copy.gif', |
2038 | 'cut' => 'ed_cut.gif', |
2039 | 'paste' => 'ed_paste.gif', |
2040 | 'clean' => 'ed_wordclean.gif', |
2041 | 'undo' => 'ed_undo.gif', |
2042 | 'redo' => 'ed_redo.gif', |
2043 | 'justifyleft' => 'ed_align_left.gif', |
2044 | 'justifycenter' => 'ed_align_center.gif', |
2045 | 'justifyright' => 'ed_align_right.gif', |
2046 | 'justifyfull' => 'ed_align_justify.gif', |
2047 | 'lefttoright' => 'ed_left_to_right.gif', |
2048 | 'righttoleft' => 'ed_right_to_left.gif', |
2049 | 'insertorderedlist' => 'ed_list_num.gif', |
2050 | 'insertunorderedlist' => 'ed_list_bullet.gif', |
2051 | 'outdent' => 'ed_indent_less.gif', |
2052 | 'indent' => 'ed_indent_more.gif', |
2053 | 'forecolor' => 'ed_color_fg.gif', |
2054 | 'hilitecolor' => 'ed_color_bg.gif', |
2055 | 'inserthorizontalrule' => 'ed_hr.gif', |
2056 | 'createanchor' => 'ed_anchor.gif', |
2057 | 'createlink' => 'ed_link.gif', |
2058 | 'unlink' => 'ed_unlink.gif', |
2059 | 'insertimage' => 'ed_image.gif', |
2060 | 'inserttable' => 'insert_table.gif', |
2061 | 'insertsmile' => 'em.icon.smile.gif', |
2062 | 'insertchar' => 'icon_ins_char.gif', |
2063 | 'spellcheck' => 'spell-check.gif', |
2064 | 'htmlmode' => 'ed_html.gif', |
2065 | 'popupeditor' => 'fullscreen_maximize.gif', |
2066 | 'search_replace' => 'ed_replace.gif'); |
2067 | } |
2068 | |
2069 | function get_setting() { |
2070 | global $CFG; |
2071 | return (isset($CFG->{$this->name}) ? explode(' ', $CFG->{$this->name}) : NULL); |
2072 | } |
2073 | |
2074 | function write_setting($data) { |
2075 | $result = array(); |
2076 | if (empty($data)) { $data = array(); } |
2077 | foreach ($data as $key => $value) { |
2078 | if (!in_array($key, array_keys($this->items))) { |
2079 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2080 | } |
2081 | if ($value == '1') { |
2082 | $result[] = $key; |
2083 | } |
2084 | } |
2085 | return (set_config($this->name, implode(' ',$result)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2086 | } |
2087 | |
2088 | function output_html() { |
eef868d1 |
2089 | |
6e4dc10f |
2090 | global $CFG; |
eef868d1 |
2091 | |
6e4dc10f |
2092 | // checkboxes with input name="$this->name[$key]" value="1" |
2093 | // we do 15 fields per column |
eef868d1 |
2094 | |
cc73de71 |
2095 | if ($this->get_setting() === NULL) { |
2096 | $currentsetting = $this->defaultsetting; |
2097 | } else { |
2098 | $currentsetting = $this->get_setting(); |
6e4dc10f |
2099 | } |
eef868d1 |
2100 | |
1beed35f |
2101 | $return = '<div class="form-group">'; |
2102 | $return .= '<table><tr><td valign="top" align="right">'; |
eef868d1 |
2103 | |
6e4dc10f |
2104 | $count = 0; |
eef868d1 |
2105 | |
6e4dc10f |
2106 | foreach($this->items as $key => $value) { |
8ddbd7a6 |
2107 | if ($count % 15 == 0 and $count != 0) { |
2108 | $return .= '</td><td valign="top" align="right">'; |
6e4dc10f |
2109 | } |
eef868d1 |
2110 | |
6e4dc10f |
2111 | $return .= ($value == '' ? get_string($key,'editor') : '<img width="18" height="18" src="' . $CFG->wwwroot . '/lib/editor/htmlarea/images/' . $value . '" alt="' . get_string($key,'editor') . '" title="' . get_string($key,'editor') . '" />') . ' '; |
afee9864 |
2112 | $return .= '<input type="checkbox" class="form-checkbox" value="1" id="id_s_'.$this->name.$key.'" name="s_' . $this->name . '[' . $key . ']"' . (in_array($key,$currentsetting) ? ' checked="checked"' : '') . ' /> '; |
6e4dc10f |
2113 | $count++; |
2114 | if ($count % 15 != 0) { |
2115 | $return .= '<br /><br />'; |
2116 | } |
2117 | } |
eef868d1 |
2118 | |
2119 | $return .= '</td></tr>'; |
6e4dc10f |
2120 | $return .= '</table>'; |
1beed35f |
2121 | $return .= '</div>'; |
6e4dc10f |
2122 | |
60a9a6ea |
2123 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
6e4dc10f |
2124 | } |
2125 | |
2126 | } |
2127 | |
2128 | class admin_setting_backupselect extends admin_setting_configselect { |
2129 | |
2130 | function admin_setting_backupselect($name, $visiblename, $description, $default, $choices) { |
2131 | parent::admin_setting_configselect($name, $visiblename, $description, $default, $choices); |
2132 | } |
2133 | |
2134 | function get_setting() { |
2135 | $backup_config = backup_get_config(); |
2136 | return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL); |
2137 | } |
eef868d1 |
2138 | |
6e4dc10f |
2139 | function write_setting($data) { |
2140 | // check that what we got was in the original choices |
2141 | if (! in_array($data, array_keys($this->choices))) { |
2142 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2143 | } |
eef868d1 |
2144 | |
6e4dc10f |
2145 | return (backup_set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2146 | } |
2147 | |
2148 | } |
2149 | |
2150 | class admin_setting_special_backupsaveto extends admin_setting_configtext { |
2151 | |
2152 | function admin_setting_special_backupsaveto() { |
2153 | $name = 'backup_sche_destination'; |
2154 | $visiblename = get_string('saveto'); |
2155 | $description = get_string('backupsavetohelp'); |
348d6827 |
2156 | parent::admin_setting_configtext($name, $visiblename, $description, ''); |
6e4dc10f |
2157 | } |
eef868d1 |
2158 | |
6e4dc10f |
2159 | function get_setting() { |
2160 | $backup_config = backup_get_config(); |
2161 | return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL); |
2162 | } |
eef868d1 |
2163 | |
6e4dc10f |
2164 | function write_setting($data) { |
348d6827 |
2165 | $data = trim($data); |
2166 | if (!empty($data) and !is_dir($data)) { |
6e4dc10f |
2167 | return get_string('pathnotexists') . '<br />'; |
2168 | } |
2169 | return (backup_set_config($this->name, $data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2170 | } |
2171 | |
2172 | } |
2173 | |
2174 | class admin_setting_backupcheckbox extends admin_setting_configcheckbox { |
2175 | |
2176 | function admin_setting_backupcheckbox($name, $visiblename, $description, $default) { |
2177 | parent::admin_setting_configcheckbox($name, $visiblename, $description, $default); |
2178 | } |
2179 | |
2180 | function write_setting($data) { |
2181 | if ($data == '1') { |
2182 | return (backup_set_config($this->name, 1) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2183 | } else { |
2184 | return (backup_set_config($this->name, 0) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2185 | } |
2186 | } |
eef868d1 |
2187 | |
6e4dc10f |
2188 | function get_setting() { |
2189 | $backup_config = backup_get_config(); |
2190 | return (isset($backup_config->{$this->name}) ? $backup_config->{$this->name} : NULL); |
2191 | } |
2192 | |
2193 | } |
2194 | |
2195 | class admin_setting_special_backuptime extends admin_setting_configtime { |
2196 | |
2197 | function admin_setting_special_backuptime() { |
2198 | $name = 'backup_sche_hour'; |
2199 | $name2 = 'backup_sche_minute'; |
2200 | $visiblename = get_string('executeat'); |
2201 | $description = get_string('backupexecuteathelp'); |
2202 | $default = array('h' => 0, 'm' => 0); |
2203 | parent::admin_setting_configtime($name, $name2, $visiblename, $description, $default); |
2204 | } |
eef868d1 |
2205 | |
6e4dc10f |
2206 | function get_setting() { |
2207 | $backup_config = backup_get_config(); |
9fd9df20 |
2208 | return (isset($backup_config->{$this->name}) && isset($backup_config->{$this->name}) ? array('h'=>$backup_config->{$this->name}, 'm'=>$backup_config->{$this->name2}) : NULL); |
6e4dc10f |
2209 | } |
eef868d1 |
2210 | |
6e4dc10f |
2211 | function write_setting($data) { |
2212 | // check that what we got was in the original choices |
2213 | if (!(in_array($data['h'], array_keys($this->choices)) && in_array($data['m'], array_keys($this->choices2)))) { |
2214 | return get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2215 | } |
eef868d1 |
2216 | |
2217 | return (backup_set_config($this->name, $data['h']) && backup_set_config($this->name2, $data['m']) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
6e4dc10f |
2218 | } |
eef868d1 |
2219 | |
6e4dc10f |
2220 | } |
2221 | |
2222 | class admin_setting_special_backupdays extends admin_setting { |
2223 | |
2224 | function admin_setting_special_backupdays() { |
2225 | $name = 'backup_sche_weekdays'; |
2226 | $visiblename = get_string('schedule'); |
2227 | $description = get_string('backupschedulehelp'); |
6727c175 |
2228 | $default = array('u' => 0, 'm' => 0, 't' => 0, 'w' => 0, 'r' => 0, 'f' => 0, 's' => 0); |
2229 | parent::admin_setting($name, $visiblename, $description, $default); |
6e4dc10f |
2230 | } |
eef868d1 |
2231 | |
6e4dc10f |
2232 | function get_setting() { |
2233 | $backup_config = backup_get_config(); |
cc73de71 |
2234 | if (isset($backup_config->{$this->name})) { |
2235 | $currentsetting = $backup_config->{$this->name}; |
2236 | return array('u' => substr($currentsetting, 0, 1), |
2237 | 'm' => substr($currentsetting, 1, 1), |
2238 | 't' => substr($currentsetting, 2, 1), |
2239 | 'w' => substr($currentsetting, 3, 1), |
2240 | 'r' => substr($currentsetting, 4, 1), |
2241 | 'f' => substr($currentsetting, 5, 1), |
2242 | 's' => substr($currentsetting, 6, 1)); |
2243 | } else { |
2244 | return NULL; |
2245 | } |
6e4dc10f |
2246 | } |
eef868d1 |
2247 | |
6e4dc10f |
2248 | function output_html() { |
eef868d1 |
2249 | |
cc73de71 |
2250 | if ($this->get_setting() === NULL) { |
2251 | $currentsetting = $this->defaultsetting; |
2252 | } else { |
2253 | $currentsetting = $this->get_setting(); |
6e4dc10f |
2254 | } |
eef868d1 |
2255 | |
cc73de71 |
2256 | // rewrite for simplicity |
eef868d1 |
2257 | $currentsetting = $currentsetting['u'] . $currentsetting['m'] . $currentsetting['t'] . $currentsetting['w'] . |
cc73de71 |
2258 | $currentsetting['r'] . $currentsetting['f'] . $currentsetting['s']; |
eef868d1 |
2259 | |
60a9a6ea |
2260 | $return = '<table><tr><td><div style="text-align:center"> ' . get_string('sunday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2261 | get_string('monday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('tuesday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2262 | get_string('wednesday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('thursday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2263 | get_string('friday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('saturday', 'calendar') . ' </div></td></tr><tr>' . |
2264 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'u" name="s_'. $this->name .'[u]" value="1" ' . (substr($currentsetting,0,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2265 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'m" name="s_'. $this->name .'[m]" value="1" ' . (substr($currentsetting,1,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2266 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'t" name="s_'. $this->name .'[t]" value="1" ' . (substr($currentsetting,2,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2267 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'w" name="s_'. $this->name .'[w]" value="1" ' . (substr($currentsetting,3,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2268 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'r" name="s_'. $this->name .'[r]" value="1" ' . (substr($currentsetting,4,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2269 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'f" name="s_'. $this->name .'[f]" value="1" ' . (substr($currentsetting,5,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2270 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'s" name="s_'. $this->name .'[s]" value="1" ' . (substr($currentsetting,6,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
6153cf58 |
2271 | '</tr></table>'; |
2272 | |
60a9a6ea |
2273 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
eef868d1 |
2274 | |
6e4dc10f |
2275 | } |
eef868d1 |
2276 | |
6e4dc10f |
2277 | // we're using the array trick (see http://ca.php.net/manual/en/faq.html.php#faq.html.arrays) to get the data passed to use without having to modify |
2278 | // admin_settingpage (note that admin_settingpage only calls write_setting with the data that matches $this->name... so if we have multiple form fields, |
2279 | // they MUST go into an array named $this->name, or else we won't receive them here |
2280 | function write_setting($data) { |
2281 | $week = 'umtwrfs'; |
2282 | $result = array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0); |
9fd9df20 |
2283 | if (!empty($data)) { |
2284 | foreach($data as $key => $value) { |
2285 | if ($value == '1') { |
2286 | $result[strpos($week, $key)] = 1; |
2287 | } |
2288 | } |
6e4dc10f |
2289 | } |
2290 | return (backup_set_config($this->name, implode('',$result)) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2291 | } |
2292 | } |
2293 | |
ee437bbc |
2294 | class admin_setting_special_debug extends admin_setting_configselect { |
6e4dc10f |
2295 | |
2296 | function admin_setting_special_debug() { |
2297 | $name = 'debug'; |
2298 | $visiblename = get_string('debug', 'admin'); |
2299 | $description = get_string('configdebug', 'admin'); |
7eb0b60a |
2300 | $choices = array( DEBUG_NONE => get_string('debugnone', 'admin'), |
2301 | DEBUG_MINIMAL => get_string('debugminimal', 'admin'), |
2302 | DEBUG_NORMAL => get_string('debugnormal', 'admin'), |
38d2d43b |
2303 | DEBUG_ALL => get_string('debugall', 'admin'), |
2304 | DEBUG_DEVELOPER => get_string('debugdeveloper', 'admin') |
ee437bbc |
2305 | ); |
2306 | parent::admin_setting_configselect($name, $visiblename, $description, '', $choices); |
6e4dc10f |
2307 | } |
2308 | |
ee437bbc |
2309 | function get_setting() { |
2310 | global $CFG; |
cc73de71 |
2311 | if (isset($CFG->debug)) { |
cc73de71 |
2312 | return $CFG->debug; |
2313 | } else { |
2314 | return NULL; |
ee437bbc |
2315 | } |
6e4dc10f |
2316 | } |
2317 | |
ee437bbc |
2318 | function write_setting($data) { |
2319 | return (set_config($this->name,$data) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
6e4dc10f |
2320 | } |
2321 | |
2322 | } |
2323 | |
2324 | |
2325 | class admin_setting_special_calendar_weekend extends admin_setting { |
2326 | |
2327 | function admin_setting_special_calendar_weekend() { |
2328 | $name = 'calendar_weekend'; |
2329 | $visiblename = get_string('calendar_weekend', 'admin'); |
2330 | $description = get_string('helpweekenddays', 'admin'); |
b91b1f92 |
2331 | $default = array('u' => 1, 'm' => 0, 't' => 0, 'w' => 0, 'r' => 0, 'f' => 0, 's' => 1); |
2332 | parent::admin_setting($name, $visiblename, $description, $default); |
6e4dc10f |
2333 | } |
2334 | |
2335 | function get_setting() { |
2336 | global $CFG; |
2337 | if (isset($CFG->{$this->name})) { |
b91b1f92 |
2338 | $currentsetting = decbin($CFG->{$this->name}); |
2339 | $currentsetting = str_pad($currentsetting, 7, '0', STR_PAD_LEFT); |
2340 | return array('u' => substr($currentsetting, 0, 1), |
2341 | 'm' => substr($currentsetting, 1, 1), |
2342 | 't' => substr($currentsetting, 2, 1), |
2343 | 'w' => substr($currentsetting, 3, 1), |
2344 | 'r' => substr($currentsetting, 4, 1), |
2345 | 'f' => substr($currentsetting, 5, 1), |
2346 | 's' => substr($currentsetting, 6, 1)); |
6e4dc10f |
2347 | } else { |
2348 | return NULL; |
2349 | } |
2350 | } |
eef868d1 |
2351 | |
6e4dc10f |
2352 | function write_setting($data) { |
2353 | $week = 'umtwrfs'; |
2354 | $result = array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0); |
b91b1f92 |
2355 | if (!empty($data)) { |
2356 | foreach($data as $key => $value) { |
2357 | if ($value == '1') { |
2358 | $result[strpos($week, $key)] = 1; |
2359 | } |
2360 | } |
6e4dc10f |
2361 | } |
2362 | return (set_config($this->name, bindec(implode('',$result))) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2363 | } |
eef868d1 |
2364 | |
6e4dc10f |
2365 | function output_html() { |
2366 | |
cc73de71 |
2367 | if ($this->get_setting() === NULL) { |
2368 | $currentsetting = $this->defaultsetting; |
2369 | } else { |
2370 | $currentsetting = $this->get_setting(); |
6e4dc10f |
2371 | } |
cc73de71 |
2372 | |
b91b1f92 |
2373 | // rewrite for simplicity |
2374 | $currentsetting = $currentsetting['u'] . $currentsetting['m'] . $currentsetting['t'] . $currentsetting['w'] . |
2375 | $currentsetting['r'] . $currentsetting['f'] . $currentsetting['s']; |
3b904bc9 |
2376 | |
038bf621 |
2377 | $return = '<table><tr><td><div style="text-align:center"> ' . get_string('sunday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2378 | get_string('monday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('tuesday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2379 | get_string('wednesday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('thursday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . |
2380 | get_string('friday', 'calendar') . ' </div></td><td><div style="text-align:center"> ' . get_string('saturday', 'calendar') . ' </div></td></tr><tr>' . |
2381 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'u" name="s_'. $this->name .'[u]" value="1" ' . (substr($currentsetting,0,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2382 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'m" name="s_'. $this->name .'[m]" value="1" ' . (substr($currentsetting,1,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2383 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'t" name="s_'. $this->name .'[t]" value="1" ' . (substr($currentsetting,2,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2384 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'w" name="s_'. $this->name .'[w]" value="1" ' . (substr($currentsetting,3,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2385 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'r" name="s_'. $this->name .'[r]" value="1" ' . (substr($currentsetting,4,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2386 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'f" name="s_'. $this->name .'[f]" value="1" ' . (substr($currentsetting,5,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
2387 | '<td><div style="text-align:center"><input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'s" name="s_'. $this->name .'[s]" value="1" ' . (substr($currentsetting,6,1) == '1' ? 'checked="checked"' : '') . ' /></div></td>' . |
6153cf58 |
2388 | '</tr></table>'; |
2389 | |
038bf621 |
2390 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
eef868d1 |
2391 | |
6e4dc10f |
2392 | } |
2393 | |
2394 | } |
2395 | |
73afaf5b |
2396 | /* |
2397 | * this is used in config->appearance->gradeconfig |
5a412dbf |
2398 | */ |
0909d44e |
2399 | class admin_setting_special_gradebookroles extends admin_setting { |
5a412dbf |
2400 | |
0909d44e |
2401 | function admin_setting_special_gradebookroles() { |
2402 | $name = 'gradebookroles'; |
73afaf5b |
2403 | $visiblename = get_string('gradebookroles', 'admin'); |
2404 | $description = get_string('configgradebookroles', 'admin'); |
7aa3e196 |
2405 | $default = array(5=>'1'); // The student role in a default install |
8a2cb2fa |
2406 | parent::admin_setting($name, $visiblename, $description, $default); |
5a412dbf |
2407 | } |
2408 | |
2409 | function get_setting() { |
2410 | global $CFG; |
8a2cb2fa |
2411 | if (!empty($CFG->{$this->name})) { |
60f7d402 |
2412 | $result = explode(',', $CFG->{$this->name}); |
2413 | foreach ($result as $roleid) { |
2414 | $array[$roleid] = 1; |
2415 | } |
2416 | return $array; |
5a412dbf |
2417 | } else { |
3fae9f57 |
2418 | return null; |
5a412dbf |
2419 | } |
2420 | } |
2421 | |
2422 | function write_setting($data) { |
2423 | if (!empty($data)) { |
2424 | $str = ''; |
0909d44e |
2425 | foreach ($data as $key => $value) { |
5a412dbf |
2426 | if ($value) { |
2427 | $str .= $key.','; |
2428 | } |
2429 | } |
2430 | return set_config($this->name, rtrim($str, ","))?'':get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2431 | } else { |
73afaf5b |
2432 | return set_config($this->name, '')?'':get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2433 | } |
5a412dbf |
2434 | } |
2435 | |
2436 | function output_html() { |
2437 | |
2438 | if ($this->get_setting() === NULL) { |
2439 | $currentsetting = $this->defaultsetting; |
2440 | } else { |
2441 | $currentsetting = $this->get_setting(); |
2442 | } |
5a412dbf |
2443 | // from to process which roles to display |
2444 | if ($roles = get_records('role')) { |
73afaf5b |
2445 | $return = '<div class="form-group">'; |
2446 | $first = true; |
2447 | foreach ($roles as $roleid=>$role) { |
60f7d402 |
2448 | if (is_array($currentsetting) && in_array($roleid, array_keys($currentsetting))) { |
fb132873 |
2449 | $checked = ' checked="checked"'; |
5a412dbf |
2450 | } else { |
73afaf5b |
2451 | $checked = ''; |
5a412dbf |
2452 | } |
73afaf5b |
2453 | if ($first) { |
2454 | $first = false; |
2455 | } else { |
2456 | $return .= '<br />'; |
2457 | } |
4eb777c2 |
2458 | $return .= '<input type="checkbox" name="s_'.$this->name.'['.$roleid.']" value="1"'.$checked.' /> '.$role->name; |
5a412dbf |
2459 | } |
73afaf5b |
2460 | $return .= '</div>'; |
5a412dbf |
2461 | } |
73afaf5b |
2462 | |
60a9a6ea |
2463 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
5a412dbf |
2464 | |
2465 | } |
2466 | |
2467 | } |
6e4dc10f |
2468 | |
d42c64ba |
2469 | /* |
2470 | * this is used in config->appearance->coursemanager |
2471 | * (which roles to show on course decription page) |
2472 | */ |
2473 | class admin_setting_special_coursemanager extends admin_setting { |
2474 | |
2475 | function admin_setting_special_coursemanager() { |
2476 | $name = 'coursemanager'; |
2477 | $visiblename = get_string('coursemanager', 'admin'); |
2478 | $description = get_string('configcoursemanager', 'admin'); |
2479 | $default = array(3=>'1'); // The teahcer role in a default install |
2480 | parent::admin_setting($name, $visiblename, $description, $default); |
2481 | } |
2482 | |
2483 | function get_setting() { |
2484 | |
2485 | global $CFG; |
2486 | if (!empty($CFG->{$this->name})) { |
2487 | $result = explode(',', $CFG->{$this->name}); |
2488 | foreach ($result as $roleid) { |
2489 | $array[$roleid] = 1; |
2490 | } |
2491 | return $array; |
2492 | } else { |
2493 | return null; |
2494 | } |
2495 | } |
2496 | |
2497 | function write_setting($data) { |
2498 | |
2499 | if (!empty($data)) { |
2500 | $str = ''; |
2501 | foreach ($data as $key => $value) { |
2502 | if ($value) { |
2503 | $str .= $key.','; |
2504 | } |
2505 | } |
2506 | return set_config($this->name, rtrim($str, ","))?'':get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2507 | } else { |
2508 | return set_config($this->name, '')?'':get_string('errorsetting', 'admin') . $this->visiblename . '<br />'; |
2509 | } |
2510 | } |
2511 | |
2512 | function output_html() { |
2513 | |
2514 | if ($this->get_setting() === NULL) { |
2515 | $currentsetting = $this->defaultsetting; |
2516 | } else { |
2517 | $currentsetting = $this->get_setting(); |
2518 | } |
2519 | // from to process which roles to display |
2520 | if ($roles = get_records('role')) { |
2521 | $return = '<div class="form-group">'; |
2522 | $first = true; |
2523 | foreach ($roles as $roleid=>$role) { |
2524 | if (is_array($currentsetting) && in_array($roleid, array_keys($currentsetting))) { |
2525 | $checked = 'checked="checked"'; |
2526 | } else { |
2527 | $checked = ''; |
2528 | } |
2529 | if ($first) { |
2530 | $first = false; |
2531 | } else { |
2532 | $return .= '<br />'; |
2533 | } |
7203167d |
2534 | $return .= '<input type="checkbox" name="s_'.$this->name.'['.$roleid.']" value="1" '.$checked.' /> '.$role->name; |
d42c64ba |
2535 | } |
2536 | $return .= '</div>'; |
2537 | } |
60a9a6ea |
2538 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description, false); |
d42c64ba |
2539 | } |
2540 | } |
2541 | |
6e4dc10f |
2542 | class admin_setting_special_perfdebug extends admin_setting_configcheckbox { |
2543 | |
2544 | function admin_setting_special_perfdebug() { |
2545 | $name = 'perfdebug'; |
2546 | $visiblename = get_string('perfdebug', 'admin'); |
2547 | $description = get_string('configperfdebug', 'admin'); |
2548 | parent::admin_setting_configcheckbox($name, $visiblename, $description, ''); |
2549 | } |
2550 | |
2551 | function write_setting($data) { |
d42c64ba |
2552 | |
6e4dc10f |
2553 | if ($data == '1') { |
2554 | return (set_config($this->name,15) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2555 | } else { |
2556 | return (set_config($this->name,7) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2557 | } |
2558 | } |
2559 | |
2560 | function output_html() { |
d42c64ba |
2561 | |
cc73de71 |
2562 | if ($this->get_setting() === NULL) { |
2563 | $currentsetting = $this->defaultsetting; |
2564 | } else { |
2565 | $currentsetting = $this->get_setting(); |
2566 | } |
eef868d1 |
2567 | |
3c6f7a78 |
2568 | $return = '<input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'" name="s_'. $this->name .'" value="1" ' . ($currentsetting == 15 ? 'checked="checked"' : '') . ' />'; |
fc52aa6e |
2569 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description); |
6e4dc10f |
2570 | } |
2571 | |
2572 | } |
2573 | |
47b8b9eb |
2574 | class admin_setting_special_debugdisplay extends admin_setting_configcheckbox { |
2575 | |
2576 | function admin_setting_special_debugdisplay() { |
2577 | $name = 'debugdisplay'; |
2578 | $visiblename = get_string('debugdisplay', 'admin'); |
2579 | $description = get_string('configdebugdisplay', 'admin'); |
6349a3ba |
2580 | $default = ini_get('display_errors'); |
2581 | parent::admin_setting_configcheckbox($name, $visiblename, $description, $default); |
47b8b9eb |
2582 | } |
2583 | |
2584 | function write_setting($data) { |
2585 | |
2586 | if ($data == '1') { |
2587 | return (set_config($this->name,1) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2588 | } else { |
2589 | return (set_config($this->name,0) ? '' : get_string('errorsetting', 'admin') . $this->visiblename . '<br />'); |
2590 | } |
2591 | } |
2592 | |
2593 | function output_html() { |
2594 | |
2595 | if ($this->get_setting() === NULL) { |
6349a3ba |
2596 | $currentsetting = $this->defaultsetting; |
47b8b9eb |
2597 | } else { |
2598 | $currentsetting = $this->get_setting(); |
2599 | } |
2600 | |
2601 | $return = '<input type="checkbox" class="form-checkbox" id="id_s_'.$this->name.'" name="s_'. $this->name .'" value="1" ' . ($currentsetting == 1 ? 'checked="checked"' : '') . ' />'; |
2602 | return format_admin_setting($this->name, $this->visiblename, $return, $this->description); |
2603 | } |
2604 | |
2605 | } |
2606 | |
2607 | |
6e4dc10f |
2608 | // Code for a function that helps externalpages print proper headers and footers |
2609 | // N.B.: THIS FUNCTION HANDLES AUTHENTICATION |
2610 | function admin_externalpage_setup($section, $adminroot) { |
2611 | |
2612 | global $CFG, $PAGE, $USER; |
eef868d1 |
2613 | |
6e4dc10f |
2614 | require_once($CFG->libdir . '/blocklib.php'); |
02cc05a7 |
2615 | require_once($CFG->dirroot . '/'.$CFG->admin.'/pagelib.php'); |
eef868d1 |
2616 | |
02cc05a7 |
2617 | page_map_class(PAGE_ADMIN, 'page_admin'); |
6e4dc10f |
2618 | |
e9a20759 |
2619 | $PAGE = page_create_object(PAGE_ADMIN, 0); // there must be any constant id number |
6e4dc10f |
2620 | |
02cc05a7 |
2621 | $PAGE->init_extra($section); // hack alert! |
6e4dc10f |
2622 | |
2623 | $root = $adminroot->locate($PAGE->section); |
2624 | |
2625 | if ($site = get_site()) { |
2626 | require_login(); |
2627 | } else { |
6859360c |
2628 | redirect($CFG->wwwroot . '/'.$CFG->admin.'/index.php'); |
6e4dc10f |
2629 | die; |
2630 | } |
2631 | |
2632 | if (!is_a($root, 'admin_externalpage')) { |
2633 | error(get_string('sectionerror','admin')); |
2634 | die; |
2635 | } |
2636 | |
2637 | // this eliminates our need to authenticate on the actual pages |
2638 | if (!($root->check_access())) { |
2639 | error(get_string('accessdenied', 'admin')); |
2640 | die; |
2641 | } |
eef868d1 |
2642 | |
6e4dc10f |
2643 | $adminediting = optional_param('adminedit', -1, PARAM_BOOL); |
eef868d1 |
2644 | |
6e4dc10f |
2645 | if (!isset($USER->adminediting)) { |
2646 | $USER->adminediting = false; |
2647 | } |
eef868d1 |
2648 | |
6e4dc10f |
2649 | if ($PAGE->user_allowed_editing()) { |
2650 | if ($adminediting == 1) { |
2651 | $USER->adminediting = true; |
2652 | } elseif ($adminediting == 0) { |
2653 | $USER->adminediting = false; |
2654 | } |
2655 | } |
eef868d1 |
2656 | |
6e4dc10f |
2657 | } |
2658 | |
2659 | function admin_externalpage_print_header($adminroot) { |
2660 | |
ce821fda |
2661 | global $CFG, $PAGE, $SITE, $THEME; |
eef868d1 |
2662 | |
b1ce7811 |
2663 | if (!empty($SITE->fullname)) { |
2664 | $pageblocks = blocks_setup($PAGE); |
6e4dc10f |
2665 | |
e524c0ed |
2666 | $preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, |
2667 | blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), |
b1ce7811 |
2668 | BLOCK_L_MAX_WIDTH); |
b1ce7811 |
2669 | $PAGE->print_header(); |
5577ceb3 |
2670 | echo '<table id="layout-table" summary=""><tr>'; |
b1ce7811 |
2671 | echo '<td style="width: ' . $preferred_width_left . 'px;" id="left-column">'; |
ce821fda |
2672 | if (!empty($THEME->roundcorners)) { |
2673 | echo '<div class="bt"><div></div></div>'; |
2674 | echo '<div class="i1"><div class="i2"><div class="i3">'; |
2675 | } |
b1ce7811 |
2676 | blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); |
ce821fda |
2677 | if (!empty($THEME->roundcorners)) { |
2678 | echo '</div></div></div>'; |
2679 | echo '<div class="bb"><div></div></div>'; |
2680 | } |
b1ce7811 |
2681 | echo '</td>'; |
a06c8c2c |
2682 | echo '<td id="middle-column">'; |
ce821fda |
2683 | if (!empty($THEME->roundcorners)) { |
2684 | echo '<div class="bt"><div></div></div>'; |
2685 | echo '<div class="i1"><div class="i2"><div class="i3">'; |
2686 | } |
b1ce7811 |
2687 | } else { |
2688 | print_header(); |
2689 | } |
6e4dc10f |
2690 | } |
2691 | |
2692 | function admin_externalpage_print_footer($adminroot) { |
2693 | |
ce821fda |
2694 | global $CFG, $PAGE, $SITE, $THEME; |
b1ce7811 |
2695 | |
2696 | if (!empty($SITE->fullname)) { |
2697 | $pageblocks = blocks_setup($PAGE); |
e524c0ed |
2698 | $preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, |
2699 | blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), |
b1ce7811 |
2700 | BLOCK_R_MAX_WIDTH); |
ce821fda |
2701 | if (!empty($THEME->roundcorners)) { |
2702 | echo '</div></div></div>'; |
2703 | echo '<div class="bb"><div></div></div>'; |
2704 | } |
b1ce7811 |
2705 | echo '</td>'; |
d5271d3d |
2706 | if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT)) { |
ec3938f3 |
2707 | echo '<td style="width: ' . $preferred_width_right . 'px;" id="right-column">'; |
2708 | if (!empty($THEME->roundcorners)) { |
2709 | echo '<div class="bt"><div></div></div>'; |
2710 | echo '<div class="i1"><div class="i2"><div class="i3">'; |
2711 | } |
2712 | blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); |
2713 | if (!empty($THEME->roundcorners)) { |
2714 | echo '</div></div></div>'; |
2715 | echo '<div class="bb"><div></div></div>'; |
2716 | } |
2717 | echo '</td>'; |
ce821fda |
2718 | } |
ec3938f3 |
2719 | echo '</tr></table>'; |
b1ce7811 |
2720 | } |
6e4dc10f |
2721 | print_footer(); |
6e4dc10f |
2722 | } |
2723 | |
2724 | function admin_get_root() { |
2725 | global $CFG; |
2726 | |
2727 | static $ADMIN; |
2728 | |
2729 | if (!isset($ADMIN)) { |
2730 | // start the admin tree! |
2058a0a1 |
2731 | $ADMIN = new admin_category('root', get_string("administration")); |
6e4dc10f |
2732 | // we process this file first to get categories up and running |
6859360c |
2733 | include($CFG->dirroot . '/'.$CFG->admin.'/settings/top.php'); |
6e4dc10f |
2734 | |
2735 | // now we process all other files in admin/settings to build the |
2736 | // admin tree |
6859360c |
2737 | foreach (glob($CFG->dirroot . '/'.$CFG->admin.'/settings/*.php') as $file) { |
2738 | if ($file != $CFG->dirroot . '/'.$CFG->admin.'/settings/top.php') { |
6e4dc10f |
2739 | include_once($file); |
2740 | } |
2741 | } |
2742 | } |
eef868d1 |
2743 | |
6e4dc10f |
2744 | return $ADMIN; |
2745 | } |
2746 | |
2747 | /// settings utiliti functions |
2748 | |
2749 | // n.b. this function unconditionally applies default settings |
2750 | function apply_default_settings(&$node) { |
2751 | |
2752 | global $CFG; |
2753 | |
2754 | if (is_a($node, 'admin_category')) { |
2755 | $entries = array_keys($node->children); |
2756 | foreach ($entries as $entry) { |
2757 | apply_default_settings($node->children[$entry]); |
2758 | } |
2759 | return; |
eef868d1 |
2760 | } |
6e4dc10f |
2761 | |
eef868d1 |
2762 | if (is_a($node, 'admin_settingpage')) { |
6e4dc10f |
2763 | foreach ($node->settings as $setting) { |
2764 | $CFG->{$setting->name} = $setting->defaultsetting; |
2765 | $setting->write_setting($setting->defaultsetting); |
2766 | unset($setting); // needed to prevent odd (imho) reference behaviour |
2767 | // see http://www.php.net/manual/en/language.references.whatdo.php#AEN6399 |
2768 | } |
2769 | return; |
2770 | } |
2771 | |
2772 | return; |
2773 | |
2774 | } |
2775 | |
2776 | // n.b. this function unconditionally applies default settings |
2777 | function apply_default_exception_settings($defaults) { |
2778 | |
2779 | global $CFG; |
2780 | |
2781 | foreach($defaults as $key => $value) { |
2782 | $CFG->$key = $value; |
2783 | set_config($key, $value); |
2784 | } |
2785 | |
2786 | } |
2787 | |
fbe31d22 |
2788 | function format_admin_setting($name, $title='', $form='', $description='', $label=true) { |
2789 | |
2790 | // sometimes the id is not id_s_name, but id_s_name_m or something, and this does not validate |
2791 | if ($label) { |
2792 | $labelfor = 'for = "id_s_'.$name.'"'; |
2793 | } else { |
2794 | $labelfor = ''; |
2795 | } |
2796 | |
2797 | $str = "\n". |
fc52aa6e |
2798 | '<div class="form-item" id="admin-'.$name.'">'."\n". |
fbe31d22 |
2799 | '<label '.$labelfor.'>'.$title."\n". |
6153cf58 |
2800 | ' <span class="form-shortname">'.$name.'</span>'."\n". |
2801 | '</label>'."\n". |
2802 | $form."\n". |
edb6cba4 |
2803 | '<div class="description">'.$description.'</div>'."\n". |
23586aca |
2804 | '</div>'. |
2805 | "\n\n"; |
fbe31d22 |
2806 | |
2807 | return $str; |
2c8766df |
2808 | } |
2809 | |
d210e12e |
2810 | /* |
2811 | * Try to upgrade the given language pack (or current language) |
2812 | * If it doesn't work, fail silently and return false |
2813 | */ |
2814 | function upgrade_language_pack($lang='') { |
2815 | global $CFG; |
2816 | |
2817 | if (empty($lang)) { |
2818 | $lang = current_language(); |
2819 | } |
2820 | |
2821 | if ($lang == 'en_utf8') { |
2822 | return true; // Nothing to do |
2823 | } |
2824 | |
2825 | notify(get_string('langimport', 'admin').': '.$lang.' ... ', 'notifysuccess'); |
2826 | |
2827 | @mkdir ($CFG->dataroot.'/temp/'); //make it in case it's a fresh install, it might not be there |
2828 | @mkdir ($CFG->dataroot.'/lang/'); |
2829 | |
2830 | require_once($CFG->libdir.'/componentlib.class.php'); |
2831 | |
2832 | if ($cd = new component_installer('http://download.moodle.org', 'lang16', $lang.'.zip', 'languages.md5', 'lang')) { |
2833 | $status = $cd->install(); //returns ERROR | UPTODATE | INSTALLED |
2834 | |
2835 | if ($status == INSTALLED) { |
2836 | debugging('Downloading successful: '.$lang); |
2837 | @unlink($CFG->dataroot.'/cache/languages'); |
2838 | return true; |
2839 | } |
2840 | } |
2841 | |
2842 | return false; |
2843 | } |
2844 | |
6153cf58 |
2845 | ?> |