Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/uploadlib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00036 class upload_manager {
00037 
00042     var $files;
00047     var $config;
00053     var $status;
00059     var $course;
00065     var $inputname;
00071     var $notify;
00072 
00089     function upload_manager($inputname='', $deleteothers=false, $handlecollisions=false, $course=null, $recoverifmultiple=false, $modbytes=0, $silent=false, $allownull=false, $allownullmultiple=true) {
00090 
00091         global $CFG, $SITE;
00092 
00093         if (empty($course->id)) {
00094             $course = $SITE;
00095         }
00096 
00097         $this->config->deleteothers = $deleteothers;
00098         $this->config->handlecollisions = $handlecollisions;
00099         $this->config->recoverifmultiple = $recoverifmultiple;
00100         $this->config->maxbytes = get_max_upload_file_size($CFG->maxbytes, $course->maxbytes, $modbytes);
00101         $this->config->silent = $silent;
00102         $this->config->allownull = $allownull;
00103         $this->files = array();
00104         $this->status = false;
00105         $this->course = $course;
00106         $this->inputname = $inputname;
00107         if (empty($this->inputname)) {
00108             $this->config->allownull = $allownullmultiple;
00109         }
00110     }
00111 
00120     function preprocess_files() {
00121         global $CFG, $OUTPUT;
00122 
00123         foreach ($_FILES as $name => $file) {
00124             $this->status = true; // only set it to true here so that we can check if this function has been called.
00125             if (empty($this->inputname) || $name == $this->inputname) { // if we have input name, only process if it matches.
00126                 $file['originalname'] = $file['name']; // do this first for the log.
00127                 $this->files[$name] = $file; // put it in first so we can get uploadlog out in print_upload_log.
00128                 $this->files[$name]['uploadlog'] = ''; // initialize error log
00129                 $this->status = $this->validate_file($this->files[$name]); // default to only allowing empty on multiple uploads.
00130                 if (!$this->status && ($this->files[$name]['error'] == 0 || $this->files[$name]['error'] == 4) && ($this->config->allownull || empty($this->inputname))) {
00131                     // this shouldn't cause everything to stop.. modules should be responsible for knowing which if any are compulsory.
00132                     continue;
00133                 }
00134                 if ($this->status && !empty($CFG->runclamonupload)) {
00135                     $this->status = clam_scan_moodle_file($this->files[$name],$this->course);
00136                 }
00137                 if (!$this->status) {
00138                     if (!$this->config->recoverifmultiple && count($this->files) > 1) {
00139                         $a = new stdClass();
00140                         $a->name    = $this->files[$name]['originalname'];
00141                         $a->problem = $this->files[$name]['uploadlog'];
00142                         if (!$this->config->silent) {
00143                             echo $OUTPUT->notification(get_string('uploadfailednotrecovering','moodle',$a));
00144                         }
00145                         else {
00146                             $this->notify .= '<br />'. get_string('uploadfailednotrecovering','moodle',$a);
00147                         }
00148                         $this->status = false;
00149                         return false;
00150 
00151                     } else if (count($this->files) == 1) {
00152 
00153                         if (!$this->config->silent and !$this->config->allownull) {
00154                             echo $OUTPUT->notification($this->files[$name]['uploadlog']);
00155                         } else {
00156                             $this->notify .= '<br />'. $this->files[$name]['uploadlog'];
00157                         }
00158                         $this->status = false;
00159                         return false;
00160                     }
00161                 }
00162                 else {
00163                     $newname = clean_filename($this->files[$name]['name']);
00164                     if ($newname != $this->files[$name]['name']) {
00165                         $a = new stdClass();
00166                         $a->oldname = $this->files[$name]['name'];
00167                         $a->newname = $newname;
00168                         $this->files[$name]['uploadlog'] .= get_string('uploadrenamedchars','moodle', $a);
00169                     }
00170                     $this->files[$name]['name'] = $newname;
00171                     $this->files[$name]['clear'] = true; // ok to save.
00172                     $this->config->somethingtosave = true;
00173                 }
00174             }
00175         }
00176         if (!is_array($_FILES) || count($_FILES) == 0) {
00177             return $this->config->allownull;
00178         }
00179         $this->status = true;
00180         return true; // if we've got this far it means that we're recovering so we want status to be ok.
00181     }
00182 
00189     function validate_file(&$file) {
00190         if (empty($file)) {
00191             return false;
00192         }
00193         if (!is_uploaded_file($file['tmp_name']) || $file['size'] == 0) {
00194             $file['uploadlog'] .= "\n".$this->get_file_upload_error($file);
00195             return false;
00196         }
00197         if ($file['size'] > $this->config->maxbytes) {
00198             $file['uploadlog'] .= "\n". get_string('uploadedfiletoobig', 'moodle', $this->config->maxbytes);
00199             return false;
00200         }
00201         return true;
00202     }
00203 
00212     function save_files($destination) {
00213         global $CFG, $USER, $OUTPUT;
00214 
00215         if (!$this->status) { // preprocess_files hasn't been run
00216             $this->preprocess_files();
00217         }
00218 
00219         // if there are no files, bail before we create an empty directory.
00220         if (empty($this->config->somethingtosave)) {
00221             return true;
00222         }
00223 
00224         $savedsomething = false;
00225 
00226         if ($this->status) {
00227             if (!(strpos($destination, $CFG->dataroot) === false)) {
00228                 // take it out for giving to make_upload_directory
00229                 $destination = substr($destination, strlen($CFG->dataroot)+1);
00230             }
00231 
00232             if ($destination{strlen($destination)-1} == '/') { // strip off a trailing / if we have one
00233                 $destination = substr($destination, 0, -1);
00234             }
00235 
00236             if (!make_upload_directory($destination, true)) { //TODO maybe put this function here instead of moodlelib.php now.
00237                 $this->status = false;
00238                 return false;
00239             }
00240 
00241             $destination = $CFG->dataroot .'/'. $destination; // now add it back in so we have a full path
00242 
00243             $exceptions = array(); //need this later if we're deleting other files.
00244 
00245             foreach (array_keys($this->files) as $i) {
00246 
00247                 if (!$this->files[$i]['clear']) {
00248                     // not ok to save
00249                     continue;
00250                 }
00251 
00252                 if ($this->config->handlecollisions) {
00253                     $this->handle_filename_collision($destination, $this->files[$i]);
00254                 }
00255                 if (move_uploaded_file($this->files[$i]['tmp_name'], $destination.'/'.$this->files[$i]['name'])) {
00256                     chmod($destination .'/'. $this->files[$i]['name'], $CFG->directorypermissions);
00257                     $this->files[$i]['fullpath'] = $destination.'/'.$this->files[$i]['name'];
00258                     $this->files[$i]['uploadlog'] .= "\n".get_string('uploadedfile');
00259                     $this->files[$i]['saved'] = true;
00260                     $exceptions[] = $this->files[$i]['name'];
00261                     // now add it to the log (this is important so we know who to notify if a virus is found later on)
00262                     clam_log_upload($this->files[$i]['fullpath'], $this->course);
00263                     $savedsomething=true;
00264                 }
00265             }
00266             if ($savedsomething && $this->config->deleteothers) {
00267                 $this->delete_other_files($destination, $exceptions);
00268             }
00269         }
00270         if (empty($savedsomething)) {
00271             $this->status = false;
00272             if ((empty($this->config->allownull) && !empty($this->inputname)) || (empty($this->inputname) && empty($this->config->allownullmultiple))) {
00273                 echo $OUTPUT->notification(get_string('uploadnofilefound'));
00274             }
00275             return false;
00276         }
00277         return $this->status;
00278     }
00279 
00286     function process_file_uploads($destination) {
00287         if ($this->preprocess_files()) {
00288             return $this->save_files($destination);
00289         }
00290         return false;
00291     }
00292 
00299     function delete_other_files($destination, $exceptions=null) {
00300         global $OUTPUT;
00301         $deletedsomething = false;
00302         if ($filestodel = get_directory_list($destination)) {
00303             foreach ($filestodel as $file) {
00304                 if (!is_array($exceptions) || !in_array($file, $exceptions)) {
00305                     unlink($destination .'/'. $file);
00306                     $deletedsomething = true;
00307                 }
00308             }
00309         }
00310         if ($deletedsomething) {
00311             if (!$this->config->silent) {
00312                 echo $OUTPUT->notification(get_string('uploadoldfilesdeleted'));
00313             }
00314             else {
00315                 $this->notify .= '<br />'. get_string('uploadoldfilesdeleted');
00316             }
00317         }
00318     }
00319 
00326     function handle_filename_collision($destination, &$file) {
00327         if (!file_exists($destination .'/'. $file['name'])) {
00328             return;
00329         }
00330 
00331         $parts     = explode('.', $file['name']);
00332         if (count($parts) > 1) {
00333             $extension = '.'.array_pop($parts);
00334             $name      = implode('.', $parts);
00335         } else {
00336             $extension = '';
00337             $name      = $file['name'];
00338         }
00339 
00340         $current = 0;
00341         if (preg_match('/^(.*)_(\d*)$/s', $name, $matches)) {
00342             $name    = $matches[1];
00343             $current = (int)$matches[2];
00344         }
00345         $i = $current + 1;
00346 
00347         while (!$this->check_before_renaming($destination, $name.'_'.$i.$extension, $file)) {
00348             $i++;
00349         }
00350         $a = new stdClass();
00351         $a->oldname = $file['name'];
00352         $file['name'] = $name.'_'.$i.$extension;
00353         $a->newname = $file['name'];
00354         $file['uploadlog'] .= "\n". get_string('uploadrenamedcollision','moodle', $a);
00355     }
00356 
00364     function check_before_renaming($destination, $nametocheck, $file) {
00365         if (!file_exists($destination .'/'. $nametocheck)) {
00366             return true;
00367         }
00368         if ($this->config->deleteothers) {
00369             foreach ($this->files as $tocheck) {
00370                 // if we're deleting files anyway, it's not THIS file and we care about it and it has the same name and has already been saved..
00371                 if ($file['tmp_name'] != $tocheck['tmp_name'] && $tocheck['clear'] && $nametocheck == $tocheck['name'] && $tocheck['saved']) {
00372                     $collision = true;
00373                 }
00374             }
00375             if (!$collision) {
00376                 return true;
00377             }
00378         }
00379         return false;
00380     }
00381 
00389     function get_file_upload_error(&$file) {
00390 
00391         switch ($file['error']) {
00392         case 0: // UPLOAD_ERR_OK
00393             if ($file['size'] > 0) {
00394                 $errmessage = get_string('uploadproblem', $file['name']);
00395             } else {
00396                 $errmessage = get_string('uploadnofilefound'); 
00397             }
00398             break;
00399 
00400         case 1: // UPLOAD_ERR_INI_SIZE
00401             $errmessage = get_string('uploadserverlimit');
00402             break;
00403 
00404         case 2: // UPLOAD_ERR_FORM_SIZE
00405             $errmessage = get_string('uploadformlimit');
00406             break;
00407 
00408         case 3: // UPLOAD_ERR_PARTIAL
00409             $errmessage = get_string('uploadpartialfile');
00410             break;
00411 
00412         case 4: // UPLOAD_ERR_NO_FILE
00413             $errmessage = get_string('uploadnofilefound');
00414             break;
00415 
00416         // Note: there is no error with a value of 5
00417 
00418         case 6: // UPLOAD_ERR_NO_TMP_DIR
00419             $errmessage = get_string('uploadnotempdir');
00420             break;
00421 
00422         case 7: // UPLOAD_ERR_CANT_WRITE
00423             $errmessage = get_string('uploadcantwrite');
00424             break;
00425 
00426         case 8: // UPLOAD_ERR_EXTENSION
00427             $errmessage = get_string('uploadextension');
00428             break;
00429 
00430         default:
00431             $errmessage = get_string('uploadproblem', $file['name']);
00432         }
00433         return $errmessage;
00434     }
00435 
00440     function print_upload_log($return=false,$skipemptyifmultiple=false) {
00441         $str = '';
00442         foreach (array_keys($this->files) as $i => $key) {
00443             if (count($this->files) > 1 && !empty($skipemptyifmultiple) && $this->files[$key]['error'] == 4) {
00444                 continue;
00445             }
00446             $str .= '<strong>'. get_string('uploadfilelog', 'moodle', $i+1) .' '
00447                 .((!empty($this->files[$key]['originalname'])) ? '('.$this->files[$key]['originalname'].')' : '')
00448                 .'</strong> :'. nl2br($this->files[$key]['uploadlog']) .'<br />';
00449         }
00450         if ($return) {
00451             return $str;
00452         }
00453         echo $str;
00454     }
00455 
00460     function get_new_filename() {
00461         if (!empty($this->inputname) and count($this->files) == 1 and $this->files[$this->inputname]['error'] != 4) {
00462             return $this->files[$this->inputname]['name'];
00463         }
00464         return false;
00465     }
00466 
00471     function get_new_filepath() {
00472         if (!empty($this->inputname) and count($this->files) == 1 and $this->files[$this->inputname]['error'] != 4) {
00473             return $this->files[$this->inputname]['fullpath'];
00474         }
00475         return false;
00476     }
00477 
00482     function get_original_filename() {
00483         if (!empty($this->inputname) and count($this->files) == 1 and $this->files[$this->inputname]['error'] != 4) {
00484             return $this->files[$this->inputname]['originalname'];
00485         }
00486         return false;
00487     }
00488 
00493     function get_errors() {
00494         if (!empty($this->notify)) {
00495             return '<p class="notifyproblem">'. $this->notify .'</p>';
00496         } else {
00497             return null;
00498         }
00499     }
00500 }
00501 
00502 /**************************************************************************************
00503 THESE FUNCTIONS ARE OUTSIDE THE CLASS BECAUSE THEY NEED TO BE CALLED FROM OTHER PLACES.
00504 FOR EXAMPLE CLAM_HANDLE_INFECTED_FILE AND CLAM_REPLACE_INFECTED_FILE USED FROM CRON
00505 UPLOAD_PRINT_FORM_FRAGMENT DOESN'T REALLY BELONG IN THE CLASS BUT CERTAINLY IN THIS FILE
00506 ***************************************************************************************/
00507 
00521 function clam_handle_infected_file($file, $userid=0, $basiconly=false) {
00522 
00523     global $CFG, $USER;
00524     if ($USER && !$userid) {
00525         $userid = $USER->id;
00526     }
00527     $delete = true;
00528     if (file_exists($CFG->quarantinedir) && is_dir($CFG->quarantinedir) && is_writable($CFG->quarantinedir)) {
00529         $now = date('YmdHis');
00530         if (rename($file, $CFG->quarantinedir .'/'. $now .'-user-'. $userid .'-infected')) {
00531             $delete = false;
00532             clam_log_infected($file, $CFG->quarantinedir.'/'. $now .'-user-'. $userid .'-infected', $userid);
00533             if ($basiconly) {
00534                 $notice .= "\n". get_string('clammovedfilebasic');
00535             }
00536             else {
00537                 $notice .= "\n". get_string('clammovedfile', 'moodle', $CFG->quarantinedir.'/'. $now .'-user-'. $userid .'-infected');
00538             }
00539         }
00540         else {
00541             if ($basiconly) {
00542                 $notice .= "\n". get_string('clamdeletedfile');
00543             }
00544             else {
00545                 $notice .= "\n". get_string('clamquarantinedirfailed', 'moodle', $CFG->quarantinedir);
00546             }
00547         }
00548     }
00549     else {
00550         if ($basiconly) {
00551             $notice .= "\n". get_string('clamdeletedfile');
00552         }
00553         else {
00554             $notice .= "\n". get_string('clamquarantinedirfailed', 'moodle', $CFG->quarantinedir);
00555         }
00556     }
00557     if ($delete) {
00558         if (unlink($file)) {
00559             clam_log_infected($file, '', $userid);
00560             $notice .= "\n". get_string('clamdeletedfile');
00561         }
00562         else {
00563             if ($basiconly) {
00564                 // still tell the user the file has been deleted. this is only for admins.
00565                 $notice .= "\n". get_string('clamdeletedfile');
00566             }
00567             else {
00568                 $notice .= "\n". get_string('clamdeletedfilefailed');
00569             }
00570         }
00571     }
00572     return $notice;
00573 }
00574 
00584 function clam_replace_infected_file($file) {
00585     $newcontents = get_string('virusplaceholder');
00586     if (!$f = fopen($file, 'w')) {
00587         return false;
00588     }
00589     if (!fwrite($f, $newcontents)) {
00590         return false;
00591     }
00592     return true;
00593 }
00594 
00595 
00607 function clam_scan_moodle_file(&$file, $course) {
00608     global $CFG, $USER;
00609 
00610     if (is_array($file) && is_uploaded_file($file['tmp_name'])) { // it's from $_FILES
00611         $appendlog = true;
00612         $fullpath = $file['tmp_name'];
00613     }
00614     else if (file_exists($file)) { // it's a path to somewhere on the filesystem!
00615         $fullpath = $file;
00616     }
00617     else {
00618         return false; // erm, what is this supposed to be then, huh?
00619     }
00620 
00621     $CFG->pathtoclam = trim($CFG->pathtoclam);
00622 
00623     if (!$CFG->pathtoclam || !file_exists($CFG->pathtoclam) || !is_executable($CFG->pathtoclam)) {
00624         $newreturn = 1;
00625         $notice = get_string('clamlost', 'moodle', $CFG->pathtoclam);
00626         if ($CFG->clamfailureonupload == 'actlikevirus') {
00627             $notice .= "\n". get_string('clamlostandactinglikevirus');
00628             $notice .= "\n". clam_handle_infected_file($fullpath);
00629             $newreturn = false;
00630         }
00631         clam_message_admins($notice);
00632         if ($appendlog) {
00633             $file['uploadlog'] .= "\n". get_string('clambroken');
00634             $file['clam'] = 1;
00635         }
00636         return $newreturn; // return 1 if we're allowing clam failures
00637     }
00638 
00639     $cmd = $CFG->pathtoclam .' '. $fullpath ." 2>&1";
00640 
00641     // before we do anything we need to change perms so that clamscan can read the file (clamdscan won't work otherwise)
00642     chmod($fullpath, $CFG->directorypermissions);
00643 
00644     exec($cmd, $output, $return);
00645 
00646 
00647     switch ($return) {
00648     case 0: // glee! we're ok.
00649         return 1; // translate clam return code into reasonable return code consistent with everything else.
00650     case 1:  // bad wicked evil, we have a virus.
00651         $info = new stdClass();
00652         if (!empty($course)) {
00653             $info->course = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
00654         }
00655         else {
00656             $info->course = 'No course';
00657         }
00658         $info->user = fullname($USER);
00659         $notice = get_string('virusfound', 'moodle', $info);
00660         $notice .= "\n\n". implode("\n", $output);
00661         $notice .= "\n\n". clam_handle_infected_file($fullpath);
00662         clam_message_admins($notice);
00663         if ($appendlog) {
00664             $info->filename = $file['originalname'];
00665             $file['uploadlog'] .= "\n". get_string('virusfounduser', 'moodle', $info);
00666             $file['virus'] = 1;
00667         }
00668         return false; // in this case, 0 means bad.
00669     default:
00670         // error - clam failed to run or something went wrong
00671         $notice .= get_string('clamfailed', 'moodle', get_clam_error_code($return));
00672         $notice .= "\n\n". implode("\n", $output);
00673         $newreturn = true;
00674         if ($CFG->clamfailureonupload == 'actlikevirus') {
00675             $notice .= "\n". clam_handle_infected_file($fullpath);
00676             $newreturn = false;
00677         }
00678         clam_message_admins($notice);
00679         if ($appendlog) {
00680             $file['uploadlog'] .= "\n". get_string('clambroken');
00681             $file['clam'] = 1;
00682         }
00683         return $newreturn; // return 1 if we're allowing failures.
00684     }
00685 }
00686 
00692 function clam_message_admins($notice) {
00693 
00694     $site = get_site();
00695 
00696     $subject = get_string('clamemailsubject', 'moodle', format_string($site->fullname));
00697     $admins = get_admins();
00698     foreach ($admins as $admin) {
00699         $eventdata = new stdClass();
00700         $eventdata->component         = 'moodle';
00701         $eventdata->name              = 'errors';
00702         $eventdata->userfrom          = get_admin();
00703         $eventdata->userto            = $admin;
00704         $eventdata->subject           = $subject;
00705         $eventdata->fullmessage       = $notice;
00706         $eventdata->fullmessageformat = FORMAT_PLAIN;
00707         $eventdata->fullmessagehtml   = '';
00708         $eventdata->smallmessage      = '';
00709         message_send($eventdata);
00710     }
00711 }
00712 
00713 
00720 function get_clam_error_code($returncode) {
00721     $returncodes = array();
00722     $returncodes[0] = 'No virus found.';
00723     $returncodes[1] = 'Virus(es) found.';
00724     $returncodes[2] = ' An error occured'; // specific to clamdscan
00725     // all after here are specific to clamscan
00726     $returncodes[40] = 'Unknown option passed.';
00727     $returncodes[50] = 'Database initialization error.';
00728     $returncodes[52] = 'Not supported file type.';
00729     $returncodes[53] = 'Can\'t open directory.';
00730     $returncodes[54] = 'Can\'t open file. (ofm)';
00731     $returncodes[55] = 'Error reading file. (ofm)';
00732     $returncodes[56] = 'Can\'t stat input file / directory.';
00733     $returncodes[57] = 'Can\'t get absolute path name of current working directory.';
00734     $returncodes[58] = 'I/O error, please check your filesystem.';
00735     $returncodes[59] = 'Can\'t get information about current user from /etc/passwd.';
00736     $returncodes[60] = 'Can\'t get information about user \'clamav\' (default name) from /etc/passwd.';
00737     $returncodes[61] = 'Can\'t fork.';
00738     $returncodes[63] = 'Can\'t create temporary files/directories (check permissions).';
00739     $returncodes[64] = 'Can\'t write to temporary directory (please specify another one).';
00740     $returncodes[70] = 'Can\'t allocate and clear memory (calloc).';
00741     $returncodes[71] = 'Can\'t allocate memory (malloc).';
00742     if ($returncodes[$returncode])
00743        return $returncodes[$returncode];
00744     return get_string('clamunknownerror');
00745 
00746 }
00747 
00758 function clam_log_upload($newfilepath, $course=null, $nourl=false) {
00759     global $CFG, $USER;
00760     // get rid of any double // that might have appeared
00761     $newfilepath = preg_replace('/\/\//', '/', $newfilepath);
00762     if (strpos($newfilepath, $CFG->dataroot) === false) {
00763         $newfilepath = $CFG->dataroot .'/'. $newfilepath;
00764     }
00765     $courseid = 0;
00766     if ($course) {
00767         $courseid = $course->id;
00768     }
00769     add_to_log($courseid, 'upload', 'upload', ((!$nourl) ? substr($_SERVER['HTTP_REFERER'], 0, 100) : ''), $newfilepath);
00770 }
00771 
00780 function clam_log_infected($oldfilepath='', $newfilepath='', $userid=0) {
00781     global $DB;
00782 
00783     add_to_log(0, 'upload', 'infected', $_SERVER['HTTP_REFERER'], $oldfilepath, 0, $userid);
00784 
00785     $user = $DB->get_record('user', array('id'=>$userid));
00786 
00787     $errorstr = 'Clam AV has found a file that is infected with a virus. It was uploaded by '
00788         . ((empty($user)) ? ' an unknown user ' : fullname($user))
00789         . ((empty($oldfilepath)) ? '. The infected file was caught on upload ('.$oldfilepath.')'
00790            : '. The original file path of the infected file was '. $oldfilepath)
00791         . ((empty($newfilepath)) ? '. The file has been deleted ' : '. The file has been moved to a quarantine directory and the new path is '. $newfilepath);
00792 
00793     error_log($errorstr);
00794 }
00795 
00796 
00805 function clam_change_log($oldpath, $newpath, $update=true) {
00806     global $DB;
00807 
00808     if (!$record = $DB->get_record('log', array('info'=>$oldpath, 'module'=>'upload'))) {
00809         return false;
00810     }
00811     $record->info = $newpath;
00812     if ($update) {
00813         $DB->update_record('log', $record);
00814     } else {
00815         unset($record->id);
00816         $DB->insert_record('log', $record);
00817     }
00818 }
 All Data Structures Namespaces Files Functions Variables Enumerations