ILIAS  Release_4_2_x_branch Revision 61807
 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 {
53  function processZipFile ($a_directory, $a_file, $structure, $ref_id = null, $containerType = null, $tree = null, $access_handler = null) {
54 
55  global $lng;
56  include_once("Services/Utilities/classes/class.ilUtil.php");
57 
58  $pathinfo = pathinfo($a_file);
59  $file = $pathinfo["basename"];
60 
61  // Copy zip-file to new directory, unzip and remove it
62  // TODO: check archive for broken file
63  //copy ($a_file, $a_directory . "/" . $file);
64  move_uploaded_file($a_file, $a_directory . "/" . $file);
65  ilUtil::unzip($a_directory . "/" . $file);
66  unlink ($a_directory . "/" . $file);
67 //echo "-".$a_directory . "/" . $file."-";
68  // Stores filename and paths into $filearray to check for viruses
69  // Checks if filenames can be read, else -> throw exception and leave
70  ilFileUtils::recursive_dirscan($a_directory, $filearray);
71 
72  // if there are no files unziped (->broken file!)
73  if (empty($filearray)) {
74  throw new ilFileUtilsException($lng->txt("archive_broken"), ilFileUtilsException::$BROKEN_FILE);
75  break;
76  }
77 
78  // virus handling
79  foreach ($filearray["file"] as $key => $value)
80  {
81  // remove "invisible" files
82  if(substr($value, 0, 1) == "." || stristr($filearray["path"][$key], "/__MACOSX/"))
83  {
84  unlink($filearray["path"][$key].$value);
85  unset($filearray["path"][$key]);
86  unset($filearray["file"][$key]);
87  continue;
88  }
89 
90  $vir = ilUtil::virusHandling($filearray["path"][$key], $value);
91  if (!$vir[0])
92  {
93  // Unlink file and throw exception
94  unlink($filearray[path][$key]);
95  throw new ilFileUtilsException($lng->txt("file_is_infected")."<br />".$vir[1], ilFileUtilsException::$INFECTED_FILE);
96  break;
97  }
98  else
99  {
100  if ($vir[1] != "")
101  {
103  break;
104  }
105  }
106  }
107 
108  // If archive is to be used "flat"
109  if (!$structure)
110  {
111  foreach (array_count_values($filearray["file"]) as $key => $value)
112  {
113  // Archive contains same filenames in different directories
114  if ($value != "1")
115  {
116  $doublettes .= " '" . ilFileUtils::utf8_encode($key) . "'";
117 
118  }
119  }
120  if (isset($doublettes))
121  {
122  throw new ilFileUtilsException($lng->txt("exc_upload_error") . "<br />" . $lng->txt("zip_structure_error") . $doublettes ,
124  break;
125  }
126  }
127  else
128  {
129  $mac_dir = $a_directory."/__MACOSX";
130  if(file_exists($mac_dir))
131  {
132  ilUtil::delDir($mac_dir);
133  }
134  }
135 
136  // Everything fine since we got here; so we can store files and folders into the system (if ref_id is given)
137  if ($ref_id != null)
138  {
139  ilFileUtils::createObjects ($a_directory, $structure, $ref_id, $containerType, $tree, $access_handler);
140  }
141 
142  }
143 
152  function recursive_dirscan($dir, &$arr)
153  {
154  global $lng;
155 
156  $dirlist = opendir($dir);
157  while (false !== ($file = readdir ($dirlist)))
158  {
159  if (!is_file($dir . "/" . $file) && !is_dir($dir . "/" . $file))
160  {
161  throw new ilFileUtilsException($lng->txt("filenames_not_supported"), ilFileUtilsException::$BROKEN_FILE);
162  }
163 
164  if ($file != '.' && $file != '..')
165  {
166  $newpath = $dir.'/'.$file;
167  $level = explode('/',$newpath);
168  if (is_dir($newpath))
169  {
170  ilFileUtils::recursive_dirscan($newpath, $arr);
171  }
172  else
173  {
174  $arr["path"][] = $dir . "/";
175  $arr["file"][] = end($level);
176  }
177  }
178  }
179  closedir($dirlist);
180  }
181 
182 
196  function createObjects($dir, $structure, $ref_id, $containerType, $tree = null, $access_handler = null)
197  {
198  $dirlist = opendir($dir);
199 
200  while (false !== ($file = readdir ($dirlist)))
201  {
202  if (!is_file($dir . "/" . $file) && !is_dir($dir . "/" . $file))
203  {
204  throw new ilFileUtilsException($lng->txt("filenames_not_supported") , ilFileUtilsException::$BROKEN_FILE);
205  }
206  if ($file != '.' && $file != '..')
207  {
208  $newpath = $dir.'/'.$file;
209  $level = explode('/',$newpath);
210  if (is_dir($newpath))
211  {
212  if ($structure)
213  {
214  $new_ref_id = ilFileUtils::createContainer(ilFileUtils::utf8_encode($file), $ref_id, $containerType, $tree, $access_handler);
215  ilFileUtils::createObjects($newpath, $structure, $new_ref_id, $containerType, $tree, $access_handler);
216  }
217  else
218  {
219  ilFileUtils::createObjects($newpath, $structure, $ref_id, $containerType, $tree, $access_handler);
220  }
221  }
222  else
223  {
224  ilFileUtils::createFile (end($level), $dir, $ref_id, $tree, $access_handler);
225  }
226  }
227  }
228  closedir($dirlist);
229  }
230 
231 
242  function createContainer($name, $ref_id, $containerType, $tree = null, $access_handler = null)
243  {
244  switch($containerType)
245  {
246  case "Category":
247  include_once("./Modules/Category/classes/class.ilObjCategory.php");
248  $newObj = new ilObjCategory();
249  $newObj->setType("cat");
250  break;
251 
252  case "Folder":
253  include_once("./Modules/Folder/classes/class.ilObjFolder.php");
254  $newObj = new ilObjFolder();
255  $newObj->setType("fold");
256  break;
257 
258  case "WorkspaceFolder":
259  include_once("./Modules/WorkspaceFolder/classes/class.ilObjWorkspaceFolder.php");
260  $newObj = new ilObjWorkspaceFolder();
261  break;
262  }
263 
264  $newObj->setTitle($name);
265  $newObj->create();
266 
267  // repository
268  if(!$access_handler)
269  {
270  $newObj->createReference();
271  $newObj->putInTree($ref_id);
272  $newObj->setPermissions($ref_id);
273 
274  if ($newObj->getType() == "cat")
275  {
276  global $lng;
277  $newObj->addTranslation($name,"", $lng->getLangKey(), $lng->getLangKey());
278  }
279 
280  return $newObj->getRefId();
281  }
282  // workspace
283  else
284  {
285  $node_id = $tree->insertObject($ref_id, $newObj->getId());
286  $access_handler->setPermissions($ref_id, $node_id);
287 
288  return $node_id;
289  }
290  }
291 
301  function createFile ($filename, $path, $ref_id, $tree = null, $access_handler = null)
302  {
303  global $rbacsystem;
304 
305  if(!$access_handler)
306  {
307  $permission = $rbacsystem->checkAccess("create", $ref_id, "file");
308  }
309  else
310  {
311  $permission = $access_handler->checkAccess("create", "", $ref_id, "file");
312  }
313  if ($permission) {
314 
315  // create and insert file in grp_tree
316  include_once("./Modules/File/classes/class.ilObjFile.php");
317  $fileObj = new ilObjFile();
318  $fileObj->setType($this->type);
321 
322  // better use this, mime_content_type is deprecated
323  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
324  $fileObj->setFileType(ilObjMediaObject::getMimeType($path. "/" . $filename));
325  $fileObj->setFileSize(filesize($path. "/" . $filename));
326  $fileObj->create();
327 
328  // repository
329  if(!$access_handler)
330  {
331  $fileObj->createReference();
332  $fileObj->putInTree($ref_id);
333  $fileObj->setPermissions($ref_id);
334  }
335  else
336  {
337  $node_id = $tree->insertObject($ref_id, $fileObj->getId());
338  $access_handler->setPermissions($ref_id, $node_id);
339  }
340 
341  // upload file to filesystem
342  $fileObj->createDirectory();
343  $fileObj->storeUnzipedFile($path. "/" . $filename,ilFileUtils::utf8_encode(ilUtil::stripSlashes($filename)));
344  }
345  else {
346  $this->ilErr->raiseError($this->lng->txt("permission_denied"),$this->ilErr->MESSAGE);
347  }
348  }
349 
358  function utf8_encode($string) {
359 
360  // From http://w3.org/International/questions/qa-forms-utf-8.html
361  return (preg_match('%^(?:
362  [\x09\x0A\x0D\x20-\x7E] # ASCII
363  | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
364  | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
365  | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
366  | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
367  | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
368  | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
369  | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
370  )*$%xs', $string))? $string : utf8_encode($string);
371  }
372 
373 
379  function fastBase64Decode ($filein, $fileout)
380  {
381  $fh = fopen($filein, 'rb');
382  $fh2= fopen($fileout, 'wb');
383  stream_filter_append($fh2, 'convert.base64-decode');
384 
385  while (!feof($fh)){
386  $chunk = fgets($fh);
387  if ($chunk === false)
388  break;
389  fwrite ($fh2, $chunk);
390  }
391  fclose ($fh);
392  fclose ($fh2);
393  return true;
394  }
395 
401  function fastBase64Encode ($filein, $fileout)
402  {
403  $fh = fopen($filein, 'rb');
404  $fh2= fopen($fileout, 'wb');
405  stream_filter_append($fh2, 'convert.base64-encode');
406 
407  while (feof ($fh)) {
408  $chunk = fgets($fh,76);
409  if ($chunk === false)
410  {
411  break;
412  }
413  fwrite ($fh2, $chunk);
414  }
415  fclose ($fh);
416  fclose ($fh2);
417  }
418 
428  function fastGZip ($in, $out, $level="9")
429  {
430  if (!file_exists ($in) || !is_readable ($in))
431  return false;
432  if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
433  return false;
434 
435  $in_file = fopen ($in, "rb");
436  if (!$out_file = gzopen ($out, "wb".$param)) {
437  return false;
438  }
439 
440  while (!feof ($in_file)) {
441  $buffer = fgets ($in_file, 4096);
442  gzwrite ($out_file, $buffer, 4096);
443  }
444 
445  fclose ($in_file);
446  gzclose ($out_file);
447 
448  return true;
449  }
450 
459  function fastGunzip ($in, $out)
460  {
461  if (!file_exists ($in) || !is_readable ($in))
462  return false;
463  if ((!file_exists ($out) && !is_writable (dirname ($out)) || (file_exists($out) && !is_writable($out)) ))
464  return false;
465 
466  $in_file = gzopen ($in, "rb");
467  $out_file = fopen ($out, "wb");
468 
469  while (!gzeof ($in_file)) {
470  $buffer = gzread ($in_file, 4096);
471  fwrite ($out_file, $buffer, 4096);
472  }
473 
474  gzclose ($in_file);
475  fclose ($out_file);
476 
477  return true;
478  }
479 
483  public static function _lookupMimeType($a_file)
484  {
485  if(!file_exists($a_file) or !is_readable($a_file))
486  {
487  return false;
488  }
489 
490  if(class_exists('finfo'))
491  {
492  $finfo = new finfo(FILEINFO_MIME);
493  return $finfo->buffer(file_get_contents($a_file));
494  }
495  if(function_exists('mime_content_type'))
496  {
497  return mime_content_type($a_file);
498  }
499  return 'application/octet-stream';
500  }
501 
502 } // END class.ilFileUtils
503 
504 
505 ?>