ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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 require_once('Modules/File/classes/class.ilFSStorageFile.php');
6 
16 class ilObjFile extends ilObject2 {
17 
18  var $filename;
19  var $filetype;
20  var $filemaxsize = "20000000"; // not used yet
22  var $mode = "object";
23  protected $rating = false;
24 
25  private $file_storage = null;
26  protected $log = null;
27 
28 
35  public function __construct($a_id = 0, $a_call_by_reference = true) {
36  $this->version = 0;
37  $this->raise_upload_error = true;
38 
39  $this->log = ilLoggerFactory::getLogger('file');
40 
41  parent::__construct($a_id,$a_call_by_reference);
42 
43  if($this->getId())
44  {
45  $this->initFileStorage();
46  }
47  }
48 
52  function initType()
53  {
54  $this->type = "file";
55  }
56 
62  protected function doCreate($a_upload = false)
63  {
64  //BEGIN WebDAV Move Property creation into a method of its own.
65  $this->createProperties($a_upload);
66  //END WebDAV Move Property creation into a method of its own.
67  }
68 
69  //BEGIN WebDAV: Move Property creation into a method of its own.
77  function createProperties($a_upload = false)
78  {
79  global $ilDB,$tree;
80 
81  // Create file directory
82  $this->initFileStorage();
83  $this->file_storage->create();
84 
85  if($a_upload)
86  {
87  return true;
88  }
89 
90  // not upload mode
91  require_once("./Services/History/classes/class.ilHistory.php");
92  ilHistory::_createEntry($this->getId(), "create", $this->getFileName().",1");
93  $this->addNewsNotification("file_created");
94 
95 
96  require_once("./Services/News/classes/class.ilNewsItem.php");
97  $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET['ref_id']);
98  if ($default_visibility == "public")
99  {
100  ilBlockSetting::_write("news", "public_notifications",
101  1, 0, $this->getId());
102  }
103 
104  // log creation
105  include_once("./Services/Utilities/classes/class.ilStr.php");
106  $this->log->debug("ilObjFile::createProperties, ID: ".$this->getId().
107  ", Name: ".$this->getFileName().
108  ", Type: ".$this->getFileType().
109  ", Size: ".$this->getFileSize().
110  ", Mode: ".$this->getMode().
111  ", Name(Bytes): ".implode(":", ilStr::getBytesForString($this->getFileName()))
112  );
113  $this->log->logStack(ilLogLevel::DEBUG);
114 
115  $q = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,f_mode) "
116  ."VALUES (".$ilDB->quote($this->getId() ,'integer').","
117  .$ilDB->quote($this->getFileName() ,'text').","
118  .$ilDB->quote($this->getFileType() ,'text').","
119  .$ilDB->quote((int) $this->getFileSize() ,'integer').","
120  .$ilDB->quote(1 ,'integer').",".$ilDB->quote($this->getMode() ,'text').")";
121  $res = $ilDB->manipulate($q);
122 
123  // no meta data handling for file list files
124  if ($this->getMode() != "filelist")
125  {
126  $this->createMetaData();
127  }
128  }
129  //END WebDAV: Move Property creation into a method of its own.
130 
131  public function setNoMetaDataCreation($a_status)
132  {
133  $this->no_meta_data_creation = (bool)$a_status;
134  }
135 
136  protected function beforeCreateMetaData()
137  {
138  return !(bool)$this->no_meta_data_creation;
139  }
140 
141  protected function beforeUpdateMetaData()
142  {
143  return !(bool)$this->no_meta_data_creation;
144  }
145 
149  protected function doCreateMetaData()
150  {
151  // add technical section with file size and format
152  $md_obj = new ilMD($this->getId(),0,$this->getType());
153  $technical = $md_obj->addTechnical();
154  $technical->setSize($this->getFileSize());
155  $technical->save();
156  $format = $technical->addFormat();
157  $format->setFormat($this->getFileType());
158  $format->save();
159  $technical->update();
160  }
161 
162  protected function beforeMDUpdateListener($a_element)
163  {
164  // Check file extension
165  // Removing the file extension is not allowed
166  include_once 'Services/MetaData/classes/class.ilMD.php';
167  $md = new ilMD($this->getId(),0, $this->getType());
168  if(!is_object($md_gen = $md->getGeneral()))
169  {
170  return false;
171  }
172  $title = $this->checkFileExtension($this->getFileName(), $md_gen->getTitle());
173  $md_gen->setTitle($title);
174  $md_gen->update();
175  return true;
176  }
177 
178  protected function doMDUpdateListener($a_element)
179  {
180  // handling for technical section
181  include_once 'Services/MetaData/classes/class.ilMD.php';
182 //echo "-".$a_element."-";
183  switch($a_element)
184  {
185  case 'Technical':
186 
187  // Update Format (size is not stored in db)
188  $md = new ilMD($this->getId(),0, $this->getType());
189  if(!is_object($md_technical = $md->getTechnical()))
190  {
191  return false;
192  }
193 
194  foreach($md_technical->getFormatIds() as $id)
195  {
196  $md_format = $md_technical->getFormat($id);
197  ilObjFile::_writeFileType($this->getId(),$md_format->getFormat());
198  $this->setFileType($md_format->getFormat());
199  break;
200  }
201 
202  break;
203  }
204  return true;
205  }
206 
207 
208  function getDirectory($a_version = 0)
209  {
210  $version_subdir = "";
211 
212  if ($a_version)
213  {
214  // BEGIN WebDAV Avoid double slash before version subdirectory
215  $version_subdir = sprintf("%03d", $a_version);
216  // END WebDAV Avoid double slash before version subdirectory
217  }
218 
219  if(!is_object($this->file_storage))
220  {
221  $this->initFileStorage();
222  }
223 
224  return $this->file_storage->getAbsolutePath().'/'.$version_subdir;
225  }
226 
227  function createDirectory()
228  {
230  }
231 
232  function raiseUploadError($a_raise = true)
233  {
234  $this->raise_upload_error = $a_raise;
235  }
236 
237  function getUploadFile($a_upload_file, $a_filename, $a_prevent_preview = false, $handle_secure_name = true)
238  {
239  if ($handle_secure_name) {
240  require_once('./Services/Utilities/classes/class.ilFileUtils.php');
241  $a_filename = ilFileUtils::getValidFilename($a_filename);
242  $this->setFileName($a_filename);
243  $this->setTitle($a_filename);
244  $this->update();
245  }
246  if($this->version) {
247  $this->setVersion($this->getVersion() + 1);
248  }
249 
250  if (@!is_dir($this->getDirectory($this->getVersion())))
251  {
253  }
254 
255  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
256  ilUtil::moveUploadedFile($a_upload_file, $a_filename, $file, $this->raise_upload_error);
257 
258  $this->handleQuotaUpdate($this);
259 
260  // create preview?
261  if (!$a_prevent_preview)
262  {
263  $this->createPreview(false);
264  }
265  }
266 
270  function replaceFile($a_upload_file, $a_filename)
271  {
272  $this->getUploadFile($a_upload_file, $a_filename, true);
273 
274  require_once("./Services/History/classes/class.ilHistory.php");
276  $this->getId(),
277  "replace",
278  $a_filename.",".$this->getVersion()
279  );
280  $this->setFilename($a_filename);
281  $this->addNewsNotification("file_updated");
282 
283  // create preview
284  $this->createPreview(true);
285  }
286 
287 
288  public function addFileVersion($a_upload_file,$a_filename)
289  {
290  $this->getUploadFile($a_upload_file, $a_filename, true);
291 
292  require_once("./Services/History/classes/class.ilHistory.php");
294  $this->getId(),
295  "new_version",
296  $a_filename.",".$this->getVersion()
297  );
298  $this->setFilename($a_filename);
299  $this->addNewsNotification("file_updated");
300 
301  // create preview
302  $this->createPreview($this->getVersion() > 1);
303  }
304 
305 
309  function copy($a_source,$a_destination)
310  {
311  return copy($a_source,$this->getDirectory()."/".$a_destination);
312  }
313 
318  {
319  ilUtil::delDir($this->getDirectory());
320  $this->createDirectory();
321  }
322 
328  public function deleteVersions($a_hist_entry_ids = null)
329  {
330  global $ilDB;
331 
332  require_once("./Services/History/classes/class.ilHistory.php");
333 
334  if ($a_hist_entry_ids == null || count($a_hist_entry_ids) < 1)
335  {
336  $ilDB->manipulate("UPDATE file_data SET version = 1 WHERE file_id = ".$ilDB->quote($this->getId() ,'integer'));
337  $this->setVersion(0);
338  $this->clearDataDirectory();
339 
341 
342  self::handleQuotaUpdate($this);
343  }
344  else
345  {
346  $actualVersionDeleted = false;
347 
348  // get all versions
349  $versions = $this->getVersions();
350 
351  // delete each version
352  foreach ($a_hist_entry_ids as $hist_id)
353  {
354  $entry = null;
355 
356  // get version
357  foreach ($versions as $index => $version)
358  {
359  if ($version["hist_entry_id"] == $hist_id)
360  {
361  // remove each history entry
363 
364  // delete directory
365  $version_dir = $this->getDirectory($version["version"]);
366  ilUtil::delDir($version_dir);
367 
368  // is actual version?
369  if ($version["version"] == $this->getVersion())
370  $actualVersionDeleted = true;
371 
372  // remove from array
373  unset($versions[$index]);
374  break;
375  }
376  }
377  }
378 
379  // update actual version if it was deleted before
380  if ($actualVersionDeleted)
381  {
382  // get newest version (already sorted by getVersions)
383  $version = reset($versions);
384  $this->updateWithVersion($version);
385  }
386  else
387  {
388  // updateWithVersion() will trigger quota, too
389  self::handleQuotaUpdate($this);
390  }
391  }
392  }
393 
397  protected function doRead()
398  {
399  global $ilDB;
400 
401  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
402  $r = $this->ilias->db->query($q);
403  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
404 
405  $this->setFileName($row->file_name);
406  $this->setFileType($row->file_type);
407  $this->setFileSize($row->file_size);
408  $this->setVersion($row->version);
409  $this->setMode($row->f_mode);
410  $this->setRating($row->rating);
411 
412  $this->initFileStorage();
413  }
414 
415  protected function beforeUpdate()
416  {
417  // no meta data handling for file list files
418  if ($this->getMode() != "filelist")
419  {
420  $this->updateMetaData();
421  }
422 
423  return true;
424  }
425 
429  protected function doUpdate()
430  {
431  global $ilDB, $ilLog;
432 
433  //$ilLog->write(__METHOD__.' File type: '.$this->getFileType());
434 
435  $q = "UPDATE file_data SET file_name = ".$ilDB->quote($this->getFileName() ,'text').
436  ", file_type = ".$ilDB->quote($this->getFiletype() ,'text')." ".
437  ", file_size = ".$ilDB->quote((int) $this->getFileSize() ,'integer')." ".
438  ", version = ".$ilDB->quote($this->getVersion() ,'integer')." ".
439  ", f_mode = ".$ilDB->quote($this->getMode() ,'text')." ".
440  ", rating = ".$ilDB->quote($this->hasRating() ,'integer')." ".
441  "WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
442  $res = $ilDB->manipulate($q);
443 
444  self::handleQuotaUpdate($this);
445 
446  return true;
447  }
448 
452  protected function doUpdateMetaData()
453  {
454  // add technical section with file size and format
455  $md_obj = new ilMD($this->getId(),0,$this->getType());
456  if(!is_object($technical = $md_obj->getTechnical()))
457  {
458  $technical = $md_obj->addTechnical();
459  $technical->save();
460  }
461  $technical->setSize($this->getFileSize());
462 
463  $format_ids = $technical->getFormatIds();
464  if (count($format_ids) > 0)
465  {
466  $format = $technical->getFormat($format_ids[0]);
467  $format->setFormat($this->getFileType());
468  $format->update();
469  }
470  else
471  {
472  $format = $technical->addFormat();
473  $format->setFormat($this->getFileType());
474  $format->save();
475  }
476  $technical->update();
477  }
478 
482  function setFileName($a_name)
483  {
484  $this->filename = $a_name;
485  }
486 
487  function getFileName()
488  {
489  return $this->filename;
490  }
491 
492  function setFileType($a_type)
493  {
494  global $ilLog;
495 
496 
497  $this->filetype = $a_type;
498  }
499 
500  function getFileType()
501  {
502  return $this->filetype;
503  }
504 
505  function setFileSize($a_size)
506  {
507  $this->filesize = $a_size;
508  }
509 
510  function getFileSize()
511  {
512  return $this->filesize;
513  }
520  function getDiskUsage()
521  {
522  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
523  return ilObjFileAccess::_lookupDiskUsage($this->id);
524  }
525 
526 
527  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
528  function getFile($a_hist_entry_id = null)
529  {
530  if (is_null($a_hist_entry_id))
531  {
532  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
533  }
534  else
535  {
536  require_once("./Services/History/classes/class.ilHistory.php");
537  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
538 
539  if ($entry === false)
540  {
541  return false;
542  }
543 
544  $data = $this->parseInfoParams($entry);
545  $file = $this->getDirectory($data["version"])."/".$data["filename"];
546  }
547  return $file;
548  }
549  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
550 
551  function setVersion($a_version)
552  {
553  $this->version = $a_version;
554  }
555 
556  function getVersion()
557  {
558  return $this->version ? $this->version : 1;
559  }
560 
566  function setMode($a_mode)
567  {
568  $this->mode = $a_mode;
569  }
570 
576  function getMode()
577  {
578  return $this->mode;
579  }
580 
581  static function _writeFileType($a_id ,$a_format)
582  {
583  global $ilDB;
584 
585  $q = "UPDATE file_data SET ".
586  " file_type = ".$ilDB->quote($a_format ,'text').
587  " WHERE file_id = ".$ilDB->quote($a_id ,'integer');
588  $res = $ilDB->manipulate($q);
589 
590  }
591 
592  static function _lookupFileName($a_id)
593  {
594  global $ilDB;
595 
596  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($a_id ,'integer');
597  $r = $ilDB->query($q);
598  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
599 
600  return ilUtil::stripSlashes($row->file_name);
601  }
602 
603 
605  static function _lookupFileSize($a_id)
606  {
607  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
608  return ilObjFileAccess::_lookupFileSize($a_id);
609  }
610 
614  static function _lookupVersion($a_id)
615  {
616  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
617  return ilObjFileAccess::_lookupVersion($a_id);
618  }
619 
623  function determineFileSize($a_hist_entry_id = null)
624  {
625  if (is_null($a_hist_entry_id))
626  {
627  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
628  }
629  else
630  {
631  require_once("./Services/History/classes/class.ilHistory.php");
632  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
633 
634  if ($entry === false)
635  {
636  return false;
637  }
638 
639  $data = $this->parseInfoParams($entry);
640  $file = $this->getDirectory($data["version"])."/".$data["filename"];
641  }
642  if (is_file($file))
643  {
644  $this->setFileSize(filesize($file));
645  }
646  }
647 
648  function sendFile($a_hist_entry_id = null)
649  {
650  if (is_null($a_hist_entry_id))
651  {
652  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
653 
654  // if not found lookup for file in file object's main directory for downward c ompability
655  if (@!is_file($file))
656  {
657  $file = $this->getDirectory()."/".$this->getFileName();
658  }
659  }
660  else
661  {
662  require_once("./Services/History/classes/class.ilHistory.php");
663  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
664 
665  if ($entry === false)
666  {
667  echo "3";return false;
668  }
669 
670  $data = $this->parseInfoParams($entry);
671  $file = $this->getDirectory($data["version"])."/".$data["filename"];
672 
673  // if not found lookup for file in file object's main directory for downward compability
674  if (@!is_file($file))
675  {
676  $file = $this->getDirectory()."/".$data[0];
677  }
678 
679  // BEGIN WebDAV removed duplicated code
680  // END WebDAV removed duplicated code
681  }
682 
683  if (@is_file($file))
684  {
685  global $ilClientIniFile;
689  /*require_once('./Services/FileDelivery/classes/class.ilFileDelivery.php');
690 
691  //
692 
693  $ilFileDelivery = new ilFileDelivery($file);
694  $ilFileDelivery->setDeliveryType(ilFileDelivery::DELIVERY_METHOD_PHP); // always use PHP in ILIAS 5.1
695  $ilFileDelivery->setDisposition($this->isInline() ? ilFileDelivery::DISP_INLINE : ilFileDelivery::DISP_ATTACHMENT);
696  $ilFileDelivery->setMimeType($this->guessFileType($file));
697  $ilFileDelivery->setConvertFileNameToAsci(true);*/
698 
699  // also returning the 'real' filename if a history file is delivered
700  if ($ilClientIniFile->readVariable('file_access', 'download_with_uploaded_filename') != '1' && is_null($a_hist_entry_id)) {
701  // $ilFileDelivery->setDownloadFileName($this->getTitle());
702  ilUtil::deliverFile($file, $this->getTitle(), $this->guessFileType($file), $this->isInline());
703  } else {
704  // $download_file_name = basename($file);
705  /* FSX Info: basename has a Bug with Japanese and other characters, see:
706  * http://stackoverflow.com/questions/32115609/basename-fail-when-file-name-start-by-an-accent
707  * Therefore we can no longer use basename();
708  */
709  $download_file_name = end(explode(DIRECTORY_SEPARATOR, $file));
710  // $ilFileDelivery->setDownloadFileName($download_file_name);
711  ilUtil::deliverFile($file, $download_file_name, $this->guessFileType($file), $this->isInline());
712  }
713  // $ilFileDelivery->deliver();
714 
715  return true;
716  }
717 
718  return false;
719  }
720 
721  // BEGIN WebDAV: Get file extension, determine if file is inline, guess file type.
726  function getFileExtension() {
727  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
729  }
735  function isInline() {
736  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
737  return ilObjFileAccess::_isFileInline($this->getTitle());
738  }
742  function isHidden() {
743  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
744  return ilObjFileAccess::_isFileHidden($this->getTitle());
745  }
746  // END WebDAV: Get file extension, determine if file is inline, guess file type.
747 
754  function guessFileType($a_file = "") {
755 
756  $path = pathinfo($a_file);
757  if ($path["extension"] != "")
758  {
759  $filename = $path["basename"];
760  }
761  else
762  {
763  $filename = "dummy.".$this->getFileExtension();
764  }
765  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
766  $mime = ilMimeTypeUtil::getMimeType($a_file, $filename, $this->getFileType());
767  return $mime;
768 
769 /*
770  $fileType = $this->getFileType();
771  if (strlen($fileType) == 0) {
772  $fileType = 'application/octet-stream';
773  }
774 
775  // Firefox browser assigns 'application/x-pdf' to PDF files, but
776  // it can only handle them if the have the mime-type 'application/pdf'.
777  if ($fileType == 'application/x-pdf')
778  {
779  $fileType = 'application/pdf';
780  }
781 
782  if ($fileType == 'application/octet-stream')
783  {
784  $fileExtension = $this->getFileExtension();
785  $mimeArray = array(
786  'mpeg' => 'video/mpeg',
787  'mp3' => 'audio/mpeg',
788  'pdf' => 'application/pdf',
789  'gif' => 'image/gif',
790  'jpg' => 'image/jpg',
791  'png' => 'image/png',
792  'htm' => 'text/html',
793  'html' => 'text/html',
794  'wma' => 'video/x-ms-wma',
795  'wmv' => 'video/x-ms-wmv',
796  'swf' => 'application/x-shockwave-flash',
797  );
798  if (array_key_exists($fileExtension, $mimeArray))
799  {
800  $fileType = $mimeArray[$fileExtension];
801  }
802  }
803  return $fileType;
804 */
805  }
806 
816  protected function doCloneObject($a_new_obj,$a_target_id,$a_copy_id = 0)
817  {
818  global $ilDB;
819 
820  $a_new_obj->createDirectory();
821  $this->cloneMetaData($a_new_obj);
822 
823  // Copy all file versions
824  ilUtil::rCopy($this->getDirectory(),$a_new_obj->getDirectory());
825 
826  // object created now copy other settings
827  $query = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,rating,f_mode) VALUES (".
828  $ilDB->quote($a_new_obj->getId() ,'integer').",".
829  $ilDB->quote($this->getFileName() ,'text').",".
830  $ilDB->quote($this->getFileType() ,'text').",".
831  $ilDB->quote((int) $this->getFileSize() ,'integer').", ".
832  $ilDB->quote($this->getVersion() ,'integer').", ".
833  $ilDB->quote($this->hasRating() ,'integer').", ".
834  $ilDB->quote($this->getMode() ,'text').")";
835  $res = $ilDB->manipulate($query);
836 
837  // copy all previews
838  require_once("./Services/Preview/classes/class.ilPreview.php");
839  ilPreview::copyPreviews($this->getId(), $a_new_obj->getId());
840 
841  // copy history entries
842  require_once("./Services/History/classes/class.ilHistory.php");
843  ilHistory::_copyEntriesForObject($this->getId(),$a_new_obj->getId());
844 
845  // Copy learning progress settings
846  include_once('Services/Tracking/classes/class.ilLPObjSettings.php');
847  $obj_settings = new ilLPObjSettings($this->getId());
848  $obj_settings->cloneSettings($a_new_obj->getId());
849  unset($obj_settings);
850 
851  // add news notification
852  $a_new_obj->addNewsNotification("file_created");
853 
854  return $a_new_obj;
855  }
856 
857  protected function beforeDelete()
858  {
859  global $ilDB;
860 
861  // check, if file is used somewhere
862  $usages = $this->getUsages();
863  if (count($usages) == 0)
864  {
865  return true;
866  }
867  return false;
868  }
869 
870  protected function doDelete()
871  {
872  global $ilDB;
873 
874  // delete file data entry
875  $q = "DELETE FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
876  $this->ilias->db->query($q);
877 
878  // delete history entries
879  require_once("./Services/History/classes/class.ilHistory.php");
881 
882  // delete entire directory and its content
883  if (@is_dir($this->getDirectory()))
884  {
885  ilUtil::delDir($this->getDirectory());
886  }
887 
888  // delete meta data
889  if ($this->getMode() != "filelist")
890  {
891  $this->deleteMetaData();
892  }
893 
894  self::handleQuotaUpdate($this);
895 
896  // delete preview
897  $this->deletePreview();
898  }
899 
907  function export($a_target_dir)
908  {
909  $subdir = "il_".IL_INST_ID."_file_".$this->getId();
910  ilUtil::makeDir($a_target_dir."/objects/".$subdir);
911 
912  $filedir = $this->getDirectory($this->getVersion());
913 
914  if (@!is_dir($filedir))
915  {
916  $filedir = $this->getDirectory();
917  }
918 
919  ilUtil::rCopy($filedir, $a_target_dir."/objects/".$subdir);
920  }
921 
925  static function _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
926  {
927  global $ilDB;
928 
929  $and_hist = ($a_usage_hist_nr !== false)
930  ? " AND usage_hist_nr = ".$ilDB->quote($a_usage_hist_nr, "integer")
931  : "";
932 
933  $file_ids = array();
934  $set = $ilDB->query("SELECT id FROM file_usage".
935  " WHERE usage_type = ".$ilDB->quote($a_type, "text").
936  " AND usage_id= ".$ilDB->quote($a_id, "integer").
937  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
938  $and_hist);
939  while($row = $ilDB->fetchAssoc($set))
940  {
941  $file_ids[] = $row["id"];
942  }
943 
944  $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = ".
945  $ilDB->quote($a_type, "text").
946  " AND usage_id = ".$ilDB->quote((int) $a_id, "integer").
947  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
948  " AND usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer"));
949 
950  foreach($file_ids as $file_id)
951  {
952  self::handleQuotaUpdate(new self($file_id, false));
953  }
954  }
955 
959  static function _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
960  {
961  global $ilDB;
962 
963  /*
964  $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = ".
965  $ilDB->quote((string) $a_type, "text").
966  " AND usage_id = ".$ilDB->quote((int) $a_id, "integer").
967  " AND usage_lang = ".$ilDB->quote($a_usage_lang, "text").
968  " AND usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer").
969  " AND id = ".$ilDB->quote((int) $a_file_id, "integer"));
970 
971  $ilDB->manipulate("INSERT INTO file_usage (id, usage_type, usage_id, usage_hist_nr, usage_lang) VALUES".
972  " (".$ilDB->quote((int) $a_file_id, "integer").",".
973  $ilDB->quote((string) $a_type, "text").",".
974  $ilDB->quote((int) $a_id, "integer").",".
975  $ilDB->quote((int) $a_usage_hist_nr, "integer").",".
976  $ilDB->quote($a_usage_lang, "text").
977  ")");
978  */
979 
980  // #15143
981  $ilDB->replace("file_usage",
982  array(
983  "id" => array("integer", (int) $a_file_id),
984  "usage_type" => array("text", (string) $a_type),
985  "usage_id" => array("integer", (int) $a_id),
986  "usage_hist_nr" => array("integer", (int) $a_usage_hist_nr),
987  "usage_lang" => array("text", $a_usage_lang)
988  ),
989  array()
990  );
991 
992  self::handleQuotaUpdate(new self($a_file_id, false));
993  }
994 
998  function getUsages()
999  {
1000  global $ilDB;
1001 
1002  // get usages in learning modules
1003  $q = "SELECT * FROM file_usage WHERE id = ".$ilDB->quote($this->getId(), "integer");
1004  $us_set = $ilDB->query($q);
1005  $ret = array();
1006  while($us_rec = $ilDB->fetchAssoc($us_set))
1007  {
1008  $ret[] = array("type" => $us_rec["usage_type"],
1009  "id" => $us_rec["usage_id"],
1010  "lang" => $us_rec["usage_lang"],
1011  "hist_nr" => $us_rec["usage_hist_nr"]);
1012  }
1013 
1014  return $ret;
1015  }
1016 
1025  static function _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
1026  {
1027  global $ilDB;
1028 
1029  $lstr = "";
1030  if ($a_usage_lang != "")
1031  {
1032  $lstr = "usage_lang = ".$ilDB->quote((string) $a_usage_lang, "text")." AND ";
1033  }
1034 
1035  // get usages in learning modules
1036  $q = "SELECT * FROM file_usage WHERE ".
1037  "usage_id = ".$ilDB->quote((int) $a_id, "integer")." AND ".
1038  "usage_type = ".$ilDB->quote((string) $a_type, "text")." AND ".
1039  $lstr.
1040  "usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer");
1041  $file_set = $ilDB->query($q);
1042  $ret = array();
1043  while($file_rec = $ilDB->fetchAssoc($file_set))
1044  {
1045  $ret[$file_rec["id"]] = $file_rec["id"];
1046  }
1047 
1048  return $ret;
1049  }
1050 
1051  // TODO: What is this function good for??
1052  function getXMLZip()
1053  {
1054  global $ilias;
1055 
1056  $zip = PATH_TO_ZIP;
1057 
1058  exec($zip.' '.ilUtil::escapeShellArg($this->getDirectory().'/'.$this->getFileName())." ".
1059  ilUtil::escapeShellArg($this->getDirectory().'/'.'1.zip'));
1060 
1061  return $this->getDirectory().'/1.zip';
1062  }
1063 
1064  function addNewsNotification($a_lang_var)
1065  {
1066  // BEGIN WebDAV Suppress news notification for hidden files
1067  if ($this->isHidden()) {
1068  return;
1069  }
1070  // END WebDAV Suppress news notification for hidden files
1071 
1072  global $ilUser;
1073 
1074  // Add Notification to news
1075  include_once("./Services/News/classes/class.ilNewsItem.php");
1076  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
1077  $news_item = new ilNewsItem();
1078  $news_item->setContext($this->getId(), $this->getType());
1079  $news_item->setPriority(NEWS_NOTICE);
1080  $news_item->setTitle($a_lang_var);
1081  $news_item->setContentIsLangVar(true);
1082  if ($this->getDescription() != "")
1083  {
1084  $news_item->setContent(
1085  "<p>".
1086  $this->getDescription()."</p>");
1087  }
1088  $news_item->setUserId($ilUser->getId());
1089  $news_item->setVisibility(NEWS_USERS);
1090  $news_item->create();
1091  }
1092 
1099  public function initFileStorage()
1100  {
1101  $this->file_storage = new ilFSStorageFile($this->getId());
1102  return true;
1103  }
1113  function storeUnzipedFile($a_upload_file, $a_filename)
1114  {
1115  if (@!is_dir($this->getDirectory($this->getVersion())))
1116  {
1117  ilUtil::makeDir($this->getDirectory($this->getVersion()));
1118  }
1119 
1120  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
1121  require_once('./Services/Utilities/classes/class.ilFileUtils.php');
1122  ilFileUtils::rename($a_upload_file, $file);
1123 
1124  // create preview
1125  $this->createPreview();
1126  }
1127 
1132  public static function _lookupAbsolutePath ($obj_id, $a_version = null)
1133  {
1134  $file_storage = new ilFSStorageFile($obj_id);
1135  $filename = ilObjFile::_lookupFileName($obj_id);
1136  $version_subdir = "";
1137 
1138  if (!is_numeric($a_version))
1139  {
1140  $a_version = ilObjFile::_lookupVersion ($obj_id);
1141  }
1142  $version_subdir = DIRECTORY_SEPARATOR.sprintf("%03d", $a_version);
1143  return $file_storage->getAbsolutePath().$version_subdir.DIRECTORY_SEPARATOR.$filename;
1144  }
1145 
1150  public function checkFileExtension($new_filename,$new_title)
1151  {
1152  include_once './Modules/File/classes/class.ilObjFileAccess.php';
1153  $fileExtension = ilObjFileAccess::_getFileExtension($new_filename);
1154  $titleExtension = ilObjFileAccess::_getFileExtension($new_title);
1155  if ($titleExtension != $fileExtension && strlen($fileExtension) > 0)
1156  {
1157  // remove old extension
1158  $pi = pathinfo($this->getFileName());
1159  $suffix = $pi["extension"];
1160  if ($suffix != "")
1161  {
1162  if (substr($new_title,
1163  strlen($new_title) - strlen($suffix) - 1)
1164  == ".".$suffix)
1165  {
1166  $new_title = substr($new_title, 0, strlen($new_title) - strlen($suffix) - 1);
1167  }
1168  }
1169  $new_title .= '.'.$fileExtension;
1170  }
1171  return $new_title;
1172  }
1173 
1180  public function getVersions($version_ids = null)
1181  {
1182  include_once("./Services/History/classes/class.ilHistory.php");
1183  $versions = ilHistory::_getEntriesForObject($this->getId(), $this->getType());
1184 
1185  if ($version_ids != null && count($version_ids) > 0)
1186  {
1187  foreach ($versions as $index => $version)
1188  {
1189  if (!in_array($version["hist_entry_id"], $version_ids, true))
1190  {
1191  unset($versions[$index]);
1192  }
1193  }
1194  }
1195 
1196  // add custom entries
1197  foreach ($versions as $index => $version)
1198  {
1199  $params = $this->parseInfoParams($version);
1200  $versions[$index] = array_merge($version, $params);
1201  }
1202 
1203  // sort by version number (hist_entry_id will do for that)
1204  usort($versions, array($this, "compareVersions"));
1205 
1206  return $versions;
1207  }
1208 
1215  public function getSpecificVersion($version_id)
1216  {
1217  include_once("./Services/History/classes/class.ilHistory.php");
1218  $version = ilHistory::_getEntryByHistoryID($version_id);
1219  if ($version === false)
1220  return false;
1221 
1222  // ilHistory returns different keys in _getEntryByHistoryID and _getEntriesForObject
1223  // so this makes it the same
1224  $version["hist_entry_id"] = $version["id"];
1225  $version["user_id"] = $version["usr_id"];
1226  $version["date"] = $version["hdate"];
1227  unset($version["id"], $version["usr_id"], $version["hdate"]);
1228 
1229  // parse params
1230  $params = $this->parseInfoParams($version);
1231  return array_merge($version, $params);
1232  }
1233 
1240  public function rollback($version_id)
1241  {
1242  global $ilDB, $ilUser;
1243 
1244  $source = $this->getSpecificVersion($version_id);
1245  if ($source === false)
1246  {
1247  $this->ilErr->raiseError($this->lng->txt("obj_not_found"), $this->ilErr->MESSAGE);
1248  }
1249 
1250  // get the new version number
1251  $new_version_nr = $this->getVersion() + 1;
1252 
1253  // copy file
1254  $source_path = $this->getDirectory($source["version"]) . "/" . $source["filename"];
1255  $dest_dir = $this->getDirectory($new_version_nr);
1256  if (@!is_dir($dest_dir))
1257  ilUtil::makeDir($dest_dir);
1258 
1259  copy($source_path, $dest_dir . "/" . $source["filename"]);
1260 
1261  // create new history entry based on the old one
1262  include_once("./Services/History/classes/class.ilHistory.php");
1264  $this->getId(),
1265  "rollback",
1266  $source["filename"] . "," . $new_version_nr . "|" . $source["version"] . "|" . $ilUser->getId());
1267 
1268  // get id of newest entry
1269  $new_version = $this->getSpecificVersion($ilDB->getLastInsertId());
1270 
1271  // change user back to the original uploader
1272  ilHistory::_changeUserId($new_version["hist_entry_id"], $source["user_id"]);
1273 
1274  // update this file with the new version
1275  $this->updateWithVersion($new_version);
1276 
1277  $this->addNewsNotification("file_updated");
1278 
1279  return $new_version;
1280  }
1281 
1287  protected function updateWithVersion($version)
1288  {
1289  // update title (checkFileExtension must be called before setFileName!)
1290  $this->setTitle($this->checkFileExtension($version["filename"], $this->getTitle()));
1291 
1292  $this->setVersion($version["version"]);
1293  $this->setFileName($version["filename"]);
1294 
1295  // evaluate mime type (reset file type before)
1296  $this->setFileType("");
1297  $this->setFileType($this->guessFileType($version["filename"]));
1298 
1299  // set filesize
1300  $this->determineFileSize();
1301 
1302  $this->update();
1303 
1304  // refresh preview
1305  $this->createPreview(true);
1306  }
1307 
1315  function compareVersions($v1, $v2)
1316  {
1317  // v2 - v1 because version should be descending
1318  return (int)$v2["version"] - (int)$v1["version"];
1319  }
1320 
1327  function parseInfoParams($entry)
1328  {
1329  $data = preg_split("/(.*),(.*)/", $entry["info_params"], 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
1330 
1331  // bugfix: first created file had no version number
1332  // this is a workaround for all files created before the bug was fixed
1333  if (empty($data[1]))
1334  $data[1] = "1";
1335 
1336  $result = array("filename" => $data[0], "version" => $data[1], "rollback_version" => "", "rollback_user_id" => "");
1337 
1338  // if rollback, the version contains the rollback version as well
1339  if ($entry["action"] == "rollback")
1340  {
1341  $tokens = explode("|", $result["version"]);
1342  if (count($tokens) > 1)
1343  {
1344  $result["version"] = $tokens[0];
1345  $result["rollback_version"] = $tokens[1];
1346 
1347  if (count($tokens) > 2)
1348  $result["rollback_user_id"] = $tokens[2];
1349  }
1350  }
1351 
1352  return $result;
1353  }
1354 
1355  protected static function handleQuotaUpdate(ilObjFile $a_file)
1356  {
1357  include_once "Services/MediaObjects/classes/class.ilObjMediaObject.php";
1358  $mob = new ilObjMediaObject();
1359 
1360  // file itself could be workspace item
1361  $parent_obj_ids = array($a_file->getId());
1362 
1363  foreach($a_file->getUsages() as $item)
1364  {
1365  $parent_obj_id = $mob->getParentObjectIdForUsage($item);
1366  if($parent_obj_id &&
1367  !in_array($parent_obj_id, $parent_obj_ids))
1368  {
1369  $parent_obj_ids[]= $parent_obj_id;
1370  }
1371  }
1372 
1373  include_once "Services/DiskQuota/classes/class.ilDiskQuotaHandler.php";
1375  $a_file->getId(),
1376  $a_file->getDiskUsage(),
1377  $parent_obj_ids);
1378  }
1379 
1385  protected function createPreview($force = false)
1386  {
1387  // only normal files are supported
1388  if ($this->getMode() != "object")
1389  return;
1390 
1391  require_once("./Services/Preview/classes/class.ilPreview.php");
1392  ilPreview::createPreview($this, $force);
1393  }
1394 
1398  protected function deletePreview()
1399  {
1400  // only normal files are supported
1401  if ($this->getMode() != "object")
1402  return;
1403 
1404  require_once("./Services/Preview/classes/class.ilPreview.php");
1405  ilPreview::deletePreview($this->getId());
1406  }
1407 
1408  public function setRating($a_value)
1409  {
1410  $this->rating = (bool)$a_value;
1411  }
1412 
1413  public function hasRating()
1414  {
1415  return $this->rating;
1416  }
1417 
1418 } // END class.ilObjFile
1419 ?>
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static _writeFileType($a_id, $a_format)
setFileType($a_type)
print $file
createProperties($a_upload=false)
The basic properties of a file object are stored in table object_data.
static _removeEntryByHistoryID($a_hist_entry_id)
Removes a single entry from the history.
static _isFileInline($a_file_name)
Returns true, if the specified file shall be displayed inline in the browser.
parseInfoParams($entry)
Parses the info parameters ("info_params") of the specified history entry.
static _write($a_type, $a_setting, $a_value, $a_user=0, $a_block_id=0)
Write setting to database.
const NEWS_USERS
setFileName($a_name)
set filename
static _changeUserId($a_hist_entry_id, $new_user_id)
Changes the user id of the specified history entry.
$result
setMode($a_mode)
mode is object or filelist
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
$_GET["client_id"]
copy($a_source, $a_destination)
copy file
static _isFileHidden($a_file_name)
Returns true, if a file with the specified name, is usually hidden from the user. ...
static _getFileExtension($a_file_name)
Gets the file extension of the specified file name.
clearDataDirectory()
clear data directory
compareVersions($v1, $v2)
Compares two file versions.
getFile($a_hist_entry_id=null)
getMode()
mode is object or filelist
storeUnzipedFile($a_upload_file, $a_filename)
storeUnzipedFile
_lookupVersion($a_id)
lookup version
static _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
static delete all usages of
setVersion($a_version)
doCreateMetaData()
create file object meta data
getDirectory($a_version=0)
setFileSize($a_size)
setNoMetaDataCreation($a_status)
doCreate($a_upload=false)
create object
const DB_FETCHMODE_OBJECT
Definition: class.ilDB.php:11
beforeMDUpdateListener($a_element)
checkFileExtension($new_filename, $new_title)
Check if the file extension does still exist after an update of the title.
static _lookupFileSize($a_id)
Quickly looks up the file size from the database and returns the number of bytes. ...
doUpdateMetaData()
update meta data
static rename($a_source, $a_target)
Rename a file.
replaceFile($a_upload_file, $a_filename)
replace file with new file
static getMimeType($a_file='', $a_filename='', $a_mime='')
doRead()
read file properties
$r
Definition: example_031.php:79
_createEntry($a_obj_id, $a_action, $a_info_params="", $a_obj_type="", $a_user_comment="", $a_update_last=false)
Creates a new history entry for an object.
$data
static _lookupFileName($a_id)
static getBytesForString($a_str)
Return string as byte array Note: Use this for debugging purposes only.
addFileVersion($a_upload_file, $a_filename)
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
const NEWS_NOTICE
Class ilObjFile.
static createPreview($a_obj, $a_force=false)
Creates the preview for the object with the specified id.
deletePreview()
Deletes the preview of the file object.
isHidden()
Returns true, if this file should be hidden in the repository view.
redirection script todo: (a better solution should control the processing via a xml file) ...
initType()
Init type.
Class ilObjMediaObject.
setTitle($a_title)
static _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
save usage
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
isInline()
Returns true, if this file should be displayed inline in a browser window.
createPreview($force=false)
Creates a preview for the file object.
getSpecificVersion($version_id)
Gets a specific file version.
static deliverFile($a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
_copyEntriesForObject($a_src_id, $a_dst_id)
copy all history entries for an object
_getEntryByHistoryID($a_hist_entry_id)
returns a single history entry
addNewsNotification($a_lang_var)
getUsages()
get all usages of file object
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
doCloneObject($a_new_obj, $a_target_id, $a_copy_id=0)
Clone.
doUpdate()
update file
static copyPreviews($a_src_id, $a_dest_id)
Copies the preview images from one preview to a new preview object.
deleteVersions($a_hist_entry_ids=null)
Deletes the specified history entries or all entries if no ids are specified.
static _lookupFileSize($a_id)
Lookups the file size of the file in bytes.
getFileExtension()
Returns the extension of the file name converted to lower-case.
static handleQuotaUpdate(ilObjFile $a_file)
rollback($version_id)
Makes the specified version the current one and returns theSummary of rollbackVersion.
global $ilUser
Definition: imgupload.php:15
export($a_target_dir)
export files of object to target directory note: target directory must be the export target directory...
static _lookupVersion($a_id)
lookup version
static escapeShellArg($a_arg)
initFileStorage()
init file storage object
static handleUpdatedSourceObject($a_src_obj_type, $a_src_obj_id, $a_src_filesize, $a_owner_obj_ids=null, $a_is_prtf=false)
Find and update/create all related entries for source object.
$path
Definition: index.php:22
static deletePreview($a_obj_id)
Deletes the preview for the object with the specified id.
getUploadFile($a_upload_file, $a_filename, $a_prevent_preview=false, $handle_secure_name=true)
global $ilDB
static _lookupAbsolutePath($obj_id, $a_version=null)
return absolute path for version
static _getDefaultVisibilityForRefId($a_ref_id)
Get default visibility for reference id.
_getEntriesForObject($a_obj_id, $a_obj_type="")
get all history entries for an object
Class ilObject2 This is an intermediate progress of ilObject class.
_lookupDiskUsage($a_id)
Returns the number of bytes used on the harddisk by the file object with the specified object id...
static getLogger($a_component_id)
Get component logger.
raiseUploadError($a_raise=true)
_removeEntriesForObject($a_obj_id)
remove all history entries for an object
doMDUpdateListener($a_element)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
determineFileSize($a_hist_entry_id=null)
Determine File Size.
__construct($a_id=0, $a_call_by_reference=true)
ilObjFile constructor.
getVersions($version_ids=null)
Gets the file versions for this object.
$params
Definition: example_049.php:96
setRating($a_value)
static getValidFilename($a_filename)
Get valid filename.
guessFileType($a_file="")
Guesses the file type based on the current values returned by getFileType() and getFileExtension().
updateWithVersion($version)
Updates the file object with the specified file version.
cloneMetaData($target_obj)
getDiskUsage()
Gets the disk usage of the object in bytes.