root/releases/0.8rc1/lms/sendfile.php

Revision 269, 6.3 kB (checked in by ben, 3 years ago)

--

  • Property svn:eol-style set to native
Line 
1 <?php
2
3 // accept a file send from the lms
4 require_once(dirname(dirname(__FILE__)).'/includes.php');
5 require_once($CFG->dirroot.'lib/lmslib.php');
6 require_once($CFG->dirroot.'lib/uploadlib.php');
7
8 $textlib = textlib_get_instance();
9
10 // the POST parameters we expect are:
11 $installid = optional_param('installid');
12 $username = optional_param('username');
13 $filename = optional_param('filename');
14 $action = optional_param('action');
15 $size = optional_param('size',0,PARAM_INT);
16 $signature = optional_param('signature');
17 $foldername = optional_param('foldername');
18
19 // verify the signature and find our user...
20 $user = find_lms_user($installid,$username,$signature);
21 if (!is_object($user)) {
22     echo $user;
23     die();
24 }
25
26 switch ($action) {
27  case 'intention':
28      $incoming = new StdClass;
29      $incoming->installid = $installid;
30      $incoming->intentiondate = time();
31      $incoming->user_id = $user->ident;
32      $incoming->foldername = $foldername; // should relate to course name.
33      $incoming->size = $size;
34      $id = insert_record('files_incoming',$incoming);
35
36      // create the holding directory if it doesn't already exist...
37      $dir = 'lms/incoming/'.$user->ident;
38
39      if (!make_upload_directory($dir,false)) {
40          echo 'Could not create holding directory';
41          die();
42      }
43      $filename = $CFG->dataroot.$dir.'/'.$id.'-'.time().'.zip';
44
45      echo 'OK|'.$filename;
46      break;
47
48  case 'done':
49      // first try and find the 'incoming' record that matches.
50      $m = array();
51      if (!preg_match('/(\d+)\-(\d+).zip/',$filename,$m)) {
52          echo 'couldn\'t find information about the specified file';
53          break;
54      }
55      if (!$intention = get_record('files_incoming','ident',$m[1])) {
56          echo 'couldn\'t find information about the specified file';
57          break;
58      }
59     
60      // check the date  (should be within an hour)
61      if ($intention->intentiondate < (time()-(60*60))) {
62          echo 'intention too old';
63          break;
64      }
65      // find the file
66      $filepath = $CFG->dataroot.'lms/incoming/'.$intention->user_id.'/'.$filename;
67      if (!file_exists($filepath)) {
68          echo 'couldn\'t find file';
69          break;
70      }
71      // check filesize
72      $actualsize = filesize($filepath);
73      if ($actualsize != $intention->size) {
74          echo 'filesize of received file ('.$actualsize.') didn\'t match expected size ('.$intention->size.')';
75          break;
76      }
77
78      // make a temporary directory to unzip the file into
79      $tempdir = 'temp/lms/'.$intention->user_id.'/'.time();
80      if (!make_upload_directory($tempdir,false)) {
81          echo 'Could not create temporary directory structure to extract the files into';
82          break;
83      }
84      $tempdir = $CFG->dataroot . $tempdir;
85
86      if (!unzip_file($filepath,$tempdir,false)) {
87          echo 'Could not unzip the file to the temporary directory';
88          break;
89      }
90
91      // read & parse the manifest file
92      $manifest = $tempdir.'/manifest.txt';
93      if (!file_exists($manifest)) {
94          echo 'Could not find the manifest file';
95          break;
96      }
97
98      if (!$contents = file($manifest)) {
99          echo 'Could not read the contents of the manifest file';
100          break;
101      }
102     
103      if (count($contents) == 0) {
104          echo 'Manifest file was empty!';
105          break;
106      }
107
108      $files = array(); // (temp) we need to rejuggle filenames to handle collisions.
109      $fileinfo = array(); // this is our proper data structure.
110      $ul_username = $user->username;
111      $upload_folder = $textlib->substr($ul_username,0,1);
112      $destination = "files/" . $upload_folder . "/" . $ul_username ;
113      $relativedestination = $destination;
114      make_upload_directory($destination,false);
115      $destination = $CFG->dataroot . $destination;
116
117      // first do some basic validation.
118      foreach ($contents as $line) {
119          $bits = explode('|',$line,2); // limit set to 2 so we just get filename|decription
120          if (count($bits) != 2) { // houston, we have a problem!
121              echo "Something wrong in manifest file, with line $line";
122              break 2;
123          }
124          if (!file_exists($tempdir.'/'.$bits[0])) {
125              echo "Manifest file points to ".$bits[0]." but it doesn't exist!";
126              break 2;
127          }
128          $files[] = $bits[0];
129      }
130     
131      // rejuggle to handle filename conflicts...
132      $files = resolve_filename_collisions($destination,$files);
133     
134      // keys should still match, make up the proper data structure...
135      foreach ($files as $k => $f) {
136          $file = new StdClass;
137          $file->filename = $f;
138          $line = $contents[$k];
139          $bits = explode('|',$line,2); // limit set to 2 so we just get filename|decription
140          $file->description = $bits[1];
141          $file->originalname = $bits[0];
142          $fileinfo[] = $file;
143      }
144
145      begin_sql(); // do it transactionally if we CAN
146         
147      // start looking for the database stuff we need....
148      $folder = lms_get_folder($installid,$intention->foldername,$user);
149
150      foreach ($fileinfo as $tosave) {
151          // first move the file to where it should go.
152          if (!copy($tempdir.'/'.$tosave->originalname,$destination.'/'.$tosave->filename)) {
153              echo 'Failed to save some files to the final destination!';
154              rollback_sql();
155              break 2;
156          }
157          $f = new StdClass;
158          $f->owner = $user->ident;
159          $f->files_owner = $user->ident;
160          $f->folder = $folder->ident;
161          $f->originalname = $tosave->originalname;
162          $f->title = $tosave->originalname;
163          $f->description = $tosave->description;
164          $f->location = $relativedestination.'/'.$tosave->filename;
165          $f->access = 'user'.$user->ident; // ew again.
166          $f->size = filesize($destination.'/'.$tosave->filename);
167          $f->time_uploaded = time();
168          if (!insert_record('files',$f)) {
169              echo 'Failed to save some file information to the database! Some files may have copied across ok';
170              rollback_sql();
171              break 2;
172          }
173      }
174
175      commit_sql();
176
177      // remove all the temporary stuff and delete the record from the queue.
178      delete_records('files_incoming','ident',$intention->ident);
179      delete_records_select('files_incoming','intentiondate < ?',array(time()-60*60));
180     
181      @unlink($filepath); // we may not have permissions to do this ...
182      remove_dir($tempdir);
183
184      echo 'OK';
185      break;
186 }
187 ?>
Note: See TracBrowser for help on using the browser.