ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjFile.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once "Services/Object/classes/class.ilObject2.php";
5 include_once('Modules/File/classes/class.ilFSStorageFile.php');
6 
18 class ilObjFile extends ilObject2
19 {
20  var $filename;
21  var $filetype;
22  var $filemaxsize = "20000000"; // not used yet
24  var $mode = "object";
25  protected $rating;
26 
27  private $file_storage = null;
28 
29 
36  function __construct($a_id = 0,$a_call_by_reference = true)
37  {
38  $this->version = 0;
39  $this->raise_upload_error = true;
40  parent::__construct($a_id,$a_call_by_reference);
41 
42  if($this->getId())
43  {
44  $this->initFileStorage();
45  }
46  }
47 
48  function initType()
49  {
50  $this->type = "file";
51  }
52 
58  protected function doCreate($a_upload = false, $a_prevent_meta_data_creation = false)
59  {
60  //BEGIN WebDAV Move Property creation into a method of its own.
61  $this->createProperties($a_upload);
62  //END WebDAV Move Property creation into a method of its own.
63  }
64 
65  //BEGIN WebDAV: Move Property creation into a method of its own.
73  function createProperties($a_upload = false, $a_prevent_meta_data_creation = false)
74  {
75  global $ilDB,$tree;
76 
77  // Create file directory
78  $this->initFileStorage();
79  $this->file_storage->create();
80 
81  if($a_upload)
82  {
83  return true;
84  }
85 
86  // not upload mode
87  require_once("./Services/History/classes/class.ilHistory.php");
88  ilHistory::_createEntry($this->getId(), "create", $this->getFileName().",1");
89  $this->addNewsNotification("file_created");
90 
91 
92  require_once("./Services/News/classes/class.ilNewsItem.php");
93  $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET['ref_id']);
94  if ($default_visibility == "public")
95  {
96  ilBlockSetting::_write("news", "public_notifications",
97  1, 0, $this->getId());
98  }
99 
100  $q = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,f_mode) "
101  ."VALUES (".$ilDB->quote($this->getId() ,'integer').","
102  .$ilDB->quote($this->getFileName() ,'text').","
103  .$ilDB->quote($this->getFileType() ,'text').","
104  .$ilDB->quote((int) $this->getFileSize() ,'integer').","
105  .$ilDB->quote(1 ,'integer').",".$ilDB->quote($this->getMode() ,'text').")";
106  $res = $ilDB->manipulate($q);
107 
108  // no meta data handling for file list files
109  if ($this->getMode() != "filelist" && !$a_prevent_meta_data_creation)
110  {
111  $this->createMetaData();
112  }
113  }
114  //END WebDAV: Move Property creation into a method of its own.
115 
119  protected function doCreateMetaData()
120  {
121  // add technical section with file size and format
122  $md_obj =& new ilMD($this->getId(),0,$this->getType());
123  $technical = $md_obj->addTechnical();
124  $technical->setSize($this->getFileSize());
125  $technical->save();
126  $format = $technical->addFormat();
127  $format->setFormat($this->getFileType());
128  $format->save();
129  $technical->update();
130  }
131 
132  protected function beforeMDUpdateListener($a_element)
133  {
134  // Check file extension
135  // Removing the file extension is not allowed
136  include_once 'Services/MetaData/classes/class.ilMD.php';
137  $md = new ilMD($this->getId(),0, $this->getType());
138  if(!is_object($md_gen = $md->getGeneral()))
139  {
140  return false;
141  }
142  $title = $this->checkFileExtension($this->getFileName(), $md_gen->getTitle());
143  $md_gen->setTitle($title);
144  $md_gen->update();
145  return true;
146  }
147 
148  protected function doMDUpdateListener($a_element)
149  {
150  // handling for technical section
151  include_once 'Services/MetaData/classes/class.ilMD.php';
152 //echo "-".$a_element."-";
153  switch($a_element)
154  {
155  case 'Technical':
156 
157  // Update Format (size is not stored in db)
158  $md = new ilMD($this->getId(),0, $this->getType());
159  if(!is_object($md_technical = $md->getTechnical()))
160  {
161  return false;
162  }
163 
164  foreach($md_technical->getFormatIds() as $id)
165  {
166  $md_format = $md_technical->getFormat($id);
167  ilObjFile::_writeFileType($this->getId(),$md_format->getFormat());
168  $this->setFileType($md_format->getFormat());
169  break;
170  }
171 
172  break;
173  }
174  return true;
175  }
176 
177 
178  function getDirectory($a_version = 0)
179  {
180  $version_subdir = "";
181 
182  if ($a_version)
183  {
184  // BEGIN WebDAV Avoid double slash before version subdirectory
185  $version_subdir = sprintf("%03d", $a_version);
186  // END WebDAV Avoid double slash before version subdirectory
187  }
188 
189  if(!is_object($this->file_storage))
190  {
191  $this->initFileStorage();
192  }
193 
194  return $this->file_storage->getAbsolutePath().'/'.$version_subdir;
195  }
196 
197  function createDirectory()
198  {
200  }
201 
202  function raiseUploadError($a_raise = true)
203  {
204  $this->raise_upload_error = $a_raise;
205  }
206 
207  function getUploadFile($a_upload_file, $a_filename, $a_prevent_preview = false)
208  {
209  $this->setVersion($this->getVersion() + 1);
210 
211  if (@!is_dir($this->getDirectory($this->getVersion())))
212  {
214  }
215 
216  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
217  //move_uploaded_file($a_upload_file, $file);
218  ilUtil::moveUploadedFile($a_upload_file, $a_filename, $file, $this->raise_upload_error);
219 
220  $this->handleQuotaUpdate($this);
221 
222  // create preview?
223  if (!$a_prevent_preview)
224  {
225  $this->createPreview(false);
226  }
227  }
228 
232  function replaceFile($a_upload_file, $a_filename)
233  {
234  $this->getUploadFile($a_upload_file, $a_filename, true);
235 
236  require_once("./Services/History/classes/class.ilHistory.php");
238  $this->getId(),
239  "replace",
240  $a_filename.",".$this->getVersion()
241  );
242  $this->setFilename($a_filename);
243  $this->addNewsNotification("file_updated");
244 
245  // create preview
246  $this->createPreview(true);
247  }
248 
249 
250  public function addFileVersion($a_upload_file,$a_filename)
251  {
252  $this->getUploadFile($a_upload_file, $a_filename, true);
253 
254  require_once("./Services/History/classes/class.ilHistory.php");
256  $this->getId(),
257  "new_version",
258  $a_filename.",".$this->getVersion()
259  );
260  $this->setFilename($a_filename);
261  $this->addNewsNotification("file_updated");
262 
263  // create preview
264  $this->createPreview($this->getVersion() > 1);
265  }
266 
267 
271  function copy($a_source,$a_destination)
272  {
273  return copy($a_source,$this->getDirectory()."/".$a_destination);
274  }
275 
280  {
281  ilUtil::delDir($this->getDirectory());
282  $this->createDirectory();
283  }
284 
290  public function deleteVersions($a_hist_entry_ids = null)
291  {
292  global $ilDB;
293 
294  require_once("./Services/History/classes/class.ilHistory.php");
295 
296  if ($a_hist_entry_ids == null || count($a_hist_entry_ids) < 1)
297  {
298  $ilDB->manipulate("UPDATE file_data SET version = 1 WHERE file_id = ".$ilDB->quote($this->getId() ,'integer'));
299  $this->setVersion(0);
300  $this->clearDataDirectory();
301 
303 
305  }
306  else
307  {
308  $actualVersionDeleted = false;
309 
310  // get all versions
311  $versions = $this->getVersions();
312 
313  // delete each version
314  foreach ($a_hist_entry_ids as $hist_id)
315  {
316  $entry = null;
317 
318  // get version
319  foreach ($versions as $index => $version)
320  {
321  if ($version["hist_entry_id"] == $hist_id)
322  {
323  // remove each history entry
325 
326  // delete directory
327  $version_dir = $this->getDirectory($version["version"]);
328  ilUtil::delDir($version_dir);
329 
330  // is actual version?
331  if ($version["version"] == $this->getVersion())
332  $actualVersionDeleted = true;
333 
334  // remove from array
335  unset($versions[$index]);
336  break;
337  }
338  }
339  }
340 
341  // update actual version if it was deleted before
342  if ($actualVersionDeleted)
343  {
344  // get newest version (already sorted by getVersions)
345  $version = reset($versions);
346  $this->updateWithVersion($version);
347  }
348  else
349  {
350  // updateWithVersion() will trigger quota, too
352  }
353  }
354  }
355 
359  protected function doRead()
360  {
361  global $ilDB;
362 
363  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
364  $r = $this->ilias->db->query($q);
365  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
366 
367  $this->setFileName($row->file_name);
368  $this->setFileType($row->file_type);
369  $this->setFileSize($row->file_size);
370  $this->setVersion($row->version);
371  $this->setMode($row->f_mode);
372  $this->setRating($row->rating);
373 
374  $this->initFileStorage();
375  }
376 
377  protected function beforeUpdate()
378  {
379  // no meta data handling for file list files
380  if ($this->getMode() != "filelist")
381  {
382  $this->updateMetaData();
383  }
384 
385  return true;
386  }
387 
391  protected function doUpdate()
392  {
393  global $ilDB, $ilLog;
394 
395  //$ilLog->write(__METHOD__.' File type: '.$this->getFileType());
396 
397  $q = "UPDATE file_data SET file_name = ".$ilDB->quote($this->getFileName() ,'text').
398  ", file_type = ".$ilDB->quote($this->getFiletype() ,'text')." ".
399  ", file_size = ".$ilDB->quote((int) $this->getFileSize() ,'integer')." ".
400  ", version = ".$ilDB->quote($this->getVersion() ,'integer')." ".
401  ", f_mode = ".$ilDB->quote($this->getMode() ,'text')." ".
402  ", rating = ".$ilDB->quote($this->hasRating() ,'integer')." ".
403  "WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
404  $res = $ilDB->manipulate($q);
405 
407 
408  return true;
409  }
410 
414  protected function doUpdateMetaData()
415  {
416  // add technical section with file size and format
417  $md_obj =& new ilMD($this->getId(),0,$this->getType());
418  if(!is_object($technical = $md_obj->getTechnical()))
419  {
420  $technical = $md_obj->addTechnical();
421  $technical->save();
422  }
423  $technical->setSize($this->getFileSize());
424 
425  $format_ids = $technical->getFormatIds();
426  if (count($format_ids) > 0)
427  {
428  $format = $technical->getFormat($format_ids[0]);
429  $format->setFormat($this->getFileType());
430  $format->update();
431  }
432  else
433  {
434  $format = $technical->addFormat();
435  $format->setFormat($this->getFileType());
436  $format->save();
437  }
438  $technical->update();
439  }
440 
444  function setFileName($a_name)
445  {
446  $this->filename = $a_name;
447  }
448 
449  function getFileName()
450  {
451  return $this->filename;
452  }
453 
454  function setFileType($a_type)
455  {
456  global $ilLog;
457 
458 
459  $this->filetype = $a_type;
460  }
461 
462  function getFileType()
463  {
464  return $this->filetype;
465  }
466 
467  function setFileSize($a_size)
468  {
469  $this->filesize = $a_size;
470  }
471 
472  function getFileSize()
473  {
474  return $this->filesize;
475  }
482  function getDiskUsage()
483  {
484  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
485  return ilObjFileAccess::_lookupDiskUsage($this->id);
486  }
487 
488 
489  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
490  function getFile($a_hist_entry_id = null)
491  {
492  if (is_null($a_hist_entry_id))
493  {
494  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
495  }
496  else
497  {
498  require_once("./Services/History/classes/class.ilHistory.php");
499  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
500 
501  if ($entry === false)
502  {
503  return false;
504  }
505 
506  $data = $this->parseInfoParams($entry);
507  $file = $this->getDirectory($data["version"])."/".$data["filename"];
508  }
509  return $file;
510  }
511  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
512 
513  function setVersion($a_version)
514  {
515  $this->version = $a_version;
516  }
517 
518  function getVersion()
519  {
520  return $this->version;
521  }
522 
528  function setMode($a_mode)
529  {
530  $this->mode = $a_mode;
531  }
532 
538  function getMode()
539  {
540  return $this->mode;
541  }
542 
543  function _writeFileType($a_id ,$a_format)
544  {
545  global $ilDB;
546 
547  $q = "UPDATE file_data SET ".
548  " file_type = ".$ilDB->quote($a_format ,'text').
549  " WHERE file_id = ".$ilDB->quote($a_id ,'integer');
550  $res = $ilDB->manipulate($q);
551 
552  }
553 
554  function _lookupFileName($a_id)
555  {
556  global $ilDB;
557 
558  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($a_id ,'integer');
559  $r = $ilDB->query($q);
560  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
561 
562  return ilUtil::stripSlashes($row->file_name);
563  }
564 
565 
567  function _lookupFileSize($a_id)
568  {
569  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
570  return ilObjFileAccess::_lookupFileSize($a_id);
571  }
572 
576  function _lookupVersion($a_id)
577  {
578  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
579  return ilObjFileAccess::_lookupVersion($a_id);
580  }
581 
585  function determineFileSize($a_hist_entry_id = null)
586  {
587  if (is_null($a_hist_entry_id))
588  {
589  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
590  }
591  else
592  {
593  require_once("./Services/History/classes/class.ilHistory.php");
594  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
595 
596  if ($entry === false)
597  {
598  return false;
599  }
600 
601  $data = $this->parseInfoParams($entry);
602  $file = $this->getDirectory($data["version"])."/".$data["filename"];
603  }
604  if (is_file($file))
605  {
606  $this->setFileSize(filesize($file));
607  }
608  }
609 
610  function sendFile($a_hist_entry_id = null)
611  {
612  if (is_null($a_hist_entry_id))
613  {
614  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
615 
616  // if not found lookup for file in file object's main directory for downward c ompability
617  if (@!is_file($file))
618  {
619  $file = $this->getDirectory()."/".$this->getFileName();
620  }
621  }
622  else
623  {
624  require_once("./Services/History/classes/class.ilHistory.php");
625  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
626 
627  if ($entry === false)
628  {
629  echo "3";return false;
630  }
631 
632  $data = $this->parseInfoParams($entry);
633  $file = $this->getDirectory($data["version"])."/".$data["filename"];
634 
635  // if not found lookup for file in file object's main directory for downward compability
636  if (@!is_file($file))
637  {
638  $file = $this->getDirectory()."/".$data[0];
639  }
640 
641  // BEGIN WebDAV removed duplicated code
642  // END WebDAV removed duplicated code
643  }
644 
645  if (@is_file($file))
646  {
647  global $ilClientIniFile;
648 
649  // also returning the 'real' filename if a history file is delivered
650  if ($ilClientIniFile->readVariable('file_access','download_with_uploaded_filename') != '1' && is_null($a_hist_entry_id))
651  {
652  ilUtil::deliverFile($file, $this->getTitle(), $this->guessFileType($file), $this->isInline());
653  }
654  else
655  {
656  ilUtil::deliverFile($file, basename($file), $this->guessFileType($file), $this->isInline());
657  }
658  return true;
659  }
660 
661  return false;
662  }
663 
664  // BEGIN WebDAV: Get file extension, determine if file is inline, guess file type.
669  function getFileExtension() {
670  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
672  }
678  function isInline() {
679  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
680  return ilObjFileAccess::_isFileInline($this->getTitle());
681  }
685  function isHidden() {
686  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
687  return ilObjFileAccess::_isFileHidden($this->getTitle());
688  }
689  // END WebDAV: Get file extension, determine if file is inline, guess file type.
690 
697  function guessFileType($a_file = "") {
698 
699  $path = pathinfo($a_file);
700  if ($path["extension"] != "")
701  {
702  $filename = $path["basename"];
703  }
704  else
705  {
706  $filename = "dummy.".$this->getFileExtension();
707  }
708  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
709  $mime = ilMimeTypeUtil::getMimeType($a_file, $filename, $this->getFileType());
710  return $mime;
711 
712 /*
713  $fileType = $this->getFileType();
714  if (strlen($fileType) == 0) {
715  $fileType = 'application/octet-stream';
716  }
717 
718  // Firefox browser assigns 'application/x-pdf' to PDF files, but
719  // it can only handle them if the have the mime-type 'application/pdf'.
720  if ($fileType == 'application/x-pdf')
721  {
722  $fileType = 'application/pdf';
723  }
724 
725  if ($fileType == 'application/octet-stream')
726  {
727  $fileExtension = $this->getFileExtension();
728  $mimeArray = array(
729  'mpeg' => 'video/mpeg',
730  'mp3' => 'audio/mpeg',
731  'pdf' => 'application/pdf',
732  'gif' => 'image/gif',
733  'jpg' => 'image/jpg',
734  'png' => 'image/png',
735  'htm' => 'text/html',
736  'html' => 'text/html',
737  'wma' => 'video/x-ms-wma',
738  'wmv' => 'video/x-ms-wmv',
739  'swf' => 'application/x-shockwave-flash',
740  );
741  if (array_key_exists($fileExtension, $mimeArray))
742  {
743  $fileType = $mimeArray[$fileExtension];
744  }
745  }
746  return $fileType;
747 */
748  }
749 
759  protected function doCloneObject($a_new_obj,$a_target_id,$a_copy_id = 0)
760  {
761  global $ilDB;
762 
763  $a_new_obj->createDirectory();
764  $this->cloneMetaData($a_new_obj);
765 
766  // Copy all file versions
767  ilUtil::rCopy($this->getDirectory(),$a_new_obj->getDirectory());
768 
769  // object created now copy other settings
770  $query = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,rating,f_mode) VALUES (".
771  $ilDB->quote($a_new_obj->getId() ,'integer').",".
772  $ilDB->quote($this->getFileName() ,'text').",".
773  $ilDB->quote($this->getFileType() ,'text').",".
774  $ilDB->quote((int) $this->getFileSize() ,'integer').", ".
775  $ilDB->quote($this->getVersion() ,'integer').", ".
776  $ilDB->quote($this->hasRating() ,'integer').", ".
777  $ilDB->quote($this->getMode() ,'text').")";
778  $res = $ilDB->manipulate($query);
779 
780  // copy all previews
781  require_once("./Services/Preview/classes/class.ilPreview.php");
782  ilPreview::copyPreviews($this->getId(), $a_new_obj->getId());
783 
784  // copy history entries
785  require_once("./Services/History/classes/class.ilHistory.php");
786  ilHistory::_copyEntriesForObject($this->getId(),$a_new_obj->getId());
787 
788  // add news notification
789  $a_new_obj->addNewsNotification("file_created");
790 
791  return $a_new_obj;
792  }
793 
794  protected function beforeDelete()
795  {
796  global $ilDB;
797 
798  // check, if file is used somewhere
799  $usages = $this->getUsages();
800  if (count($usages) == 0)
801  {
802  return true;
803  }
804  return false;
805  }
806 
807  protected function doDelete()
808  {
809  global $ilDB;
810 
811  // delete file data entry
812  $q = "DELETE FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
813  $this->ilias->db->query($q);
814 
815  // delete history entries
816  require_once("./Services/History/classes/class.ilHistory.php");
818 
819  // delete entire directory and its content
820  if (@is_dir($this->getDirectory()))
821  {
822  ilUtil::delDir($this->getDirectory());
823  }
824 
825  // delete meta data
826  if ($this->getMode() != "filelist")
827  {
828  $this->deleteMetaData();
829  }
830 
832 
833  // delete preview
834  $this->deletePreview();
835  }
836 
844  function export($a_target_dir)
845  {
846  $subdir = "il_".IL_INST_ID."_file_".$this->getId();
847  ilUtil::makeDir($a_target_dir."/objects/".$subdir);
848 
849  $filedir = $this->getDirectory($this->getVersion());
850 
851  if (@!is_dir($filedir))
852  {
853  $filedir = $this->getDirectory();
854  }
855 
856  ilUtil::rCopy($filedir, $a_target_dir."/objects/".$subdir);
857  }
858 
862  function _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
863  {
864  global $ilDB;
865 
866  $and_hist = ($a_usage_hist_nr !== false)
867  ? " AND usage_hist_nr = ".$ilDB->quote($a_usage_hist_nr, "integer")
868  : "";
869 
870  $file_ids = array();
871  $set = $ilDB->query("SELECT id FROM file_usage".
872  " WHERE usage_type = ".$ilDB->quote($a_type, "text").
873  " AND usage_id= ".$ilDB->quote($a_id, "integer").
874  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
875  $and_hist);
876  while($row = $ilDB->fetchAssoc($set))
877  {
878  $file_ids[] = $row["id"];
879  }
880 
881  $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = ".
882  $ilDB->quote($a_type, "text").
883  " AND usage_id = ".$ilDB->quote((int) $a_id, "integer").
884  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
885  " AND usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer"));
886 
887  foreach($file_ids as $file_id)
888  {
889  self::handleQuotaUpdate(new self($file_id, false));
890  }
891  }
892 
896  function _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
897  {
898  global $ilDB;
899 
900  $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = ".
901  $ilDB->quote((string) $a_type, "text").
902  " AND usage_id = ".$ilDB->quote((int) $a_id, "integer").
903  " AND usage_lang = ".$ilDB->quote($a_lang, "text").
904  " AND usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer").
905  " AND id = ".$ilDB->quote((int) $a_file_id, "integer"));
906 
907  $ilDB->manipulate("INSERT INTO file_usage (id, usage_type, usage_id, usage_hist_nr, usage_lang) VALUES".
908  " (".$ilDB->quote((int) $a_file_id, "integer").",".
909  $ilDB->quote((string) $a_type, "text").",".
910  $ilDB->quote((int) $a_id, "integer").",".
911  $ilDB->quote((int) $a_usage_hist_nr, "integer").",".
912  $ilDB->quote($a_usage_lang, "text").
913  ")");
914 
915  self::handleQuotaUpdate(new self($a_file_id, false));
916  }
917 
921  function getUsages()
922  {
923  global $ilDB;
924 
925  // get usages in learning modules
926  $q = "SELECT * FROM file_usage WHERE id = ".$ilDB->quote($this->getId(), "integer");
927  $us_set = $ilDB->query($q);
928  $ret = array();
929  while($us_rec = $ilDB->fetchAssoc($us_set))
930  {
931  $ret[] = array("type" => $us_rec["usage_type"],
932  "id" => $us_rec["usage_id"],
933  "lang" => $us_rec["usage_lang"],
934  "hist_nr" => $us_rec["usage_hist_nr"]);
935  }
936 
937  return $ret;
938  }
939 
948  function _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
949  {
950  global $ilDB;
951 
952  // get usages in learning modules
953  $q = "SELECT * FROM file_usage WHERE ".
954  "usage_id = ".$ilDB->quote((int) $a_id, "integer")." AND ".
955  "usage_type = ".$ilDB->quote((string) $a_type, "text")." AND ".
956  "usage_lang = ".$ilDB->quote((string) $a_usage_lang, "text")." AND ".
957  "usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer");
958  $file_set = $ilDB->query($q);
959  $ret = array();
960  while($file_rec = $ilDB->fetchAssoc($file_set))
961  {
962  $ret[$file_rec["id"]] = $file_rec["id"];
963  }
964 
965  return $ret;
966  }
967 
968  // TODO: What is this function good for??
969  function getXMLZip()
970  {
971  global $ilias;
972 
973  $zip = PATH_TO_ZIP;
974 
975  exec($zip.' '.ilUtil::escapeShellArg($this->getDirectory().'/'.$this->getFileName())." ".
976  ilUtil::escapeShellArg($this->getDirectory().'/'.'1.zip'));
977 
978  return $this->getDirectory().'/1.zip';
979  }
980 
981  function addNewsNotification($a_lang_var)
982  {
983  // BEGIN WebDAV Suppress news notification for hidden files
984  if ($this->isHidden()) {
985  return;
986  }
987  // END WebDAV Suppress news notification for hidden files
988 
989  global $ilUser;
990 
991  // Add Notification to news
992  include_once("./Services/News/classes/class.ilNewsItem.php");
993  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
994  $news_item = new ilNewsItem();
995  $news_item->setContext($this->getId(), $this->getType());
996  $news_item->setPriority(NEWS_NOTICE);
997  $news_item->setTitle($a_lang_var);
998  $news_item->setContentIsLangVar(true);
999  if ($this->getDescription() != "")
1000  {
1001  $news_item->setContent(
1002  "<p>".
1003  $this->getDescription()."</p>");
1004  }
1005  $news_item->setUserId($ilUser->getId());
1006  $news_item->setVisibility(NEWS_USERS);
1007  $news_item->create();
1008  }
1009 
1016  public function initFileStorage()
1017  {
1018  $this->file_storage = new ilFSStorageFile($this->getId());
1019  return true;
1020  }
1030  function storeUnzipedFile($a_upload_file, $a_filename)
1031  {
1032  $this->setVersion($this->getVersion() + 1);
1033 
1034  if (@!is_dir($this->getDirectory($this->getVersion())))
1035  {
1036  ilUtil::makeDir($this->getDirectory($this->getVersion()));
1037  }
1038 
1039  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
1040  //move_uploaded_file($a_upload_file, $file);
1041  rename($a_upload_file, $file);
1042 
1043  // create preview
1044  $this->createPreview();
1045  }
1046 
1051  public static function _lookupAbsolutePath ($obj_id, $a_version = null)
1052  {
1053  $file_storage = new ilFSStorageFile($obj_id);
1055  $version_subdir = "";
1056 
1057  if (!is_numeric($a_version))
1058  {
1059  $a_version = ilObjFile::_lookupVersion ($obj_id);
1060  }
1061  $version_subdir = DIRECTORY_SEPARATOR.sprintf("%03d", $a_version);
1062  return $file_storage->getAbsolutePath().$version_subdir.DIRECTORY_SEPARATOR.$filename;
1063  }
1064 
1069  public function checkFileExtension($new_filename,$new_title)
1070  {
1071  include_once './Modules/File/classes/class.ilObjFileAccess.php';
1072  $fileExtension = ilObjFileAccess::_getFileExtension($new_filename);
1073  $titleExtension = ilObjFileAccess::_getFileExtension($new_title);
1074  if ($titleExtension != $fileExtension && strlen($fileExtension) > 0)
1075  {
1076  // remove old extension
1077  $pi = pathinfo($this->getFileName());
1078  $suffix = $pi["extension"];
1079  if ($suffix != "")
1080  {
1081  if (substr($new_title,
1082  strlen($new_title) - strlen($suffix) - 1)
1083  == ".".$suffix)
1084  {
1085  $new_title = substr($new_title, 0, strlen($new_title) - strlen($suffix) - 1);
1086  }
1087  }
1088  $new_title .= '.'.$fileExtension;
1089  }
1090  return $new_title;
1091  }
1092 
1099  public function getVersions($version_ids = null)
1100  {
1101  include_once("./Services/History/classes/class.ilHistory.php");
1102  $versions = ilHistory::_getEntriesForObject($this->getId(), $this->getType());
1103 
1104  if ($version_ids != null && count($version_ids) > 0)
1105  {
1106  foreach ($versions as $index => $version)
1107  {
1108  if (!in_array($version["hist_entry_id"], $version_ids, true))
1109  {
1110  unset($versions[$index]);
1111  }
1112  }
1113  }
1114 
1115  // add custom entries
1116  foreach ($versions as $index => $version)
1117  {
1118  $params = $this->parseInfoParams($version);
1119  $versions[$index] = array_merge($version, $params);
1120  }
1121 
1122  // sort by version number (hist_entry_id will do for that)
1123  usort($versions, array($this, "compareVersions"));
1124 
1125  return $versions;
1126  }
1127 
1134  public function getSpecificVersion($version_id)
1135  {
1136  include_once("./Services/History/classes/class.ilHistory.php");
1137  $version = ilHistory::_getEntryByHistoryID($version_id);
1138  if ($version === false)
1139  return false;
1140 
1141  // ilHistory returns different keys in _getEntryByHistoryID and _getEntriesForObject
1142  // so this makes it the same
1143  $version["hist_entry_id"] = $version["id"];
1144  $version["user_id"] = $version["usr_id"];
1145  $version["date"] = $version["hdate"];
1146  unset($version["id"], $version["usr_id"], $version["hdate"]);
1147 
1148  // parse params
1149  $params = $this->parseInfoParams($version);
1150  return array_merge($version, $params);
1151  }
1152 
1159  public function rollback($version_id)
1160  {
1161  global $ilDB, $ilUser;
1162 
1163  $source = $this->getSpecificVersion($version_id);
1164  if ($source === false)
1165  {
1166  $this->ilErr->raiseError($this->lng->txt("obj_not_found"), $this->ilErr->MESSAGE);
1167  }
1168 
1169  // get the new version number
1170  $new_version_nr = $this->getVersion() + 1;
1171 
1172  // copy file
1173  $source_path = $this->getDirectory($source["version"]) . "/" . $source["filename"];
1174  $dest_dir = $this->getDirectory($new_version_nr);
1175  if (@!is_dir($dest_dir))
1176  ilUtil::makeDir($dest_dir);
1177 
1178  copy($source_path, $dest_dir . "/" . $source["filename"]);
1179 
1180  // create new history entry based on the old one
1181  include_once("./Services/History/classes/class.ilHistory.php");
1183  $this->getId(),
1184  "rollback",
1185  $source["filename"] . "," . $new_version_nr . "|" . $source["version"] . "|" . $ilUser->getId());
1186 
1187  // get id of newest entry
1188  $new_version = $this->getSpecificVersion($ilDB->getLastInsertId());
1189 
1190  // change user back to the original uploader
1191  ilHistory::_changeUserId($new_version["hist_entry_id"], $source["user_id"]);
1192 
1193  // update this file with the new version
1194  $this->updateWithVersion($new_version);
1195 
1196  $this->addNewsNotification("file_updated");
1197 
1198  return $new_version;
1199  }
1200 
1206  protected function updateWithVersion($version)
1207  {
1208  // update title (checkFileExtension must be called before setFileName!)
1209  $this->setTitle($this->checkFileExtension($version["filename"], $this->getTitle()));
1210 
1211  $this->setVersion($version["version"]);
1212  $this->setFileName($version["filename"]);
1213 
1214  // evaluate mime type (reset file type before)
1215  $this->setFileType("");
1216  $this->setFileType($this->guessFileType($version["filename"]));
1217 
1218  // set filesize
1219  $this->determineFileSize();
1220 
1221  $this->update();
1222 
1223  // refresh preview
1224  $this->createPreview(true);
1225  }
1226 
1234  function compareVersions($v1, $v2)
1235  {
1236  // v2 - v1 because version should be descending
1237  return (int)$v2["version"] - (int)$v1["version"];
1238  }
1239 
1246  function parseInfoParams($entry)
1247  {
1248  $data = preg_split("/(.*),(.*)/", $entry["info_params"], 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
1249 
1250  // bugfix: first created file had no version number
1251  // this is a workaround for all files created before the bug was fixed
1252  if (empty($data[1]))
1253  $data[1] = "1";
1254 
1255  $result = array("filename" => $data[0], "version" => $data[1], "rollback_version" => "", "rollback_user_id" => "");
1256 
1257  // if rollback, the version contains the rollback version as well
1258  if ($entry["action"] == "rollback")
1259  {
1260  $tokens = explode("|", $result["version"]);
1261  if (count($tokens) > 1)
1262  {
1263  $result["version"] = $tokens[0];
1264  $result["rollback_version"] = $tokens[1];
1265 
1266  if (count($tokens) > 2)
1267  $result["rollback_user_id"] = $tokens[2];
1268  }
1269  }
1270 
1271  return $result;
1272  }
1273 
1274  protected static function handleQuotaUpdate(ilObjFile $a_file)
1275  {
1276  include_once "Services/MediaObjects/classes/class.ilObjMediaObject.php";
1277  $mob = new ilObjMediaObject();
1278 
1279  // file itself could be workspace item
1280  $parent_obj_ids = array($a_file->getId());
1281 
1282  foreach($a_file->getUsages() as $item)
1283  {
1284  $parent_obj_id = $mob->getParentObjectIdForUsage($item);
1285  if($parent_obj_id &&
1286  !in_array($parent_obj_id, $parent_obj_ids))
1287  {
1288  $parent_obj_ids[]= $parent_obj_id;
1289  }
1290  }
1291 
1292  include_once "Services/DiskQuota/classes/class.ilDiskQuotaHandler.php";
1294  $a_file->getId(),
1295  $a_file->getDiskUsage(),
1296  $parent_obj_ids);
1297  }
1298 
1304  protected function createPreview($force = false)
1305  {
1306  // only normal files are supported
1307  if ($this->getMode() != "object")
1308  return;
1309 
1310  require_once("./Services/Preview/classes/class.ilPreview.php");
1311  ilPreview::createPreview($this, $force);
1312  }
1313 
1317  protected function deletePreview()
1318  {
1319  // only normal files are supported
1320  if ($this->getMode() != "object")
1321  return;
1322 
1323  require_once("./Services/Preview/classes/class.ilPreview.php");
1324  ilPreview::deletePreview($this->getId());
1325  }
1326 
1327  public function setRating($a_value)
1328  {
1329  $this->rating = (bool)$a_value;
1330  }
1331 
1332  public function hasRating()
1333  {
1334  return $this->rating;
1335  }
1336 
1337 } // END class.ilObjFile
1338 ?>