Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/lib.php
Go to the documentation of this file.
00001 <?php
00002     //This file contains all the general function needed (file manipulation...)
00003     //not directly part of the backup/restore utility plus some constants
00004 
00005     // Define "restoreto" options
00006     define('RESTORETO_CURRENT_DELETING',  0);
00007     define('RESTORETO_CURRENT_ADDING',    1);
00008     define('RESTORETO_NEW_COURSE',        2);
00009     define('RESTORETO_EXISTING_DELETING', 3);
00010     define('RESTORETO_EXISTING_ADDING',   4);
00011 
00012     require_once($CFG->libdir . '/completionlib.php');
00013 
00014     //Sets a name/value pair in config_plugin table
00015     function backup_set_config($name, $value) {
00016         return set_config($name, $value, 'backup');
00017     }
00018 
00019     //Gets all the information from config_plugin table
00020     function backup_get_config() {
00021         $backup_config = get_config('backup');
00022         return (object)$backup_config;
00023     }
00024 
00025     //Delete old data in backup tables (if exists)
00026     //Four hours seem to be appropiate now that backup is stable
00027     function backup_delete_old_data() {
00028         global $CFG, $DB;
00029 
00030         //Change this if you want !!
00031         $hours = 4;
00032         //End change this
00033         $seconds = $hours * 60 * 60;
00034         $delete_from = time()-$seconds;
00035         //Now delete from tables
00036         $status = $DB->execute("DELETE FROM {backup_ids}
00037                                  WHERE backup_code < ?", array($delete_from));
00038         if ($status) {
00039             $status = $DB->execute("DELETE FROM {backup_files}
00040                                      WHERE backup_code < ?", array($delete_from));
00041         }
00042         //Now, delete old directory (if exists)
00043         if ($status) {
00044             $status = backup_delete_old_dirs($delete_from);
00045         }
00046         return($status);
00047     }
00048 
00049     //Function to delete dirs/files into temp/backup directory
00050     //older than $delete_from
00051     function backup_delete_old_dirs($delete_from) {
00052 
00053         global $CFG;
00054 
00055         $status = true;
00056         //Get files and directories in the temp backup dir witout descend
00057         $list = get_directory_list($CFG->tempdir."/backup", "", false, true, true);
00058         foreach ($list as $file) {
00059             $file_path = $CFG->tempdir."/backup/".$file;
00060             $moddate = filemtime($file_path);
00061             if ($status && $moddate < $delete_from) {
00062                 //If directory, recurse
00063                 if (is_dir($file_path)) {
00064                     $status = delete_dir_contents($file_path);
00065                     //There is nothing, delete the directory itself
00066                     if ($status) {
00067                         $status = rmdir($file_path);
00068                     }
00069                 //If file
00070                 } else {
00071                     unlink("$file_path");
00072                 }
00073             }
00074         }
00075 
00076         return $status;
00077     }
00078 
00079     //Function to check and create the needed dir to
00080     //save all the backup
00081     function check_and_create_backup_dir($backup_unique_code) {
00082         global $CFG;
00083 
00084         $status = check_dir_exists($CFG->tempdir."",true);
00085         if ($status) {
00086             $status = check_dir_exists($CFG->tempdir."/backup",true);
00087         }
00088         if ($status) {
00089             $status = check_dir_exists($CFG->tempdir."/backup/".$backup_unique_code,true);
00090         }
00091 
00092         return $status;
00093     }
00094 
00095     //Function to delete all the directory contents recursively
00096     //it supports a excluded dit too
00097     //Copied from the web !!
00098     function delete_dir_contents ($dir,$excludeddir="") {
00099         global $CFG;
00100 
00101         if (!is_dir($dir)) {
00102             // if we've been given a directory that doesn't exist yet, return true.
00103             // this happens when we're trying to clear out a course that has only just
00104             // been created.
00105             return true;
00106         }
00107         $slash = "/";
00108 
00109         // Create arrays to store files and directories
00110         $dir_files      = array();
00111         $dir_subdirs    = array();
00112 
00113         // Make sure we can delete it
00114         chmod($dir, $CFG->directorypermissions);
00115 
00116         if ((($handle = opendir($dir))) == FALSE) {
00117             // The directory could not be opened
00118             return false;
00119         }
00120 
00121         // Loop through all directory entries, and construct two temporary arrays containing files and sub directories
00122         while (false !== ($entry = readdir($handle))) {
00123             if (is_dir($dir. $slash .$entry) && $entry != ".." && $entry != "." && $entry != $excludeddir) {
00124                 $dir_subdirs[] = $dir. $slash .$entry;
00125             }
00126             else if ($entry != ".." && $entry != "." && $entry != $excludeddir) {
00127                 $dir_files[] = $dir. $slash .$entry;
00128             }
00129         }
00130 
00131         // Delete all files in the curent directory return false and halt if a file cannot be removed
00132         $countdirfiles = count($dir_files);
00133         for ($i=0; $i<$countdirfiles; $i++) {
00134             chmod($dir_files[$i], $CFG->directorypermissions);
00135             if (((unlink($dir_files[$i]))) == FALSE) {
00136                 return false;
00137             }
00138         }
00139 
00140         // Empty sub directories and then remove the directory
00141         $countdirsubdirs = count($dir_subdirs);
00142         for($i=0; $i<$countdirsubdirs; $i++) {
00143             chmod($dir_subdirs[$i], $CFG->directorypermissions);
00144             if (delete_dir_contents($dir_subdirs[$i]) == FALSE) {
00145                 return false;
00146             }
00147             else {
00148                 if (remove_dir($dir_subdirs[$i]) == FALSE) {
00149                 return false;
00150                 }
00151             }
00152         }
00153 
00154         // Close directory
00155         closedir($handle);
00156 
00157         // Success, every thing is gone return true
00158         return true;
00159     }
00160 
00161     //Function to clear (empty) the contents of the backup_dir
00162     function clear_backup_dir($backup_unique_code) {
00163         global $CFG;
00164 
00165         $rootdir = $CFG->tempdir."/backup/".$backup_unique_code;
00166 
00167         //Delete recursively
00168         $status = delete_dir_contents($rootdir);
00169 
00170         return $status;
00171     }
00172 
00173     //Returns the module type of a course_module's id in a course
00174     function get_module_type ($courseid,$moduleid) {
00175         global $DB;
00176 
00177         $results = $DB->get_records_sql("SELECT cm.id, m.name
00178                                            FROM {course_modules} cm, {modules} m
00179                                           WHERE cm.course = ? AND cm.id = ? AND
00180                                                 m.id = cm.module", array($courseid, $moduleid));
00181 
00182         if ($results) {
00183             $name = $results[$moduleid]->name;
00184         } else {
00185             $name = false;
00186         }
00187         return $name;
00188     }
00189 
00190     //This function return the names of all directories under a give directory
00191     //Not recursive
00192     function list_directories ($rootdir) {
00193 
00194         $results = null;
00195 
00196         $dir = opendir($rootdir);
00197         while (false !== ($file=readdir($dir))) {
00198             if ($file=="." || $file=="..") {
00199                 continue;
00200             }
00201             if (is_dir($rootdir."/".$file)) {
00202                 $results[$file] = $file;
00203             }
00204         }
00205         closedir($dir);
00206         return $results;
00207     }
00208 
00209     //This function return the names of all directories and files under a give directory
00210     //Not recursive
00211     function list_directories_and_files ($rootdir) {
00212 
00213         $results = "";
00214 
00215         $dir = opendir($rootdir);
00216         while (false !== ($file=readdir($dir))) {
00217             if ($file=="." || $file=="..") {
00218                 continue;
00219             }
00220             $results[$file] = $file;
00221         }
00222         closedir($dir);
00223         return $results;
00224     }
00225 
00226     //This function clean data from backup tables and
00227     //delete all temp files used
00228     function clean_temp_data ($preferences) {
00229         global $CFG, $DB;
00230 
00231         $status = true;
00232 
00233         //true->do it, false->don't do it. To debug if necessary.
00234         if (true) {
00235             //Now delete from tables
00236             $status = $DB->delete_records('backup_ids', array('backup_code'=>$preferences->backup_unique_code))
00237                    && $DB->delete_records('backup_files', array('backup_code'=>$preferences->backup_unique_code));
00238 
00239             //Now, delete temp directory (if exists)
00240             $file_path = $CFG->tempdir."/backup/".$preferences->backup_unique_code;
00241             if (is_dir($file_path)) {
00242                 $status = delete_dir_contents($file_path);
00243                 //There is nothing, delete the directory itself
00244                 if ($status) {
00245                     $status = rmdir($file_path);
00246                 }
00247             }
00248         }
00249         return $status;
00250     }
00251 
00252     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00253     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00254     //This functions are used to copy any file or directory ($from_file)
00255     //to a new file or directory ($to_file). It works recursively and
00256     //mantains file perms.
00257     //I've copied it from: http://www.php.net/manual/en/function.copy.php
00258     //Little modifications done
00259 
00260     function backup_copy_file ($from_file,$to_file,$log_clam=false) {
00261         global $CFG;
00262 
00263         if (is_file($from_file)) {
00264             //echo "<br />Copying ".$from_file." to ".$to_file;              //Debug
00265             //$perms=fileperms($from_file);
00266             //return copy($from_file,$to_file) && chmod($to_file,$perms);
00267             umask(0000);
00268             if (copy($from_file,$to_file)) {
00269                 chmod($to_file,$CFG->directorypermissions);
00270                 if (!empty($log_clam)) {
00271                     //clam_log_upload($to_file,null,true);
00272                 }
00273                 return true;
00274             }
00275             return false;
00276         }
00277         else if (is_dir($from_file)) {
00278             return backup_copy_dir($from_file,$to_file);
00279         }
00280         else{
00281             //echo "<br />Error: not file or dir ".$from_file;               //Debug
00282             return false;
00283         }
00284     }
00285 
00286     function backup_copy_dir($from_file,$to_file) {
00287         global $CFG;
00288 
00289         $status = true; // Initialize this, next code will change its value if needed
00290 
00291         if (!is_dir($to_file)) {
00292             //echo "<br />Creating ".$to_file;                                //Debug
00293             umask(0000);
00294             $status = mkdir($to_file,$CFG->directorypermissions);
00295         }
00296         $dir = opendir($from_file);
00297         while (false !== ($file=readdir($dir))) {
00298             if ($file=="." || $file=="..") {
00299                 continue;
00300             }
00301             $status = backup_copy_file ("$from_file/$file","$to_file/$file");
00302         }
00303         closedir($dir);
00304         return $status;
00305     }
00307     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00308     // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00309 
00317     function backup_is_same_site(&$restore) {
00318         global $CFG;
00319         static $hashedsiteid = null;
00320         if (is_null($hashedsiteid)) {
00321             $hashedsiteid = md5(get_site_identifier());
00322         }
00323         if (!empty($restore->original_siteidentifier)) {
00324             return $restore->original_siteidentifier == $hashedsiteid;
00325         } else {
00326             return $restore->original_wwwroot == $CFG->wwwroot;
00327         }
00328     }
00329 
00330     //This function is used to insert records in the backup_ids table
00331     //If the info field is greater than max_db_storage, then its info
00332     //is saved to filesystem
00333     function backup_putid($backup_unique_code, $table, $old_id, $new_id, $info="") {
00334         global $CFG, $DB;
00335 
00336         $max_db_storage = 128;  //Max bytes to save to db, else save to file
00337 
00338         $status = true;
00339 
00340         //First delete to avoid PK duplicates
00341         $status = backup_delid($backup_unique_code, $table, $old_id);
00342 
00343         //Now, serialize info
00344         $info_ser = serialize($info);
00345 
00346         //Now, if the size of $info_ser > $max_db_storage, save it to filesystem and
00347         //insert a "infile" in the info field
00348 
00349         if (strlen($info_ser) > $max_db_storage) {
00350             //Calculate filename (in current_backup_dir, $backup_unique_code_$table_$old_id.info)
00351             $filename = $CFG->tempdir."/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info";
00352             //Save data to file
00353             $status = backup_data2file($filename,$info_ser);
00354             //Set info_to save
00355             $info_to_save = "infile";
00356         } else {
00357             //Saving to db
00358             $info_to_save = $info_ser;
00359         }
00360 
00361         //Now, insert the record
00362         if ($status) {
00363             //Build the record
00364             $rec = new stdClass();
00365             $rec->backup_code = $backup_unique_code;
00366             $rec->table_name = $table;
00367             $rec->old_id = $old_id;
00368             $rec->new_id = ($new_id === null? 0 : $new_id);
00369             $rec->info = $info_to_save;
00370 
00371             $DB->insert_record('backup_ids', $rec, false);
00372         }
00373         return $status;
00374     }
00375 
00376     //This function is used to delete recods from the backup_ids table
00377     //If the info field is "infile" then the file is deleted too
00378     function backup_delid ($backup_unique_code, $table, $old_id) {
00379         global $DB;
00380         return $DB->delete_records('backup_ids', array('backup_code'=>$backup_unique_code, 'table_name'=>$table, 'old_id'=>$old_id));
00381     }
00382 
00383     //This function is used to get a record from the backup_ids table
00384     //If the info field is "infile" then its info
00385     //is read from filesystem
00386     function backup_getid ($backup_unique_code, $table, $old_id) {
00387         global $CFG, $DB;
00388 
00389         $status = true;
00390         $status2 = true;
00391 
00392         $status = $DB->get_record("backup_ids", array("backup_code"=>$backup_unique_code,
00393                                   "table_name"=>$table, "old_id"=>$old_id));
00394 
00395         //If info field = "infile", get file contents
00396         if (!empty($status->info) && $status->info == "infile") {
00397             $filename = $CFG->tempdir."/backup/".$backup_unique_code."/".$backup_unique_code."_".$table."_".$old_id.".info";
00398             //Read data from file
00399             $status2 = backup_file2data($filename,$info);
00400             if ($status2) {
00401                 //unserialize data
00402                 $status->info = unserialize($info);
00403             } else {
00404                 $status = false;
00405             }
00406         } else {
00407             //Only if status (record exists)
00408             if (!empty($status->info)) {
00409                 if ($status->info === 'needed') {
00410                     // TODO: ugly hack - fix before 1.9.1
00411                     debugging('Incorrect string "needed" in $status->info, please fix the code (table:'.$table.'; old_id:'.$old_id.').', DEBUG_DEVELOPER);
00412                 } else {
00414                     $temp = $status->info;
00415                     //Now unserialize
00416                     $status->info = unserialize($temp);
00417                 }
00418             }
00419         }
00420 
00421         return $status;
00422     }
00423 
00424     //This function is used to add slashes (and decode from UTF-8 if needed)
00425     //It's used intensivelly when restoring modules and saving them in db
00426     function backup_todb ($data) {
00427         // MDL-10770
00428         if ($data === '$@NULL@$') {
00429             return null;
00430         } else {
00431             return restore_decode_absolute_links($data);
00432         }
00433     }
00434 
00435     //This function is used to check that every necessary function to
00436     //backup/restore exists in the current php installation. Thanks to
00437     //gregb@crowncollege.edu by the idea.
00438     function backup_required_functions($justcheck=false) {
00439 
00440         if(!function_exists('utf8_encode')) {
00441             if (empty($justcheck)) {
00442                 print_error('needphpext', '', '', 'XML');
00443             } else {
00444                 return false;
00445             }
00446         }
00447 
00448         return true;
00449     }
00450 
00451     //This function send n white characters to the browser and flush the
00452     //output buffer. Used to avoid browser timeouts and to show the progress.
00453     function backup_flush($n=0,$time=false) {
00454         if (defined('RESTORE_SILENTLY_NOFLUSH')) {
00455             return;
00456         }
00457         if ($time) {
00458             $ti = strftime("%X",time());
00459         } else {
00460             $ti = "";
00461         }
00462         echo str_repeat(" ", $n) . $ti . "\n";
00463         flush();
00464     }
00465 
00466     //This function creates the filename and write data to it
00467     //returning status as result
00468     function backup_data2file ($file,&$data) {
00469 
00470         $status = true;
00471         $status2 = true;
00472 
00473         $f = fopen($file,"w");
00474         $status = fwrite($f,$data);
00475         $status2 = fclose($f);
00476 
00477         return ($status && $status2);
00478     }
00479 
00480     //This function read the filename and read data from it
00481     function backup_file2data ($file,&$data) {
00482 
00483         $status = true;
00484         $status2 = true;
00485 
00486         $f = fopen($file,"r");
00487         $data = fread ($f,filesize($file));
00488         $status2 = fclose($f);
00489 
00490         return ($status && $status2);
00491     }
 All Data Structures Namespaces Files Functions Variables Enumerations