ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjFile.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 
24 require_once "./classes/class.ilObject.php";
25 include_once('Modules/File/classes/class.ilFSStorageFile.php');
26 
38 class ilObjFile extends ilObject
39 {
40  var $filename;
41  var $filetype;
42  var $filemaxsize = "20000000"; // not used yet
44  var $mode = "object";
45 
46  private $file_storage = null;
47 
48 
55  function ilObjFile($a_id = 0,$a_call_by_reference = true)
56  {
57  $this->version = 0;
58  $this->type = "file";
59  $this->raise_upload_error = true;
60  $this->ilObject($a_id,$a_call_by_reference);
61 
62  if($this->getId())
63  {
64  $this->initFileStorage();
65  }
66  }
67 
73  function create($a_upload = false)
74  {
75  $new_id = parent::create();
76 
77  //BEGIN WebDAV Move Property creation into a method of its own.
78  $this->createProperties($a_upload);
79  //END WebDAV Move Property creation into a method of its own.
80 
81  return $new_id;
82  }
83  //BEGIN WebDAV: Move Property creation into a method of its own.
91  function createProperties($a_upload = false)
92  {
93  global $ilDB,$tree;
94 
95  // Create file directory
96  $this->initFileStorage();
97  $this->file_storage->create();
98 
99  if($a_upload)
100  {
101  return true;
102  }
103 
104  // not upload mode
105  require_once("classes/class.ilHistory.php");
106  ilHistory::_createEntry($this->getId(), "create", $this->getFileName().",1");
107  $this->addNewsNotification("file_created");
108 
109 
110  require_once("./Services/News/classes/class.ilNewsItem.php");
111  $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET['ref_id']);
112  if ($default_visibility == "public")
113  {
114  ilBlockSetting::_write("news", "public_notifications",
115  1, 0, $this->getId());
116  }
117 
118  $q = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,mode) "
119  ."VALUES (".$ilDB->quote($this->getId()).","
120  .$ilDB->quote($this->getFileName()).","
121  .$ilDB->quote($this->getFileType()).","
122  .$ilDB->quote($this->getFileSize()).","
123  .$ilDB->quote("1").",".$ilDB->quote($this->getMode()).")";
124  $this->ilias->db->query($q);
125 
126  // no meta data handling for file list files
127  if ($this->getMode() != "filelist")
128  {
129  $this->createMetaData();
130  }
131  }
132  //END WebDAV: Move Property creation into a method of its own.
133 
137  function createMetaData()
138  {
140 
141  // add technical section with file size and format
142  $md_obj =& new ilMD($this->getId(),0,$this->getType());
143  $technical = $md_obj->addTechnical();
144  $technical->setSize($this->getFileSize());
145  $technical->save();
146  $format = $technical->addFormat();
147  $format->setFormat($this->getFileType());
148  $format->save();
149  $technical->update();
150  }
151 
163  function MDUpdateListener($a_element)
164  {
165  // handling for general section
166  parent::MDUpdateListener($a_element);
167 
168  // handling for technical section
169  include_once 'Services/MetaData/classes/class.ilMD.php';
170 //echo "-".$a_element."-";
171  switch($a_element)
172  {
173  case 'Technical':
174 
175  // Update Format (size is not stored in db)
176  $md = new ilMD($this->getId(),0, $this->getType());
177  if(!is_object($md_technical = $md->getTechnical()))
178  {
179  return false;
180  }
181 
182  foreach($md_technical->getFormatIds() as $id)
183  {
184  $md_format = $md_technical->getFormat($id);
185  ilObjFile::_writeFileType($this->getId(),$md_format->getFormat());
186  $this->setFileType($md_format->getFormat());
187  break;
188  }
189 
190  break;
191 
192  default:
193  }
194  return true;
195  }
196 
197 
198  function getDirectory($a_version = 0)
199  {
200  $version_subdir = "";
201 
202  if ($a_version)
203  {
204  // BEGIN WebDAV Avoid double slash before version subdirectory
205  $version_subdir = sprintf("%03d", $a_version);
206  // END WebDAV Avoid double slash before version subdirectory
207  }
208 
209  if(!is_object($this->file_storage))
210  {
211  $this->initFileStorage();
212  }
213 
214  return $this->file_storage->getAbsolutePath().'/'.$version_subdir;
215  }
216 
217  function createDirectory()
218  {
220  }
221 
222  function raiseUploadError($a_raise = true)
223  {
224  $this->raise_upload_error = $a_raise;
225  }
226 
227  function getUploadFile($a_upload_file, $a_filename)
228  {
229  $this->setVersion($this->getVersion() + 1);
230 
231  if (@!is_dir($this->getDirectory($this->getVersion())))
232  {
234  }
235 
236  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
237  //move_uploaded_file($a_upload_file, $file);
238  ilUtil::moveUploadedFile($a_upload_file, $a_filename, $file, $this->raise_upload_error);
239  }
240 
244  function replaceFile($a_upload_file, $a_filename)
245  {
246  //$this->clearDataDirectory(); // ! This has to be changed, if multiple versions should be supported
247  $this->getUploadFile($a_upload_file, $a_filename);
248 
249  require_once("classes/class.ilHistory.php");
250  ilHistory::_createEntry($this->getId(), "replace",
251  $a_filename.",".$this->getVersion());
252  $this->setFilename($a_filename);
253  $this->addNewsNotification("file_updated");
254  }
255 
256 
260  function copy($a_source,$a_destination)
261  {
262  return copy($a_source,$this->getDirectory()."/".$a_destination);
263  }
264 
269  {
270  ilUtil::delDir($this->getDirectory());
271  $this->createDirectory();
272  }
273 
277  function read()
278  {
279  global $ilDB;
280 
281  parent::read();
282 
283  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($this->getId());
284  $r = $this->ilias->db->query($q);
285  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
286 
287  $this->setFileName($row->file_name);
288  $this->setFileType($row->file_type);
289  $this->setFileSize($row->file_size);
290  $this->setVersion($row->version);
291  $this->setMode($row->mode);
292 
293  $this->initFileStorage();
294  }
295 
299  function update()
300  {
301  global $ilDB;
302 
303  // no meta data handling for file list files
304  if ($this->getMode() != "filelist")
305  {
306  $this->updateMetaData();
307  }
308  parent::update();
309 
310  global $ilLog;
311 
312  //$ilLog->write(__METHOD__.' File type: '.$this->getFileType());
313 
314  $q = "UPDATE file_data SET file_name = ".$ilDB->quote($this->getFileName()).
315  ", file_type = ".$ilDB->quote($this->getFiletype())." ".
316  ", file_size = ".$ilDB->quote($this->getFileSize())." ".
317  ", version = ".$ilDB->quote($this->getVersion())." ".
318  ", mode = ".$ilDB->quote($this->getMode())." ".
319  "WHERE file_id = ".$ilDB->quote($this->getId());
320  $this->ilias->db->query($q);
321 
322  return true;
323  }
324 
328  function updateMetaData()
329  {
331 
332  // add technical section with file size and format
333  $md_obj =& new ilMD($this->getId(),0,$this->getType());
334  if(!is_object($technical = $md_obj->getTechnical()))
335  {
336  $technical = $md_obj->addTechnical();
337  $technical->save();
338  }
339  $technical->setSize($this->getFileSize());
340 
341  $format_ids = $technical->getFormatIds();
342  if (count($format_ids) > 0)
343  {
344  $format = $technical->getFormat($format_ids[0]);
345  $format->setFormat($this->getFileType());
346  $format->update();
347  }
348  else
349  {
350  $format = $technical->addFormat();
351  $format->setFormat($this->getFileType());
352  $format->save();
353  }
354  $technical->update();
355  }
356 
360  function setFileName($a_name)
361  {
362  $this->filename = $a_name;
363  }
364 
365  function getFileName()
366  {
367  return $this->filename;
368  }
369 
370  function setFileType($a_type)
371  {
372  global $ilLog;
373 
374 
375  $this->filetype = $a_type;
376  }
377 
378  function getFileType()
379  {
380  return $this->filetype;
381  }
382 
383  function setFileSize($a_size)
384  {
385  $this->filesize = $a_size;
386  }
387 
388  function getFileSize()
389  {
390  return $this->filesize;
391  }
392 
393  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
394  function getFile($a_hist_entry_id = null)
395  {
396  if (is_null($a_hist_entry_id))
397  {
398  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
399  }
400  else
401  {
402  require_once("classes/class.ilHistory.php");
403  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
404 
405  if ($entry === false)
406  {
407  return false;
408  }
409 
410  $data = explode(",",$entry["info_params"]);
411 
412  // bugfix: first created file had no version number
413  // this is a workaround for all files created before the bug was fixed
414  if (empty($data[1]))
415  {
416  $data[1] = "1";
417  }
418 
419  $file = $this->getDirectory($data[1])."/".$data[0];
420  }
421  return $file;
422  }
423  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
424 
425  function setVersion($a_version)
426  {
427  $this->version = $a_version;
428  }
429 
430  function getVersion()
431  {
432  return $this->version;
433  }
434 
440  function setMode($a_mode)
441  {
442  $this->mode = $a_mode;
443  }
444 
450  function getMode()
451  {
452  return $this->mode;
453  }
454 
455  function _writeFileType($a_id ,$a_format)
456  {
457  global $ilDB;
458 
459  $q = "UPDATE file_data SET ".
460  " file_type = ".$ilDB->quote($a_format).
461  " WHERE file_id = ".$ilDB->quote($a_id);
462  $ilDB->query($q);
463 
464  }
465 
466  function _lookupFileName($a_id)
467  {
468  global $ilDB;
469 
470  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($a_id);
471  $r = $ilDB->query($q);
472  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
473 
474  return ilUtil::stripSlashes($row->file_name);
475  }
476 
477 
478  function _lookupFileSize($a_id, $a_as_string = false)
479  {
480  // BEGIN WebDAV: Use lookupFileSize function of class ilObjFileAccess
481  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
482  return ilObjFileAccess::_lookupFileSize($a_id, $a_as_string, true);
483  // END WebDAV: Use lookupFileSize function of class ilObjFileAccess
484  }
485 
489  function _lookupVersion($a_id)
490  {
491  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
492  return ilObjFileAccess::_lookupVersion($a_id);
493  }
494 
498  function determineFileSize($a_hist_entry_id = null)
499  {
500  if (is_null($a_hist_entry_id))
501  {
502  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
503  }
504  else
505  {
506  require_once("classes/class.ilHistory.php");
507  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
508 
509  if ($entry === false)
510  {
511  return false;
512  }
513 
514  $data = explode(",",$entry["info_params"]);
515 
516  // bugfix: first created file had no version number
517  // this is a workaround for all files created before the bug was fixed
518  if (empty($data[1]))
519  {
520  $data[1] = "1";
521  }
522  $file = $this->getDirectory($data[1])."/".$data[0];
523  }
524  $this->setFileSize(filesize($file));
525  }
526 
527  function sendFile($a_hist_entry_id = null)
528  {
529  if (is_null($a_hist_entry_id))
530  {
531  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
532 
533  // if not found lookup for file in file object's main directory for downward c ompability
534  if (@!is_file($file))
535  {
536  $file = $this->getDirectory()."/".$this->getFileName();
537  }
538  }
539  else
540  {
541  require_once("classes/class.ilHistory.php");
542  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
543 
544  if ($entry === false)
545  {
546  echo "3";return false;
547  }
548 
549  $data = explode(",",$entry["info_params"]);
550 
551  // bugfix: first created file had no version number
552  // this is a workaround for all files created before the bug was fixed
553  if (empty($data[1]))
554  {
555  $data[1] = "1";
556  }
557 
558  $file = $this->getDirectory($data[1])."/".$data[0];
559 
560  // if not found lookup for file in file object's main directory for downward compability
561  if (@!is_file($file))
562  {
563  $file = $this->getDirectory()."/".$data[0];
564  }
565 
566  // BEGIN WebDAV removed duplicated code
567  // END WebDAV removed duplicated code
568  }
569 
570  if (@is_file($file))
571  {
572  // BEGIN WebDAV: Deliver file with title, file type, and eventually as inline object.
573  ilUtil::deliverFile($file, $this->getTitle(), $this->guessFileType($file), $this->isInline());
574  // END WebDAV: Deliver file with title, file type, and eventually as inline object.
575  return true;
576  }
577 
578  return false;
579  }
580 
581  // BEGIN WebDAV: Get file extension, determine if file is inline, guess file type.
586  function getFileExtension() {
587  require_once 'class.ilObjFileAccess.php';
589  }
595  function isInline() {
596  require_once 'class.ilObjFileAccess.php';
597  return ilObjFileAccess::_isFileInline($this->getTitle());
598  }
602  function isHidden() {
603  require_once 'class.ilObjFileAccess.php';
604  return ilObjFileAccess::_isFileHidden($this->getTitle());
605  }
606  // END WebDAV: Get file extension, determine if file is inline, guess file type.
607 
614  function guessFileType($a_file = "") {
615 
616  $path = pathinfo($a_file);
617  if ($path["extension"] != "")
618  {
619  $filename = $path["basename"];
620  }
621  else
622  {
623  $filename = "dummy.".$this->getFileExtension();
624  }
625  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
626  $mime = ilMimeTypeUtil::getMimeType($a_file, $filename, $this->getFileType());
627  return $mime;
628 
629 /*
630  $fileType = $this->getFileType();
631  if (strlen($fileType) == 0) {
632  $fileType = 'application/octet-stream';
633  }
634 
635  // Firefox browser assigns 'application/x-pdf' to PDF files, but
636  // it can only handle them if the have the mime-type 'application/pdf'.
637  if ($fileType == 'application/x-pdf')
638  {
639  $fileType = 'application/pdf';
640  }
641 
642  if ($fileType == 'application/octet-stream')
643  {
644  $fileExtension = $this->getFileExtension();
645  $mimeArray = array(
646  'mpeg' => 'video/mpeg',
647  'mp3' => 'audio/mpeg',
648  'pdf' => 'application/pdf',
649  'gif' => 'image/gif',
650  'jpg' => 'image/jpg',
651  'png' => 'image/png',
652  'htm' => 'text/html',
653  'html' => 'text/html',
654  'wma' => 'video/x-ms-wma',
655  'wmv' => 'video/x-ms-wmv',
656  'swf' => 'application/x-shockwave-flash',
657  );
658  if (array_key_exists($fileExtension, $mimeArray))
659  {
660  $fileType = $mimeArray[$fileExtension];
661  }
662  }
663  return $fileType;
664 */
665  }
666 
675  public function cloneObject($a_target_id,$a_copy_id = 0)
676  {
677  global $ilDB;
678 
679  $new_obj = parent::cloneObject($a_target_id,$a_copy_id);
680  $new_obj->createDirectory();
681  $this->cloneMetaData($new_obj);
682 
683  // Copy all file versions
684  ilUtil::rCopy($this->getDirectory(),$new_obj->getDirectory());
685 
686  // object created now copy other settings
687  $query = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,mode) VALUES (".
688  $ilDB->quote($new_obj->getId()).",".
689  $ilDB->quote($this->getFileName()).",".
690  $ilDB->quote($this->getFileType()).",".
691  $ilDB->quote($this->getFileSize()).", ".
692  $ilDB->quote($this->getVersion()).", ".
693  $ilDB->quote($this->getMode()).")";
694  $ilDB->query($query);
695 
696  // copy history entries
697  require_once("classes/class.ilHistory.php");
698  ilHistory::_copyEntriesForObject($this->getId(),$new_obj->getId());
699 
700  // add news notification
701  $new_obj->addNewsNotification("file_created");
702 
703  return $new_obj;
704  }
705 
706 
713  function delete()
714  {
715  global $ilDB;
716 
717  // check, if file is used somewhere
718  $usages = $this->getUsages();
719 
720  if (count($usages) == 0)
721  {
722  // always call parent delete function first!!
723  if (!parent::delete())
724  {
725  return false;
726  }
727 
728  // delete file data entry
729  $q = "DELETE FROM file_data WHERE file_id = ".$ilDB->quote($this->getId());
730  $this->ilias->db->query($q);
731 
732  // delete history entries
733  require_once("classes/class.ilHistory.php");
735 
736  // delete entire directory and its content
737  if (@is_dir($this->getDirectory()))
738  {
739  ilUtil::delDir($this->getDirectory());
740  }
741 
742  // delete meta data
743  if ($this->getMode() != "filelist")
744  {
745  $this->deleteMetaData();
746  }
747 
748  return true;
749  }
750 
751  return false;
752  }
753 
761  function export($a_target_dir)
762  {
763  $subdir = "il_".IL_INST_ID."_file_".$this->getId();
764  ilUtil::makeDir($a_target_dir."/objects/".$subdir);
765 
766  $filedir = $this->getDirectory($this->getVersion());
767 
768  if (@!is_dir($filedir))
769  {
770  $filedir = $this->getDirectory();
771  }
772 
773  ilUtil::rCopy($filedir, $a_target_dir."/objects/".$subdir);
774  }
775 
779  function _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr = 0)
780  {
781  global $ilDB;
782 
783  $q = "DELETE FROM file_usage WHERE usage_type=".$ilDB->quote($a_type)." AND usage_id=".$ilDB->quote($a_id).
784  " AND usage_hist_nr = ".$ilDB->quote($a_usage_hist_nr);
785  $this->ilias->db->query($q);
786  }
787 
791  function _saveUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr = 0)
792  {
793  global $ilDB;
794 
795  $q = "REPLACE INTO file_usage (id, usage_type, usage_id, usage_hist_nr) VALUES".
796  " (".$ilDB->quote($a_mob_id).",".$ilDB->quote($a_type).",".$ilDB->quote($a_id).",".
797  $ilDB->quote($a_usage_hist_nr).")";
798  $this->ilias->db->query($q);
799  }
800 
804  function getUsages()
805  {
806  global $ilDB;
807 
808  // get usages in learning modules
809  $q = "SELECT * FROM file_usage WHERE id = ".$ilDB->quote($this->getId());
810  $us_set = $ilDB->query($q);
811  $ret = array();
812  while($us_rec = $us_set->fetchRow(DB_FETCHMODE_ASSOC))
813  {
814  $ret[] = array("type" => $us_rec["usage_type"],
815  "id" => $us_rec["usage_id"],
816  "hist_nr" => $us_rec["usage_hist_nr"]);
817  }
818 
819  return $ret;
820  }
821 
830  function _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr = 0)
831  {
832  global $ilDB;
833 
834  // get usages in learning modules
835  $q = "SELECT * FROM file_usage WHERE usage_id = ".$ilDB->quote($a_id).
836  " AND usage_type = ".$ilDB->quote($a_type)." AND ".
837  "usage_hist_nr = ".$ilDB->quote($a_usage_hist_nr);
838  $file_set = $ilDB->query($q);
839  $ret = array();
840  while($file_rec = $file_set->fetchRow(DB_FETCHMODE_ASSOC))
841  {
842  $ret[$file_rec["id"]] = $file_rec["id"];
843  }
844 
845  return $ret;
846  }
847 
848  // TODO: What is this function good for??
849  function getXMLZip()
850  {
851  global $ilias;
852 
853  $zip = PATH_TO_ZIP;
854 
855  exec($zip.' '.ilUtil::escapeShellArg($this->getDirectory().'/'.$this->getFileName())." ".
856  ilUtil::escapeShellArg($this->getDirectory().'/'.'1.zip'));
857 
858  return $this->getDirectory().'/1.zip';
859  }
860 
861  function addNewsNotification($a_lang_var)
862  {
863  // BEGIN WebDAV Suppress news notification for hidden files
864  if ($this->isHidden()) {
865  return;
866  }
867  // END WebDAV Suppress news notification for hidden files
868 
869  global $ilUser;
870 
871  // Add Notification to news
872  include_once("./Services/News/classes/class.ilNewsItem.php");
873  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
874  $news_item = new ilNewsItem();
875  $news_item->setContext($this->getId(), $this->getType());
876  $news_item->setPriority(NEWS_NOTICE);
877  $news_item->setTitle($a_lang_var);
878  $news_item->setContentIsLangVar(true);
879  if ($this->getDescription() != "")
880  {
881  $news_item->setContent(
882  "<p>".
883  $this->getDescription()."</p>");
884  }
885  $news_item->setUserId($ilUser->getId());
886  $news_item->setVisibility(NEWS_USERS);
887  $news_item->create();
888  }
889 
896  public function initFileStorage()
897  {
898  $this->file_storage = new ilFSStorageFile($this->getId());
899  return true;
900  }
910  function storeUnzipedFile($a_upload_file, $a_filename)
911  {
912  $this->setVersion($this->getVersion() + 1);
913 
914  if (@!is_dir($this->getDirectory($this->getVersion())))
915  {
916  ilUtil::makeDir($this->getDirectory($this->getVersion()));
917  }
918 
919  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
920  //move_uploaded_file($a_upload_file, $file);
921  rename($a_upload_file, $file);
922  }
923 
928  public static function _lookupAbsolutePath ($obj_id, $a_version = null)
929  {
930  $file_storage = new ilFSStorageFile($obj_id);
932  $version_subdir = "";
933 
934  if (!is_numeric($a_version))
935  {
936  $a_version = ilObjFile::_lookupVersion ($obj_id);
937  }
938  $version_subdir = DIRECTORY_SEPARATOR.sprintf("%03d", $a_version);
939  return $file_storage->getAbsolutePath().$version_subdir.DIRECTORY_SEPARATOR.$filename;
940  }
941 
942 
943 } // END class.ilObjFile
944 ?>