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 |
22 | function 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'); |
76 | print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '', '', false, ' ', ' '); |
173cc1c3 |
77 | } |
ead29342 |
78 | print_heading($plugin->name .' plugin needs upgrading'); |
79 | $upgrade_function = $type.'_'.$plugin->name .'_upgrade'; |
173cc1c3 |
80 | if (function_exists($upgrade_function)) { |
81 | $db->debug=true; |
ead29342 |
82 | if ($upgrade_function($CFG->$pluginversion)) { |
173cc1c3 |
83 | $db->debug=false; |
ead29342 |
84 | // OK so far, now update the plugins record |
85 | set_config($pluginversion, $plugin->version); |
86 | notify(get_string('modulesuccess', '', $plugin->name), 'notifysuccess'); |
88a7228a |
87 | echo '<hr />'; |
173cc1c3 |
88 | } else { |
89 | $db->debug=false; |
ead29342 |
90 | notify('Upgrading '. $plugin->name .' from '. $CFG->$pluginversion .' to '. $plugin->version .' FAILED!'); |
173cc1c3 |
91 | } |
92 | } |
ead29342 |
93 | $updated_plugins = true; |
173cc1c3 |
94 | } else { |
ead29342 |
95 | error('Version mismatch: '. $plugin->name .' can\'t downgrade '. $CFG->$pluginversion .' -> '. $plugin->version .' !'); |
173cc1c3 |
96 | } |
97 | } |
98 | |
ead29342 |
99 | if (!empty($updated_plugins)) { |
173cc1c3 |
100 | print_continue($return); |
101 | die; |
102 | } |
103 | } |
104 | |
88a7228a |
105 | /** |
106 | * Find and check all modules and load them up or upgrade them if necessary |
107 | * |
108 | * @uses $db |
109 | * @uses $CFG |
110 | * @param string $return The url to prompt the user to continue to |
111 | * @todo Finish documenting this function |
112 | */ |
173cc1c3 |
113 | function upgrade_activity_modules($return) { |
173cc1c3 |
114 | |
e69ef14b |
115 | global $CFG, $db; |
173cc1c3 |
116 | |
88a7228a |
117 | if (!$mods = get_list_of_plugins('mod') ) { |
118 | error('No modules installed!'); |
173cc1c3 |
119 | } |
120 | |
121 | foreach ($mods as $mod) { |
122 | |
88a7228a |
123 | if ($mod == 'NEWMODULE') { // Someone has unzipped the template, ignore it |
173cc1c3 |
124 | continue; |
125 | } |
126 | |
88a7228a |
127 | $fullmod = $CFG->dirroot .'/mod/'. $mod; |
173cc1c3 |
128 | |
129 | unset($module); |
130 | |
88a7228a |
131 | if ( is_readable($fullmod .'/version.php')) { |
132 | include_once($fullmod .'/version.php'); // defines $module with version etc |
173cc1c3 |
133 | } else { |
88a7228a |
134 | notify('Module '. $mod .': '. $fullmod .'/version.php was not readable'); |
173cc1c3 |
135 | continue; |
136 | } |
137 | |
88a7228a |
138 | if ( is_readable($fullmod .'/db/'. $CFG->dbtype .'.php')) { |
139 | include_once($fullmod .'/db/'. $CFG->dbtype .'.php'); // defines upgrading function |
173cc1c3 |
140 | } else { |
88a7228a |
141 | notify('Module '. $mod .': '. $fullmod .'/db/'. $CFG->dbtype .'.php was not readable'); |
173cc1c3 |
142 | continue; |
143 | } |
144 | |
145 | if (!isset($module)) { |
146 | continue; |
147 | } |
148 | |
149 | if (!empty($module->requires)) { |
150 | if ($module->requires > $CFG->version) { |
151 | $info->modulename = $mod; |
152 | $info->moduleversion = $module->version; |
153 | $info->currentmoodle = $CFG->version; |
154 | $info->requiremoodle = $module->requires; |
155 | notify(get_string('modulerequirementsnotmet', 'error', $info)); |
156 | unset($info); |
157 | continue; |
158 | } |
159 | } |
160 | |
161 | $module->name = $mod; // The name MUST match the directory |
162 | |
88a7228a |
163 | if ($currmodule = get_record('modules', 'name', $module->name)) { |
173cc1c3 |
164 | if ($currmodule->version == $module->version) { |
165 | // do nothing |
166 | } else if ($currmodule->version < $module->version) { |
167 | if (empty($updated_modules)) { |
88a7228a |
168 | $strmodulesetup = get_string('modulesetup'); |
169 | print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', '', false, ' ', ' '); |
173cc1c3 |
170 | } |
88a7228a |
171 | print_heading($module->name .' module needs upgrading'); |
172 | $upgrade_function = $module->name.'_upgrade'; |
173cc1c3 |
173 | if (function_exists($upgrade_function)) { |
174 | $db->debug=true; |
175 | if ($upgrade_function($currmodule->version, $module)) { |
176 | $db->debug=false; |
177 | // OK so far, now update the modules record |
178 | $module->id = $currmodule->id; |
88a7228a |
179 | if (! update_record('modules', $module)) { |
180 | error('Could not update '. $module->name .' record in modules table!'); |
173cc1c3 |
181 | } |
d6ead3a2 |
182 | remove_dir($CFG->dataroot . '/cache', true); // flush cache |
a8f68426 |
183 | notify(get_string('modulesuccess', '', $module->name), 'notifysuccess'); |
88a7228a |
184 | echo '<hr />'; |
173cc1c3 |
185 | } else { |
186 | $db->debug=false; |
88a7228a |
187 | notify('Upgrading '. $module->name .' from '. $currmodule->version .' to '. $module->version .' FAILED!'); |
173cc1c3 |
188 | } |
189 | } |
190 | $updated_modules = true; |
191 | } else { |
88a7228a |
192 | error('Version mismatch: '. $module->name .' can\'t downgrade '. $currmodule->version .' -> '. $module->version .' !'); |
173cc1c3 |
193 | } |
194 | |
195 | } else { // module not installed yet, so install it |
196 | if (empty($updated_modules)) { |
88a7228a |
197 | $strmodulesetup = get_string('modulesetup'); |
198 | print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', '', false, ' ', ' '); |
173cc1c3 |
199 | } |
200 | print_heading($module->name); |
201 | $updated_modules = true; |
202 | $db->debug = true; |
203 | @set_time_limit(0); // To allow slow databases to complete the long SQL |
88a7228a |
204 | if (modify_database($fullmod .'/db/'. $CFG->dbtype .'.sql')) { |
173cc1c3 |
205 | $db->debug = false; |
88a7228a |
206 | if ($module->id = insert_record('modules', $module)) { |
a8f68426 |
207 | notify(get_string('modulesuccess', '', $module->name), 'notifysuccess'); |
88a7228a |
208 | echo '<hr />'; |
173cc1c3 |
209 | } else { |
88a7228a |
210 | error($module->name .' module could not be added to the module list!'); |
173cc1c3 |
211 | } |
212 | } else { |
88a7228a |
213 | error($module->name .' tables could NOT be set up successfully!'); |
173cc1c3 |
214 | } |
215 | } |
e5bd4e58 |
216 | |
217 | /// Check submodules of this module if necessary |
218 | |
219 | include_once($fullmod.'/lib.php'); // defines upgrading function |
220 | |
221 | $submoduleupgrade = $module->name.'_upgrade_submodules'; |
222 | if (function_exists($submoduleupgrade)) { |
223 | $submoduleupgrade(); |
224 | } |
225 | |
226 | |
227 | /// Run any defaults or final code that is necessary for this module |
228 | |
a5c0990e |
229 | if ( is_readable($fullmod .'/defaults.php')) { |
230 | // Insert default values for any important configuration variables |
9e6e7502 |
231 | unset($defaults); |
a5c0990e |
232 | include_once($fullmod .'/defaults.php'); |
f9a2e515 |
233 | if (!empty($defaults)) { |
234 | foreach ($defaults as $name => $value) { |
235 | if (!isset($CFG->$name)) { |
236 | set_config($name, $value); |
237 | } |
a5c0990e |
238 | } |
239 | } |
240 | } |
173cc1c3 |
241 | } |
242 | |
243 | if (!empty($updated_modules)) { |
244 | print_continue($return); |
136f43dc |
245 | print_footer(); |
173cc1c3 |
246 | die; |
247 | } |
248 | } |
249 | |
f3221af9 |
250 | /** |
251 | * This function will return FALSE if the lock fails to be set (ie, if it's already locked) |
80be7ee3 |
252 | * |
253 | * @param string $name ? |
254 | * @param bool $value ? |
255 | * @param int $staleafter ? |
256 | * @param bool $clobberstale ? |
257 | * @todo Finish documenting this function |
f3221af9 |
258 | */ |
259 | function set_cron_lock($name,$value=true,$staleafter=7200,$clobberstale=false) { |
260 | |
261 | if (empty($name)) { |
262 | mtrace("Tried to get a cron lock for a null fieldname"); |
263 | return false; |
264 | } |
265 | |
266 | if (empty($value)) { |
267 | set_config($name,0); |
268 | return true; |
269 | } |
270 | |
271 | if ($config = get_record('config','name',$name)) { |
272 | if (empty($config->value)) { |
273 | set_config($name,time()); |
274 | } else { |
275 | // check for stale. |
276 | if ((time() - $staleafter) > $config->value) { |
277 | mtrace("STALE LOCKFILE FOR $name - was $config->value"); |
278 | if (!empty($clobberstale)) { |
279 | set_config($name,time()); |
280 | return true; |
281 | } |
282 | } else { |
283 | return false; // was not stale - ie, we're ok to still be running. |
284 | } |
285 | } |
286 | } |
287 | else { |
288 | set_config($name,time()); |
289 | } |
290 | return true; |
291 | } |
a597f8a8 |
292 | |
293 | function print_progress($done, $total, $updatetime=5, $sleeptime=1) { |
294 | static $count; |
295 | static $starttime; |
296 | static $lasttime; |
297 | |
298 | if (empty($starttime)) { |
299 | $starttime = $lasttime = time(); |
300 | $lasttime = $starttime - $updatetime; |
301 | echo '<table width="500" cellpadding="0" cellspacing="0" align="center"><tr><td width="500">'; |
302 | echo '<div id="bar" style="border-style:solid;border-width:1px;width:500px;height:50px;">'; |
303 | echo '<div id="slider" style="border-style:solid;border-width:1px;height:48px;width:10px;background-color:green;"></div>'; |
304 | echo '</div>'; |
305 | echo '<div id="text" align="center" style="width:500px;"></div>'; |
306 | echo '</td></tr></table>'; |
307 | echo '</div>'; |
308 | } |
309 | |
310 | if (!isset($count)) { |
311 | $count = 0; |
312 | } |
313 | |
314 | $count++; |
315 | |
316 | $now = time(); |
317 | |
318 | if ($done && (($now - $lasttime) >= $updatetime)) { |
319 | $elapsedtime = $now - $starttime; |
320 | $projectedtime = (int)(((float)$total / (float)$done) * $elapsedtime) - $elapsedtime; |
321 | $percentage = format_float((float)$done / (float)$total, 2); |
322 | $width = (int)(500 * $percentage); |
323 | |
324 | echo '<script>'; |
325 | echo 'document.getElementById("text").innerHTML = "'.$count.' done. Ending: '.format_time($projectedtime).'";'."\n"; |
326 | echo 'document.getElementById("slider").style.width = \''.$width.'px\';'."\n"; |
327 | echo '</script>'; |
328 | |
329 | $lasttime = $now; |
330 | sleep($sleeptime); |
331 | } |
332 | } |
9e6e7502 |
333 | ?> |