9704c866 |
1 | <?php //$Id$ |
52376d94 |
2 | //This file contains all the general function needed (file manipulation...) |
3 | //not directly part of the backup/restore utility |
afbe3de8 |
4 | |
8930f900 |
5 | require_once($CFG->dirroot.'/lib/uploadlib.php'); |
6 | |
de4746a8 |
7 | //Sets a name/value pair in backup_config table |
8 | function backup_set_config($name, $value) { |
9 | if (get_field("backup_config", "name", "name", $name)) { |
348d6827 |
10 | return set_field("backup_config", "value", addslashes($value), "name", $name); |
de4746a8 |
11 | } else { |
348d6827 |
12 | $config = new object(); |
de4746a8 |
13 | $config->name = $name; |
348d6827 |
14 | $config->value = addslashes($value); |
de4746a8 |
15 | return insert_record("backup_config", $config); |
16 | } |
17 | } |
18 | |
19 | //Gets all the information from backup_config table |
20 | function backup_get_config() { |
21 | $backup_config = null; |
37afa39a |
22 | if ($configs = get_records("backup_config")) { |
de4746a8 |
23 | foreach ($configs as $config) { |
24 | $backup_config[$config->name] = $config->value; |
25 | } |
26 | } |
49b95c30 |
27 | return (object)$backup_config; |
de4746a8 |
28 | } |
29 | |
b0778a76 |
30 | //Delete old data in backup tables (if exists) |
dfd02290 |
31 | //Four hours seem to be appropiate now that backup is stable |
b0778a76 |
32 | function backup_delete_old_data() { |
674b30f5 |
33 | |
34 | global $CFG; |
35 | |
b0778a76 |
36 | //Change this if you want !! |
dfd02290 |
37 | $hours = 4; |
b0778a76 |
38 | //End change this |
dfd02290 |
39 | $seconds = $hours * 60 * 60; |
b0778a76 |
40 | $delete_from = time()-$seconds; |
41 | //Now delete from tables |
674b30f5 |
42 | $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids |
43 | WHERE backup_code < '$delete_from'",false); |
44 | if ($status) { |
45 | $status = execute_sql("DELETE FROM {$CFG->prefix}backup_files |
46 | WHERE backup_code < '$delete_from'",false); |
47 | } |
3b8bad6f |
48 | //Now, delete old directory (if exists) |
49 | if ($status) { |
50 | $status = backup_delete_old_dirs($delete_from); |
51 | } |
b0778a76 |
52 | return($status); |
53 | } |
674b30f5 |
54 | |
3b8bad6f |
55 | //Function to delete dirs/files into temp/backup directory |
56 | //older than $delete_from |
57 | function backup_delete_old_dirs($delete_from) { |
58 | |
59 | global $CFG; |
60 | |
61 | $status = true; |
41bac9d0 |
62 | //Get files and directories in the temp backup dir witout descend |
63 | $list = get_directory_list($CFG->dataroot."/temp/backup", "", false, true, true); |
3b8bad6f |
64 | foreach ($list as $file) { |
65 | $file_path = $CFG->dataroot."/temp/backup/".$file; |
66 | $moddate = filemtime($file_path); |
af9cd955 |
67 | if ($status && $moddate < $delete_from) { |
cfb9c525 |
68 | //If directory, recurse |
69 | if (is_dir($file_path)) { |
70 | $status = delete_dir_contents($file_path); |
71 | //There is nothing, delete the directory itself |
72 | if ($status) { |
73 | $status = rmdir($file_path); |
74 | } |
75 | //If file |
76 | } else { |
77 | unlink("$file_path"); |
3b8bad6f |
78 | } |
79 | } |
80 | } |
81 | |
82 | return $status; |
83 | } |
84 | |
674b30f5 |
85 | //Function to check and create the needed dir to |
86 | //save all the backup |
87 | function check_and_create_backup_dir($backup_unique_code) { |
88 | |
89 | global $CFG; |
90 | |
91 | $status = check_dir_exists($CFG->dataroot."/temp",true); |
92 | if ($status) { |
93 | $status = check_dir_exists($CFG->dataroot."/temp/backup",true); |
94 | } |
95 | if ($status) { |
96 | $status = check_dir_exists($CFG->dataroot."/temp/backup/".$backup_unique_code,true); |
97 | } |
98 | |
99 | return $status; |
100 | } |
101 | |
102 | //Function to delete all the directory contents recursively |
35ea1594 |
103 | //it supports a excluded dit too |
af9cd955 |
104 | //Copied from the web !! |
35ea1594 |
105 | function delete_dir_contents ($dir,$excludeddir="") { |
674b30f5 |
106 | |
af9cd955 |
107 | $slash = "/"; |
674b30f5 |
108 | |
af9cd955 |
109 | // Create arrays to store files and directories |
110 | $dir_files = array(); |
111 | $dir_subdirs = array(); |
674b30f5 |
112 | |
af9cd955 |
113 | // Make sure we can delete it |
114 | chmod($dir, 0777); |
115 | |
116 | if ((($handle = opendir($dir))) == FALSE) { |
117 | // The directory could not be opened |
118 | return false; |
119 | } |
120 | |
121 | // Loop through all directory entries, and construct two temporary arrays containing files and sub directories |
122 | while($entry = readdir($handle)) { |
35ea1594 |
123 | if (is_dir($dir. $slash .$entry) && $entry != ".." && $entry != "." && $entry != $excludeddir) { |
af9cd955 |
124 | $dir_subdirs[] = $dir. $slash .$entry; |
125 | } |
35ea1594 |
126 | else if ($entry != ".." && $entry != "." && $entry != $excludeddir) { |
af9cd955 |
127 | $dir_files[] = $dir. $slash .$entry; |
128 | } |
129 | } |
130 | |
131 | // Delete all files in the curent directory return false and halt if a file cannot be removed |
132 | for($i=0; $i<count($dir_files); $i++) { |
133 | chmod($dir_files[$i], 0777); |
134 | if (((unlink($dir_files[$i]))) == FALSE) { |
135 | return false; |
136 | } |
137 | } |
138 | |
139 | // Empty sub directories and then remove the directory |
140 | for($i=0; $i<count($dir_subdirs); $i++) { |
141 | chmod($dir_subdirs[$i], 0777); |
142 | if (delete_dir_contents($dir_subdirs[$i]) == FALSE) { |
143 | return false; |
144 | } |
145 | else { |
146 | if (rmdir($dir_subdirs[$i]) == FALSE) { |
147 | return false; |
674b30f5 |
148 | } |
149 | } |
150 | } |
674b30f5 |
151 | |
af9cd955 |
152 | // Close directory |
153 | closedir($handle); |
154 | |
155 | // Success, every thing is gone return true |
156 | return true; |
674b30f5 |
157 | } |
158 | |
159 | //Function to clear (empty) the contents of the backup_dir |
674b30f5 |
160 | function clear_backup_dir($backup_unique_code) { |
161 | |
162 | global $CFG; |
163 | |
164 | $rootdir = $CFG->dataroot."/temp/backup/".$backup_unique_code; |
165 | |
166 | //Delete recursively |
167 | $status = delete_dir_contents($rootdir); |
168 | |
169 | return $status; |
170 | } |
3b8bad6f |
171 | |
cfb9c525 |
172 | //Returns the module type of a course_module's id in a course |
173 | function get_module_type ($courseid,$moduleid) { |
174 | |
175 | global $CFG; |
176 | |
177 | $results = get_records_sql ("SELECT cm.id, m.name |
178 | FROM {$CFG->prefix}course_modules cm, |
179 | {$CFG->prefix}modules m |
180 | WHERE cm.course = '$courseid' AND |
181 | cm.id = '$moduleid' AND |
182 | m.id = cm.module"); |
183 | |
184 | if ($results) { |
185 | $name = $results[$moduleid]->name; |
186 | } else { |
187 | $name = false; |
188 | } |
52376d94 |
189 | return $name; |
667d2f2a |
190 | } |
191 | |
192 | //This function return the names of all directories under a give directory |
193 | //Not recursive |
194 | function list_directories ($rootdir) { |
97a49e63 |
195 | |
196 | $results = null; |
667d2f2a |
197 | |
198 | $dir = opendir($rootdir); |
199 | while ($file=readdir($dir)) { |
200 | if ($file=="." || $file=="..") { |
201 | continue; |
202 | } |
203 | if (is_dir($rootdir."/".$file)) { |
204 | $results[$file] = $file; |
205 | } |
206 | } |
207 | closedir($dir); |
208 | return $results; |
209 | } |
210 | |
211 | //This function return the names of all directories and files under a give directory |
212 | //Not recursive |
213 | function list_directories_and_files ($rootdir) { |
3a4b33c3 |
214 | |
215 | $results = ""; |
667d2f2a |
216 | |
217 | $dir = opendir($rootdir); |
218 | while ($file=readdir($dir)) { |
219 | if ($file=="." || $file=="..") { |
220 | continue; |
221 | } |
222 | $results[$file] = $file; |
223 | } |
224 | closedir($dir); |
225 | return $results; |
226 | } |
227 | |
47846965 |
228 | //This function clean data from backup tables and |
229 | //delete all temp files used |
230 | function clean_temp_data ($preferences) { |
231 | |
47846965 |
232 | global $CFG; |
233 | |
234 | $status = true; |
235 | |
236 | //true->do it, false->don't do it. To debug if necessary. |
237 | if (true) { |
238 | //Now delete from tables |
239 | $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids |
af478c0b |
240 | WHERE backup_code = '$preferences->backup_unique_code'",false); |
47846965 |
241 | if ($status) { |
242 | $status = execute_sql("DELETE FROM {$CFG->prefix}backup_files |
af478c0b |
243 | WHERE backup_code = '$preferences->backup_unique_code'",false); |
47846965 |
244 | } |
245 | //Now, delete temp directory (if exists) |
246 | $file_path = $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code; |
247 | if (is_dir($file_path)) { |
248 | $status = delete_dir_contents($file_path); |
249 | //There is nothing, delete the directory itself |
250 | if ($status) { |
251 | $status = rmdir($file_path); |
252 | } |
253 | } |
254 | } |
255 | return $status; |
256 | } |
257 | |
efead3b9 |
258 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
259 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
260 | //This functions are used to copy any file or directory ($from_file) |
261 | //to a new file or directory ($to_file). It works recursively and |
262 | //mantains file perms. |
263 | //I've copied it from: http://www.php.net/manual/en/function.copy.php |
264 | //Little modifications done |
265 | |
d27920b9 |
266 | function backup_copy_file ($from_file,$to_file,$log_clam=false) { |
f654deea |
267 | |
268 | global $CFG; |
269 | |
efead3b9 |
270 | if (is_file($from_file)) { |
7ef0797d |
271 | //echo "<br />Copying ".$from_file." to ".$to_file; //Debug |
f654deea |
272 | //$perms=fileperms($from_file); |
273 | //return copy($from_file,$to_file) && chmod($to_file,$perms); |
274 | umask(0000); |
9704c866 |
275 | if (copy($from_file,$to_file)) { |
276 | chmod($to_file,$CFG->directorypermissions); |
d27920b9 |
277 | if (!empty($log_clam)) { |
278 | clam_log_upload($to_file,null,true); |
279 | } |
8930f900 |
280 | return true; |
281 | } |
282 | return false; |
efead3b9 |
283 | } |
284 | else if (is_dir($from_file)) { |
285 | return backup_copy_dir($from_file,$to_file); |
286 | } |
287 | else{ |
7ef0797d |
288 | //echo "<br />Error: not file or dir ".$from_file; //Debug |
efead3b9 |
289 | return false; |
290 | } |
cfb9c525 |
291 | } |
efead3b9 |
292 | |
293 | function backup_copy_dir($from_file,$to_file) { |
93808667 |
294 | |
295 | global $CFG; |
296 | |
615b4a13 |
297 | $status = true; // Initialize this, next code will change its value if needed |
298 | |
efead3b9 |
299 | if (!is_dir($to_file)) { |
7ef0797d |
300 | //echo "<br />Creating ".$to_file; //Debug |
f654deea |
301 | umask(0000); |
41923e75 |
302 | $status = mkdir($to_file,$CFG->directorypermissions); |
efead3b9 |
303 | } |
304 | $dir = opendir($from_file); |
305 | while ($file=readdir($dir)) { |
306 | if ($file=="." || $file=="..") { |
307 | continue; |
308 | } |
4f6ae69e |
309 | $status = backup_copy_file ("$from_file/$file","$to_file/$file"); |
efead3b9 |
310 | } |
4f6ae69e |
311 | closedir($dir); |
312 | return $status; |
efead3b9 |
313 | } |
314 | ///Ends copy file/dirs functions |
315 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
316 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7641819d |
317 | |
10dcde40 |
318 | |
319 | function upgrade_backup_db($continueto) { |
320 | /// This function upgrades the backup tables, if necessary |
321 | /// It's called from admin/index.php, also backup.php and restore.php |
7641819d |
322 | |
6e4dc10f |
323 | global $CFG, $db; |
10dcde40 |
324 | |
325 | require_once ("$CFG->dirroot/backup/version.php"); // Get code versions |
326 | |
327 | if (empty($CFG->backup_version)) { // Backup has never been installed. |
328 | $strdatabaseupgrades = get_string("databaseupgrades"); |
a36f058e |
329 | print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, "", |
371a32e3 |
330 | upgrade_get_javascript(), false, " ", " "); |
10dcde40 |
331 | |
583fad99 |
332 | upgrade_log_start(); |
94ab72f8 |
333 | print_heading('backup'); |
10dcde40 |
334 | $db->debug=true; |
94ab72f8 |
335 | |
336 | /// Both old .sql files and new install.xml are supported |
337 | /// but we priorize install.xml (XMLDB) if present |
338 | $status = false; |
db8bd7a6 |
339 | if (file_exists($CFG->dirroot . '/backup/db/install.xml')) { |
94ab72f8 |
340 | $status = install_from_xmldb_file($CFG->dirroot . '/backup/db/install.xml'); //New method |
341 | } else if (file_exists($CFG->dirroot . '/backup/db/' . $CFG->dbtype . '.sql')) { |
342 | $status = modify_database($CFG->dirroot . '/backup/db/' . $CFG->dbtype . '.sql'); //Old method |
343 | } |
344 | |
345 | $db->debug = false; |
346 | if ($status) { |
e9346b95 |
347 | if (set_config("backup_version", $backup_version) and set_config("backup_release", $backup_release)) { |
99c8a100 |
348 | //initialize default backup settings now |
6e4dc10f |
349 | $adminroot = admin_get_root(); |
350 | apply_default_settings($adminroot->locate('backups')); |
10dcde40 |
351 | notify(get_string("databasesuccess"), "green"); |
8549af11 |
352 | notify(get_string("databaseupgradebackups", "", $backup_version), "green"); |
10dcde40 |
353 | print_continue($continueto); |
acdd790f |
354 | print_footer('none'); |
10dcde40 |
355 | exit; |
7641819d |
356 | } else { |
10dcde40 |
357 | error("Upgrade of backup system failed! (Could not update version in config table)"); |
7641819d |
358 | } |
10dcde40 |
359 | } else { |
360 | error("Backup tables could NOT be set up successfully!"); |
7641819d |
361 | } |
10dcde40 |
362 | } |
363 | |
94ab72f8 |
364 | /// Upgrading code starts here |
365 | $oldupgrade = false; |
366 | $newupgrade = false; |
367 | if (is_readable($CFG->dirroot . '/backup/db/' . $CFG->dbtype . '.php')) { |
368 | include_once($CFG->dirroot . '/backup/db/' . $CFG->dbtype . '.php'); // defines old upgrading function |
369 | $oldupgrade = true; |
370 | } |
db8bd7a6 |
371 | if (is_readable($CFG->dirroot . '/backup/db/upgrade.php')) { |
94ab72f8 |
372 | include_once($CFG->dirroot . '/backup/db/upgrade.php'); // defines new upgrading function |
373 | $newupgrade = true; |
374 | } |
10dcde40 |
375 | |
376 | if ($backup_version > $CFG->backup_version) { // Upgrade tables |
7641819d |
377 | $strdatabaseupgrades = get_string("databaseupgrades"); |
371a32e3 |
378 | print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '', upgrade_get_javascript()); |
10dcde40 |
379 | |
583fad99 |
380 | upgrade_log_start(); |
94ab72f8 |
381 | print_heading('backup'); |
382 | |
383 | /// Run de old and new upgrade functions for the module |
384 | $oldupgrade_function = 'backup_upgrade'; |
385 | $newupgrade_function = 'xmldb_backup_upgrade'; |
386 | |
387 | /// First, the old function if exists |
388 | $oldupgrade_status = true; |
389 | if ($oldupgrade && function_exists($oldupgrade_function)) { |
390 | $db->debug = true; |
391 | $oldupgrade_status = $oldupgrade_function($CFG->backup_version); |
392 | } else if ($oldupgrade) { |
393 | notify ('Upgrade function ' . $oldupgrade_function . ' was not available in ' . |
394 | '/backup/db/' . $CFG->dbtype . '.php'); |
395 | } |
10dcde40 |
396 | |
94ab72f8 |
397 | /// Then, the new function if exists and the old one was ok |
398 | $newupgrade_status = true; |
399 | if ($newupgrade && function_exists($newupgrade_function) && $oldupgrade_status) { |
400 | $db->debug = true; |
401 | $newupgrade_status = $newupgrade_function($CFG->backup_version); |
402 | } else if ($newupgrade) { |
403 | notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' . |
404 | '/backup/db/upgrade.php'); |
405 | } |
406 | |
407 | $db->debug=false; |
408 | /// Now analyze upgrade results |
409 | if ($oldupgrade_status && $newupgrade_status) { // No upgrading failed |
e9346b95 |
410 | if (set_config("backup_version", $backup_version) and set_config("backup_release", $backup_release)) { |
10dcde40 |
411 | notify(get_string("databasesuccess"), "green"); |
8549af11 |
412 | notify(get_string("databaseupgradebackups", "", $backup_version), "green"); |
10dcde40 |
413 | print_continue($continueto); |
acdd790f |
414 | print_footer('none'); |
10dcde40 |
415 | exit; |
416 | } else { |
417 | error("Upgrade of backup system failed! (Could not update version in config table)"); |
418 | } |
419 | } else { |
10dcde40 |
420 | error("Upgrade failed! See backup/version.php"); |
7641819d |
421 | } |
10dcde40 |
422 | |
423 | } else if ($backup_version < $CFG->backup_version) { |
583fad99 |
424 | upgrade_log_start(); |
10dcde40 |
425 | notify("WARNING!!! The code you are using is OLDER than the version that made these databases!"); |
7641819d |
426 | } |
94ab72f8 |
427 | upgrade_log_finish(); |
7641819d |
428 | } |
10dcde40 |
429 | |
7ba74615 |
430 | |
431 | //This function is used to insert records in the backup_ids table |
af9cd955 |
432 | //If the info field is greater than max_db_storage, then its info |
433 | //is saved to filesystem |
7ba74615 |
434 | function backup_putid ($backup_unique_code, $table, $old_id, $new_id, $info="") { |
435 | |
436 | global $CFG; |
af9cd955 |
437 | |
438 | $max_db_storage = 128; //Max bytes to save to db, else save to file |
7ba74615 |
439 | |
440 | $status = true; |
441 | |
442 | //First delete to avoid PK duplicates |
443 | $status = backup_delid($backup_unique_code, $table, $old_id); |
444 | |
af9cd955 |
445 | //Now, serialize info |
446 | $info_ser = serialize($info); |
447 | |
448 | //Now, if the size of $info_ser > $max_db_storage, save it to filesystem and |
449 | //insert a "infile" in the info field |
450 | |
451 | if (strlen($info_ser) > $max_db_storage) { |
452 | //Calculate filename (in current_backup_dir, $backup_unique_code_$table_$old_id.info) |
453 | $filename = $CFG->dataroot."/temp/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info"; |
454 | //Save data to file |
455 | $status = backup_data2file($filename,$info_ser); |
456 | //Set info_to save |
457 | $info_to_save = "infile"; |
458 | } else { |
459 | //Saving to db, addslashes |
460 | $info_to_save = addslashes($info_ser); |
461 | } |
462 | |
463 | //Now, insert the record |
464 | if ($status) { |
d8e24b78 |
465 | //Build the record |
466 | $rec->backup_code = $backup_unique_code; |
467 | $rec->table_name = $table; |
468 | $rec->old_id = $old_id; |
062a84a6 |
469 | $rec->new_id = ($new_id === null? 0 : $new_id); |
d8e24b78 |
470 | $rec->info = $info_to_save; |
15a6cf33 |
471 | |
472 | if (!insert_record('backup_ids', $rec, false)) { |
473 | $status = false; |
474 | } |
af9cd955 |
475 | } |
7ba74615 |
476 | return $status; |
477 | } |
478 | |
479 | //This function is used to delete recods from the backup_ids table |
af9cd955 |
480 | //If the info field is "infile" then the file is deleted too |
7ba74615 |
481 | function backup_delid ($backup_unique_code, $table, $old_id) { |
482 | |
483 | global $CFG; |
484 | |
485 | $status = true; |
486 | |
487 | $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids |
488 | WHERE backup_code = $backup_unique_code AND |
489 | table_name = '$table' AND |
490 | old_id = '$old_id'",false); |
491 | return $status; |
492 | } |
a2c7397c |
493 | |
494 | //This function is used to get a record from the backup_ids table |
af9cd955 |
495 | //If the info field is "infile" then its info |
496 | //is read from filesystem |
a2c7397c |
497 | function backup_getid ($backup_unique_code, $table, $old_id) { |
498 | |
499 | global $CFG; |
500 | |
501 | $status = true; |
af9cd955 |
502 | $status2 = true; |
a2c7397c |
503 | |
504 | $status = get_record ("backup_ids","backup_code",$backup_unique_code, |
505 | "table_name",$table, |
506 | "old_id", $old_id); |
507 | |
af9cd955 |
508 | //If info field = "infile", get file contents |
9a7538a3 |
509 | if (!empty($status->info) && $status->info == "infile") { |
af9cd955 |
510 | $filename = $CFG->dataroot."/temp/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info"; |
511 | //Read data from file |
512 | $status2 = backup_file2data($filename,$info); |
513 | if ($status2) { |
514 | //unserialize data |
515 | $status->info = unserialize($info); |
516 | } else { |
517 | $status = false; |
518 | } |
519 | } else { |
783ab2b0 |
520 | //Only if status (record exists) |
521 | if ($status) { |
522 | ////First strip slashes |
523 | $temp = stripslashes($status->info); |
524 | //Now unserialize |
525 | $status->info = unserialize($temp); |
526 | } |
af9cd955 |
527 | } |
528 | |
a2c7397c |
529 | return $status; |
530 | } |
6d18c5a2 |
531 | |
fd5ca378 |
532 | //This function is used to add slashes (and decode from UTF-8 if needed) |
6d18c5a2 |
533 | //It's used intensivelly when restoring modules and saving them in db |
534 | function backup_todb ($data) { |
810944af |
535 | return restore_decode_absolute_links(addslashes($data)); |
6d18c5a2 |
536 | } |
537 | |
fe3c84ab |
538 | //This function is used to check that every necessary function to |
539 | //backup/restore exists in the current php installation. Thanks to |
540 | //gregb@crowncollege.edu by the idea. |
f90666aa |
541 | function backup_required_functions($justcheck=false) { |
fe3c84ab |
542 | |
d2c94f4b |
543 | if(!function_exists('utf8_encode')) { |
f90666aa |
544 | if (empty($justcheck)) { |
545 | error('You need to add XML support to your PHP installation'); |
546 | } else { |
547 | return false; |
548 | } |
fe3c84ab |
549 | } |
550 | |
f90666aa |
551 | return true; |
fe3c84ab |
552 | } |
60b420af |
553 | |
554 | //This function send n white characters to the browser and flush the |
555 | //output buffer. Used to avoid browser timeouts and to show the progress. |
556 | function backup_flush($n=0,$time=false) { |
f90666aa |
557 | if (defined('RESTORE_SILENTLY_NOFLUSH')) { |
558 | return; |
559 | } |
60b420af |
560 | if ($time) { |
561 | $ti = strftime("%X",time()); |
562 | } else { |
563 | $ti = ""; |
564 | } |
565 | echo str_repeat(" ", $n) . $ti . "\n"; |
566 | flush(); |
567 | } |
fe3c84ab |
568 | |
af9cd955 |
569 | //This function creates the filename and write data to it |
570 | //returning status as result |
571 | function backup_data2file ($file,&$data) { |
572 | |
573 | $status = true; |
574 | $status2 = true; |
575 | |
576 | $f = fopen($file,"w"); |
577 | $status = fwrite($f,$data); |
578 | $status2 = fclose($f); |
579 | |
580 | return ($status && $status2); |
581 | } |
fe3c84ab |
582 | |
af9cd955 |
583 | //This function read the filename and read data from it |
584 | function backup_file2data ($file,&$data) { |
585 | |
586 | $status = true; |
587 | $status2 = true; |
588 | |
589 | $f = fopen($file,"r"); |
590 | $data = fread ($f,filesize($file)); |
591 | $status2 = fclose($f); |
592 | |
593 | return ($status && $status2); |
594 | } |
f90666aa |
595 | |
596 | /** this function will restore an entire backup.zip into the specified course |
597 | * using standard moodle backup/restore functions, but silently. |
598 | * @param string $pathtofile the absolute path to the backup file. |
599 | * @param int $destinationcourse the course id to restore to. |
600 | * @param boolean $emptyfirst whether to delete all coursedata first. |
601 | * @param boolean $userdata whether to include any userdata that may be in the backup file. |
602 | */ |
603 | function import_backup_file_silently($pathtofile,$destinationcourse,$emptyfirst=false,$userdata=false) { |
604 | global $CFG,$SESSION,$USER; // is there such a thing on cron? I guess so.. |
605 | |
606 | if (empty($USER)) { |
607 | $USER = get_admin(); |
608 | $USER->admin = 1; // not sure why, but this doesn't get set |
609 | } |
610 | |
611 | define('RESTORE_SILENTLY',true); // don't output all the stuff to us. |
612 | |
613 | $debuginfo = 'import_backup_file_silently: '; |
614 | $cleanupafter = false; |
615 | $errorstr = ''; // passed by reference to restore_precheck to get errors from. |
616 | |
617 | if (!$course = get_record('course','id',$destinationcourse)) { |
618 | mtrace($debuginfo.'Course with id $destinationcourse was not a valid course!'); |
619 | return false; |
620 | } |
621 | |
622 | // first check we have a valid file. |
623 | if (!file_exists($pathtofile) || !is_readable($pathtofile)) { |
624 | mtrace($debuginfo.'File '.$pathtofile.' either didn\'t exist or wasn\'t readable'); |
625 | return false; |
626 | } |
627 | |
628 | // now make sure it's a zip file |
629 | require_once($CFG->dirroot.'/lib/filelib.php'); |
630 | $filename = substr($pathtofile,strrpos($pathtofile,'/')+1); |
631 | $mimetype = mimeinfo("type", $filename); |
632 | if ($mimetype != 'application/zip') { |
633 | mtrace($debuginfo.'File '.$pathtofile.' was of wrong mimetype ('.$mimetype.')' ); |
634 | return false; |
635 | } |
636 | |
637 | // restore_precheck wants this within dataroot, so lets put it there if it's not already.. |
638 | if (strstr($pathtofile,$CFG->dataroot) === false) { |
639 | // first try and actually move it.. |
640 | if (!check_dir_exists($CFG->dataroot.'/temp/backup/',true)) { |
641 | mtrace($debuginfo.'File '.$pathtofile.' outside of dataroot and couldn\'t move it! '); |
642 | return false; |
643 | } |
644 | if (!copy($pathtofile,$CFG->dataroot.'/temp/backup/'.$filename)) { |
645 | mtrace($debuginfo.'File '.$pathtofile.' outside of dataroot and couldn\'t move it! '); |
646 | return false; |
647 | } else { |
648 | $pathtofile = 'temp/backup/'.$filename; |
649 | $cleanupafter = true; |
650 | } |
651 | } else { |
652 | // it is within dataroot, so take it off the path for restore_precheck. |
653 | $pathtofile = substr($pathtofile,strlen($CFG->dataroot.'/')); |
654 | } |
655 | |
656 | if (!backup_required_functions()) { |
657 | mtrace($debuginfo.'Required function check failed (see backup_required_functions)'); |
658 | return false; |
659 | } |
660 | |
661 | @ini_set("max_execution_time","3000"); |
8891e81c |
662 | raise_memory_limit("192M"); |
f90666aa |
663 | |
664 | if (!$backup_unique_code = restore_precheck($destinationcourse,$pathtofile,$errorstr,true)) { |
665 | mtrace($debuginfo.'Failed restore_precheck (error was '.$errorstr.')'); |
666 | return false; |
667 | } |
668 | |
669 | restore_setup_for_check($SESSION->restore,$backup_unique_code); |
670 | |
671 | // add on some extra stuff we need... |
672 | $SESSION->restore->restoreto = 1; |
673 | $SESSION->restore->course_id = $destinationcourse; |
674 | $SESSION->restore->deleting = $emptyfirst; |
675 | |
676 | // maybe we need users (defaults to 2 in restore_setup_for_check) |
677 | if (!empty($userdata)) { |
678 | $SESSION->restore->users = 1; |
679 | } |
680 | |
681 | // we also need modules... |
682 | if ($allmods = get_records("modules")) { |
683 | foreach ($allmods as $mod) { |
684 | $modname = $mod->name; |
685 | //Now check that we have that module info in the backup file |
686 | if (isset($SESSION->info->mods[$modname]) && $SESSION->info->mods[$modname]->backup == "true") { |
687 | $SESSION->restore->mods[$modname]->restore = true; |
688 | $SESSION->restore->mods[$modname]->userinfo = $userdata; |
689 | } |
690 | } |
691 | } |
692 | if (!restore_execute($SESSION->restore,$SESSION->info,$SESSION->course_header,$errorstr)) { |
693 | mtrace($debuginfo.'Failed restore_execute (error was '.$errorstr.')'); |
694 | return false; |
695 | } |
696 | return true; |
697 | } |
698 | |
afbe3de8 |
699 | ?> |