merfed fix for 6178
[moodle.git] / lib / adminlib.php
CommitLineData
88a7228a 1<?php //
2 //
3
4/**
5 * adminlib.php - Contains functions that only administrators will ever need to use
6 *
7 * @author Martin Dougiamas
8 * @version $Id$
9 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
10 * @package moodlecore
11 */
12
13/**
ead29342 14 * Upgrade plugins
88a7228a 15 *
16 * @uses $db
17 * @uses $CFG
ead29342 18 * @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype')
19 * @param string $dir The directory where the plugins are located (e.g. 'question/questiontypes')
20 * @param string $return The url to prompt the user to continue to
88a7228a 21 */
ead29342 22function upgrade_plugins($type, $dir, $return) {
e69ef14b 23 global $CFG, $db;
173cc1c3 24
ead29342 25 if (!$plugs = get_list_of_plugins($dir) ) {
26 error('No '.$type.' plugins installed!');
173cc1c3 27 }
28
ead29342 29 foreach ($plugs as $plug) {
173cc1c3 30
ead29342 31 $fullplug = $CFG->dirroot .'/'.$dir.'/'. $plug;
173cc1c3 32
ead29342 33 unset($plugin);
173cc1c3 34
ead29342 35 if ( is_readable($fullplug .'/version.php')) {
36 include_once($fullplug .'/version.php'); // defines $plugin with version etc
173cc1c3 37 } else {
38 continue; // Nothing to do.
39 }
40
ead29342 41 if ( is_readable($fullplug .'/db/'. $CFG->dbtype .'.php')) {
42 include_once($fullplug .'/db/'. $CFG->dbtype .'.php'); // defines upgrading function
173cc1c3 43 } else {
44 continue;
45 }
46
ead29342 47 if (!isset($plugin)) {
173cc1c3 48 continue;
49 }
50
ead29342 51 if (!empty($plugin->requires)) {
52 if ($plugin->requires > $CFG->version) {
53 $info->pluginname = $plug;
54 $info->pluginversion = $plugin->version;
173cc1c3 55 $info->currentmoodle = $CFG->version;
ead29342 56 $info->requiremoodle = $plugin->requires;
57 notify(get_string('pluginrequirementsnotmet', 'error', $info));
173cc1c3 58 unset($info);
59 continue;
60 }
61 }
62
ead29342 63 $plugin->name = $plug; // The name MUST match the directory
173cc1c3 64
ead29342 65 $pluginversion = $type.'_'.$plug.'_version';
173cc1c3 66
ead29342 67 if (!isset($CFG->$pluginversion)) {
68 set_config($pluginversion, 0);
173cc1c3 69 }
70
ead29342 71 if ($CFG->$pluginversion == $plugin->version) {
173cc1c3 72 // do nothing
ead29342 73 } else if ($CFG->$pluginversion < $plugin->version) {
74 if (empty($updated_plugins)) {
75 $strpluginsetup = get_string('pluginsetup');
a36f058e 76 print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '',
77 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
78 false, '&nbsp;', '&nbsp;');
173cc1c3 79 }
ead29342 80 print_heading($plugin->name .' plugin needs upgrading');
d87a9d73 81
82 if ($CFG->$pluginversion == 0) { // It's a new install of this plugin
83 if (file_exists($fullplug .'/db/'. $CFG->dbtype .'.sql')) {
84 $db->debug = true;
85 @set_time_limit(0); // To allow slow databases to complete the long SQL
86 if (modify_database($fullplug .'/db/'. $CFG->dbtype .'.sql')) {
87 // OK so far, now update the plugins record
88 set_config($pluginversion, $plugin->version);
89 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
90 } else {
91 notify('Installing '. $plugin->name .' FAILED!');
92 }
93 $db->debug = false;
94 } else { // We'll assume no tables are necessary
ead29342 95 set_config($pluginversion, $plugin->version);
96 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
d87a9d73 97 }
98 } else { // Upgrade existing install
99 $upgrade_function = $type.'_'.$plugin->name .'_upgrade';
100 if (function_exists($upgrade_function)) {
101 $db->debug=true;
102 if ($upgrade_function($CFG->$pluginversion)) {
103 $db->debug=false;
104 // OK so far, now update the plugins record
105 set_config($pluginversion, $plugin->version);
106 notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess');
107 } else {
108 $db->debug=false;
109 notify('Upgrading '. $plugin->name .' from '. $CFG->$pluginversion .' to '. $plugin->version .' FAILED!');
110 }
173cc1c3 111 }
112 }
d87a9d73 113 echo '<hr />';
ead29342 114 $updated_plugins = true;
d87a9d73 115
173cc1c3 116 } else {
ead29342 117 error('Version mismatch: '. $plugin->name .' can\'t downgrade '. $CFG->$pluginversion .' -> '. $plugin->version .' !');
173cc1c3 118 }
119 }
120
ead29342 121 if (!empty($updated_plugins)) {
173cc1c3 122 print_continue($return);
123 die;
124 }
125}
126
88a7228a 127/**
128 * Find and check all modules and load them up or upgrade them if necessary
129 *
130 * @uses $db
131 * @uses $CFG
132 * @param string $return The url to prompt the user to continue to
133 * @todo Finish documenting this function
134 */
173cc1c3 135function upgrade_activity_modules($return) {
173cc1c3 136
e69ef14b 137 global $CFG, $db;
173cc1c3 138
88a7228a 139 if (!$mods = get_list_of_plugins('mod') ) {
140 error('No modules installed!');
173cc1c3 141 }
142
143 foreach ($mods as $mod) {
144
88a7228a 145 if ($mod == 'NEWMODULE') { // Someone has unzipped the template, ignore it
173cc1c3 146 continue;
147 }
148
88a7228a 149 $fullmod = $CFG->dirroot .'/mod/'. $mod;
173cc1c3 150
151 unset($module);
152
88a7228a 153 if ( is_readable($fullmod .'/version.php')) {
154 include_once($fullmod .'/version.php'); // defines $module with version etc
173cc1c3 155 } else {
88a7228a 156 notify('Module '. $mod .': '. $fullmod .'/version.php was not readable');
173cc1c3 157 continue;
158 }
159
88a7228a 160 if ( is_readable($fullmod .'/db/'. $CFG->dbtype .'.php')) {
161 include_once($fullmod .'/db/'. $CFG->dbtype .'.php'); // defines upgrading function
173cc1c3 162 } else {
88a7228a 163 notify('Module '. $mod .': '. $fullmod .'/db/'. $CFG->dbtype .'.php was not readable');
173cc1c3 164 continue;
165 }
166
167 if (!isset($module)) {
168 continue;
169 }
170
171 if (!empty($module->requires)) {
172 if ($module->requires > $CFG->version) {
173 $info->modulename = $mod;
174 $info->moduleversion = $module->version;
175 $info->currentmoodle = $CFG->version;
176 $info->requiremoodle = $module->requires;
177 notify(get_string('modulerequirementsnotmet', 'error', $info));
178 unset($info);
179 continue;
180 }
181 }
182
183 $module->name = $mod; // The name MUST match the directory
184
88a7228a 185 if ($currmodule = get_record('modules', 'name', $module->name)) {
173cc1c3 186 if ($currmodule->version == $module->version) {
187 // do nothing
188 } else if ($currmodule->version < $module->version) {
189 if (empty($updated_modules)) {
88a7228a 190 $strmodulesetup = get_string('modulesetup');
a36f058e 191 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
192 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
193 false, '&nbsp;', '&nbsp;');
173cc1c3 194 }
88a7228a 195 print_heading($module->name .' module needs upgrading');
196 $upgrade_function = $module->name.'_upgrade';
173cc1c3 197 if (function_exists($upgrade_function)) {
198 $db->debug=true;
199 if ($upgrade_function($currmodule->version, $module)) {
200 $db->debug=false;
201 // OK so far, now update the modules record
202 $module->id = $currmodule->id;
88a7228a 203 if (! update_record('modules', $module)) {
204 error('Could not update '. $module->name .' record in modules table!');
173cc1c3 205 }
d6ead3a2 206 remove_dir($CFG->dataroot . '/cache', true); // flush cache
a8f68426 207 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
88a7228a 208 echo '<hr />';
173cc1c3 209 } else {
210 $db->debug=false;
88a7228a 211 notify('Upgrading '. $module->name .' from '. $currmodule->version .' to '. $module->version .' FAILED!');
173cc1c3 212 }
213 }
214 $updated_modules = true;
215 } else {
88a7228a 216 error('Version mismatch: '. $module->name .' can\'t downgrade '. $currmodule->version .' -> '. $module->version .' !');
173cc1c3 217 }
218
219 } else { // module not installed yet, so install it
220 if (empty($updated_modules)) {
88a7228a 221 $strmodulesetup = get_string('modulesetup');
a36f058e 222 print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '',
223 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
224 false, '&nbsp;', '&nbsp;');
173cc1c3 225 }
226 print_heading($module->name);
227 $updated_modules = true;
228 $db->debug = true;
229 @set_time_limit(0); // To allow slow databases to complete the long SQL
88a7228a 230 if (modify_database($fullmod .'/db/'. $CFG->dbtype .'.sql')) {
173cc1c3 231 $db->debug = false;
88a7228a 232 if ($module->id = insert_record('modules', $module)) {
a8f68426 233 notify(get_string('modulesuccess', '', $module->name), 'notifysuccess');
88a7228a 234 echo '<hr />';
173cc1c3 235 } else {
88a7228a 236 error($module->name .' module could not be added to the module list!');
173cc1c3 237 }
238 } else {
88a7228a 239 error($module->name .' tables could NOT be set up successfully!');
173cc1c3 240 }
241 }
e5bd4e58 242
243 /// Check submodules of this module if necessary
244
245 include_once($fullmod.'/lib.php'); // defines upgrading function
246
247 $submoduleupgrade = $module->name.'_upgrade_submodules';
248 if (function_exists($submoduleupgrade)) {
249 $submoduleupgrade();
250 }
251
252
253 /// Run any defaults or final code that is necessary for this module
254
a5c0990e 255 if ( is_readable($fullmod .'/defaults.php')) {
256 // Insert default values for any important configuration variables
9e6e7502 257 unset($defaults);
a5c0990e 258 include_once($fullmod .'/defaults.php');
f9a2e515 259 if (!empty($defaults)) {
260 foreach ($defaults as $name => $value) {
261 if (!isset($CFG->$name)) {
262 set_config($name, $value);
263 }
a5c0990e 264 }
265 }
266 }
173cc1c3 267 }
268
269 if (!empty($updated_modules)) {
270 print_continue($return);
136f43dc 271 print_footer();
173cc1c3 272 die;
273 }
274}
275
f3221af9 276/**
277 * This function will return FALSE if the lock fails to be set (ie, if it's already locked)
80be7ee3 278 *
279 * @param string $name ?
280 * @param bool $value ?
281 * @param int $staleafter ?
282 * @param bool $clobberstale ?
283 * @todo Finish documenting this function
f3221af9 284 */
285function set_cron_lock($name,$value=true,$staleafter=7200,$clobberstale=false) {
286
287 if (empty($name)) {
288 mtrace("Tried to get a cron lock for a null fieldname");
289 return false;
290 }
291
292 if (empty($value)) {
293 set_config($name,0);
294 return true;
295 }
296
297 if ($config = get_record('config','name',$name)) {
298 if (empty($config->value)) {
299 set_config($name,time());
300 } else {
301 // check for stale.
302 if ((time() - $staleafter) > $config->value) {
303 mtrace("STALE LOCKFILE FOR $name - was $config->value");
304 if (!empty($clobberstale)) {
305 set_config($name,time());
306 return true;
307 }
308 } else {
309 return false; // was not stale - ie, we're ok to still be running.
310 }
311 }
312 }
313 else {
314 set_config($name,time());
315 }
316 return true;
317}
a597f8a8 318
fb06b255 319function print_progress($done, $total, $updatetime=5, $sleeptime=1, $donetext='') {
a597f8a8 320 static $starttime;
321 static $lasttime;
322
323 if (empty($starttime)) {
324 $starttime = $lasttime = time();
325 $lasttime = $starttime - $updatetime;
326 echo '<table width="500" cellpadding="0" cellspacing="0" align="center"><tr><td width="500">';
327 echo '<div id="bar" style="border-style:solid;border-width:1px;width:500px;height:50px;">';
328 echo '<div id="slider" style="border-style:solid;border-width:1px;height:48px;width:10px;background-color:green;"></div>';
329 echo '</div>';
330 echo '<div id="text" align="center" style="width:500px;"></div>';
331 echo '</td></tr></table>';
332 echo '</div>';
333 }
334
a597f8a8 335 $now = time();
336
337 if ($done && (($now - $lasttime) >= $updatetime)) {
338 $elapsedtime = $now - $starttime;
339 $projectedtime = (int)(((float)$total / (float)$done) * $elapsedtime) - $elapsedtime;
340 $percentage = format_float((float)$done / (float)$total, 2);
341 $width = (int)(500 * $percentage);
342
fb06b255 343 if ($projectedtime > 10) {
344 $projectedtext = ' Ending: '.format_time($projectedtime);
345 } else {
346 $projectedtext = '';
347 }
348
a597f8a8 349 echo '<script>';
fb06b255 350 echo 'document.getElementById("text").innerHTML = "'.addslashes($donetext).' '.$done.' done.'.$projectedtext.'";'."\n";
a597f8a8 351 echo 'document.getElementById("slider").style.width = \''.$width.'px\';'."\n";
352 echo '</script>';
353
354 $lasttime = $now;
355 sleep($sleeptime);
356 }
357}
9e6e7502 358?>