ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilFileUtils.php
Go to the documentation of this file.
1 <?php
2 /*
3 +-----------------------------------------------------------------------------+
4 | ILIAS open source |
5 +-----------------------------------------------------------------------------+
6 | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7 | |
8 | This program is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU General Public License |
10 | as published by the Free Software Foundation; either version 2 |
11 | of the License, or (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 +-----------------------------------------------------------------------------+
22 */
23 
35 include_once 'Services/Utilities/classes/class.ilFileUtilsException.php';
36 
37 
39 {
40  protected static $new_files = array();
41 
55  function processZipFile ($a_directory, $a_file, $structure, $ref_id = null, $containerType = null, $tree = null, $access_handler = null) {
56 
57  global $lng;
58  include_once("Services/Utilities/classes/class.ilUtil.php");
59 
60  self::$new_files = array();
61 
62  $pathinfo = pathinfo($a_file);
63  $file = $pathinfo["basename"];
64 
65  // Copy zip-file to new directory, unzip and remove it
66  // TODO: check archive for broken file
67  //copy ($a_file, $a_directory . "/" . $file);
68  move_uploaded_file($a_file, $a_directory . "/" . $file);
69  ilUtil::unzip($a_directory . "/" . $file);
70  unlink ($a_directory . "/" . $file);
71 //echo "-".$a_directory . "/" . $file."-";
72  // Stores filename and paths into $filearray to check for viruses
73  // Checks if filenames can be read, else -> throw exception and leave
74  ilFileUtils::recursive_dirscan($a_directory, $filearray);
75 
76  // if there are no files unziped (->broken file!)
77  if (empty($filearray)) {
78  throw new ilFileUtilsException($lng->txt("archive_broken"), ilFileUtilsException::$BROKEN_FILE);
79  break;
80  }
81 
82  // virus handling
83  foreach ($filearray["file"] as $key => $value)
84  {
85  // remove "invisible" files
86  if(substr($value, 0, 1) == "." || stristr($filearray["path"][$key], "/__MACOSX/"))
87  {
88  unlink($filearray["path"][$key].$value);
89  unset($filearray["path"][$key]);
90  unset($filearray["file"][$key]);
91  continue;
92  }
93 
94  $vir = ilUtil::virusHandling($filearray["path"][$key], $value);
95  if (!$vir[0])
96  {
97  // Unlink file and throw exception
98  unlink($filearray[path][$key]);
99  throw new ilFileUtilsException($lng->txt("file_is_infected")."<br />".$vir[1], ilFileUtilsException::$INFECTED_FILE);
100  break;
101  }
102  else
103  {
104  if ($vir[1] != "")
105  {
107  break;
108  }
109  }
110  }
111 
112  // If archive is to be used "flat"
113  if (!$structure)
114  {
115  foreach (array_count_values($filearray["file"]) as $key => $value)
116  {
117  // Archive contains same filenames in different directories
118  if ($value != "1")
119  {
120  $doublettes .= " '" . ilFileUtils::utf8_encode($key) . "'";
121 
122  }
123  }
124  if (isset($doublettes))
125  {
126  throw new ilFileUtilsException($lng->txt("exc_upload_error") . "<br />" . $lng->txt("zip_structure_error") . $doublettes ,
128  break;
129  }
130  }
131  else
132  {
133  $mac_dir = $a_directory."/__MACOSX";
134  if(file_exists($mac_dir))
135  {
136  ilUtil::delDir($mac_dir);
137  }
138  }
139 
140  // Everything fine since we got here; so we can store files and folders into the system (if ref_id is given)
141  if ($ref_id != null)
142  {
143  ilFileUtils::createObjects ($a_directory, $structure, $ref_id, $containerType, $tree, $access_handler);
144  }
145 
146  }
147 
156  function recursive_dirscan($dir, &$arr)
157  {
158  global $lng;
159 
160  $dirlist = opendir($dir);
161  while (false !== ($file = readdir ($dirlist)))
162  {
163  if (!is_file($dir . "/" . $file) && !is_dir($dir . "/" . $file))
164  {
165  throw new ilFileUtilsException($lng->txt("filenames_not_supported"), ilFileUtilsException::$BROKEN_FILE);
166  }
167 
168  if ($file != '.' && $file != '..')
169  {
170  $newpath = $dir.'/'.$file;
171  $level = explode('/',$newpath);
172  if (is_dir($newpath))
173  {
174  ilFileUtils::recursive_dirscan($newpath, $arr);
175  }
176  else
177  {
178  $arr["path"][] = $dir . "/";
179  $arr["file"][] = end($level);
180  }
181  }
182  }
183  closedir($dirlist);
184  }
185 
186 
200  function createObjects($dir, $structure, $ref_id, $containerType, $tree = null, $access_handler = null)
201  {
202  $dirlist = opendir($dir);
203 
204  while (false !== ($file = readdir ($dirlist)))
205  {
206  if (!is_file($dir . "/" . $file) && !is_dir($dir . "/" . $file))
207  {
208  throw new ilFileUtilsException($lng->txt("filenames_not_supported") , ilFileUtilsException::$BROKEN_FILE);
209  }
210  if ($file != '.' && $file != '..')
211  {
212  $newpath = $dir.'/'.$file;
213  $level = explode('/',$newpath);
214  if (is_dir($newpath))
215  {
216  if ($structure)
217  {
218  $new_ref_id = ilFileUtils::createContainer(ilFileUtils::utf8_encode($file), $ref_id, $containerType, $tree, $access_handler);
219  ilFileUtils::createObjects($newpath, $structure, $new_ref_id, $containerType, $tree, $access_handler);
220  }
221  else
222  {
223  ilFileUtils::createObjects($newpath, $structure, $ref_id, $containerType, $tree, $access_handler);
224  }
225  }
226  else
227  {
228  ilFileUtils::createFile (end($level), $dir, $ref_id, $tree, $access_handler);
229  }
230  }
231  }
232  closedir($dirlist);
233  }
234 
235 
246  function createContainer($name, $ref_id, $containerType, $tree = null, $access_handler = null)
247  {
248  switch($containerType)
249  {
250  case "Category":
251  include_once("./Modules/Category/classes/class.ilObjCategory.php");
252  $newObj = new ilObjCategory();
253  $newObj->setType("cat");
254  break;
255 
256  case "Folder":
257  include_once("./Modules/Folder/classes/class.ilObjFolder.php");
258  $newObj = new ilObjFolder();
259  $newObj->setType("fold");
260  break;
261 
262  case "WorkspaceFolder":
263  include_once("./Modules/WorkspaceFolder/classes/class.ilObjWorkspaceFolder.php");
264  $newObj = new ilObjWorkspaceFolder();
265  break;
266  }
267 
268  $newObj->setTitle($name);
269  $newObj->create();
270 
271  // repository
272  if(!$access_handler)
273  {
274  $newObj->createReference();
275  $newObj->putInTree($ref_id);
276  $newObj->setPermissions($ref_id);
277 
278  if ($newObj->getType() == "cat")
279  {
280  global $lng;
281  $newObj->addTranslation($name,"", $lng->getLangKey(), $lng->getLangKey());
282  }
283 
284  self::$new_files[$ref_id][] = $newObj;
285 
286  return $newObj->getRefId();
287  }
288  // workspace
289  else
290  {
291  $node_id = $tree->insertObject($ref_id, $newObj->getId());
292  $access_handler->setPermissions($ref_id, $node_id);
293 
294  return $node_id;
295  }
296  }
297 
307  function createFile ($filename, $path, $ref_id, $tree = null, $access_handler = null)
308  {
309  global $rbacsystem;
310 
311  if(!$access_handler)
312  {
313  $permission = $rbacsystem->checkAccess("create", $ref_id, "file");
314  }
315  else
316  {
317  $permission = $access_handler->checkAccess("create", "", $ref_id, "file");
318  }
319  if ($permission) {
320 
321  // create and insert file in grp_tree
322  include_once("./Modules/File/classes/class.ilObjFile.php");
323  $fileObj = new ilObjFile();
324  $fileObj->setType($this->type);
327 
328  // better use this, mime_content_type is deprecated
329  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
330  $fileObj->setFileType(ilObjMediaObject::getMimeType($path. "/" . $filename));
331  $fileObj->setFileSize(filesize($path. "/" . $filename));
332  $fileObj->create();
333 
334  // repository
335  if(!$access_handler)
336  {
337  $fileObj->createReference();
338  $fileObj->putInTree($ref_id);
339  $fileObj->setPermissions($ref_id);
340 
341  self::$new_files[$ref_id][] = $fileObj;
342  }
343  else
344  {
345  $node_id = $tree->insertObject($ref_id, $fileObj->getId());
346  $access_handler->setPermissions($ref_id, $node_id);
347  }
348 
349  // upload file to filesystem
350  $fileObj->createDirectory();
351  $fileObj->storeUnzipedFile($path. "/" . $filename,ilFileUtils::utf8_encode(ilUtil::stripSlashes($filename)));
352  }
353  else {
354  $this->ilErr->raiseError($this->lng->txt("permission_denied"),$this->ilErr->MESSAGE);
355  }
356  }
357 
358  public static function getNewObjects()
359  {
360  return self::$new_files;
361  }
362 
371  function utf8_encode($string) {
372 
373  // From http://w3.org/International/questions/qa-forms-utf-8.html
374  return (preg_match('%^(?:
375  [\x09\x0A\x0D\x20-\x7E] # ASCII
376  | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
377  | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
378  | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
379  | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
380  | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
381  | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
382  | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
383  )*$%xs', $string))? $string : utf8_encode($string);
384  }
385 
386 
392  function fastBase64Decode ($filein, $fileout)
393  {
394  $fh = fopen($filein, 'rb');
395  $fh2= fopen($fileout, 'wb');
396  stream_filter_append($fh2, 'convert.base64-decode');
397 
398  while (!feof($fh)){
399  $chunk = fgets($fh);
400  if ($chunk === false)
401  break;
402  fwrite ($fh2, $chunk);
403  }
404  fclose ($fh);
405  fclose ($fh2);
406  return true;
407  }
408 
414  function fastBase64Encode ($filein, $fileout)
415  {
416  $fh = fopen($filein, 'rb');
417  $fh2= fopen($fileout, 'wb');
418  stream_filter_append($fh2, 'convert.base64-encode');
419 
420  while (feof ($fh)) {
421  $chunk = fgets($fh,76);
422  if ($chunk === false)
423  {
424  break;
425  }
426  fwrite ($fh2, $chunk);
427  }
428  fclose ($fh);
429  fclose ($fh2);
430  }
431 
441  function fastGZip ($in, $out, $level="9")
442  {
443  if (!file_exists ($in) || !is_readable ($in))
444  return false;
445  if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
446  return false;
447 
448  $in_file = fopen ($in, "rb");
449  if (!$out_file = gzopen ($out, "wb".$param)) {
450  return false;
451  }
452 
453  while (!feof ($in_file)) {
454  $buffer = fgets ($in_file, 4096);
455  gzwrite ($out_file, $buffer, 4096);
456  }
457 
458  fclose ($in_file);
459  gzclose ($out_file);
460 
461  return true;
462  }
463 
472  function fastGunzip ($in, $out)
473  {
474  if (!file_exists ($in) || !is_readable ($in))
475  return false;
476  if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
477  return false;
478 
479  $in_file = gzopen ($in, "rb");
480  $out_file = fopen ($out, "wb");
481 
482  while (!gzeof ($in_file)) {
483  $buffer = gzread ($in_file, 4096);
484  fwrite ($out_file, $buffer, 4096);
485  }
486 
487  gzclose ($in_file);
488  fclose ($out_file);
489 
490  return true;
491  }
492 
496  public static function _lookupMimeType($a_file)
497  {
498  if(!file_exists($a_file) or !is_readable($a_file))
499  {
500  return false;
501  }
502 
503  if(class_exists('finfo'))
504  {
505  $finfo = new finfo(FILEINFO_MIME);
506  return $finfo->buffer(file_get_contents($a_file));
507  }
508  if(function_exists('mime_content_type'))
509  {
510  return mime_content_type($a_file);
511  }
512  return 'application/octet-stream';
513  }
514 
515 } // END class.ilFileUtils
516 
517 
518 ?>