ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  //if no title for the file was set use the filename as title
244  if(empty($this->getTitle())) {
245  $this->setTitle($a_filename);
246  }
247  $this->update();
248  }
249  if($this->version) {
250  $this->setVersion($this->getVersion() + 1);
251  }
252 
253  if (@!is_dir($this->getDirectory($this->getVersion())))
254  {
256  }
257 
258  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
259  ilUtil::moveUploadedFile($a_upload_file, $a_filename, $file, $this->raise_upload_error);
260 
261  $this->handleQuotaUpdate($this);
262 
263  // create preview?
264  if (!$a_prevent_preview)
265  {
266  $this->createPreview(false);
267  }
268  }
269 
273  function replaceFile($a_upload_file, $a_filename)
274  {
275  $this->getUploadFile($a_upload_file, $a_filename, true);
276 
277  require_once("./Services/History/classes/class.ilHistory.php");
279  $this->getId(),
280  "replace",
281  $a_filename.",".$this->getVersion()
282  );
283  $this->setFilename($a_filename);
284  $this->addNewsNotification("file_updated");
285 
286  // create preview
287  $this->createPreview(true);
288  }
289 
290 
291  public function addFileVersion($a_upload_file,$a_filename)
292  {
293  $this->getUploadFile($a_upload_file, $a_filename, true);
294 
295  require_once("./Services/History/classes/class.ilHistory.php");
297  $this->getId(),
298  "new_version",
299  $a_filename.",".$this->getVersion()
300  );
301  $this->setFilename($a_filename);
302  $this->addNewsNotification("file_updated");
303 
304  // create preview
305  $this->createPreview($this->getVersion() > 1);
306  }
307 
308 
312  function copy($a_source,$a_destination)
313  {
314  return copy($a_source,$this->getDirectory()."/".$a_destination);
315  }
316 
321  {
322  ilUtil::delDir($this->getDirectory());
323  $this->createDirectory();
324  }
325 
331  public function deleteVersions($a_hist_entry_ids = null)
332  {
333  global $ilDB;
334 
335  require_once("./Services/History/classes/class.ilHistory.php");
336 
337  if ($a_hist_entry_ids == null || count($a_hist_entry_ids) < 1)
338  {
339  $ilDB->manipulate("UPDATE file_data SET version = 1 WHERE file_id = ".$ilDB->quote($this->getId() ,'integer'));
340  $this->setVersion(0);
341  $this->clearDataDirectory();
342 
344 
345  self::handleQuotaUpdate($this);
346  }
347  else
348  {
349  $actualVersionDeleted = false;
350 
351  // get all versions
352  $versions = $this->getVersions();
353 
354  // delete each version
355  foreach ($a_hist_entry_ids as $hist_id)
356  {
357  $entry = null;
358 
359  // get version
360  foreach ($versions as $index => $version)
361  {
362  if ($version["hist_entry_id"] == $hist_id)
363  {
364  // remove each history entry
366 
367  // delete directory
368  $version_dir = $this->getDirectory($version["version"]);
369  ilUtil::delDir($version_dir);
370 
371  // is actual version?
372  if ($version["version"] == $this->getVersion())
373  $actualVersionDeleted = true;
374 
375  // remove from array
376  unset($versions[$index]);
377  break;
378  }
379  }
380  }
381 
382  // update actual version if it was deleted before
383  if ($actualVersionDeleted)
384  {
385  // get newest version (already sorted by getVersions)
386  $version = reset($versions);
387  $this->updateWithVersion($version);
388  }
389  else
390  {
391  // updateWithVersion() will trigger quota, too
392  self::handleQuotaUpdate($this);
393  }
394  }
395  }
396 
400  protected function doRead()
401  {
402  global $ilDB;
403 
404  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
405  $r = $this->ilias->db->query($q);
407 
408  $this->setFileName($row->file_name);
409  $this->setFileType($row->file_type);
410  $this->setFileSize($row->file_size);
411  $this->setVersion($row->version);
412  $this->setMode($row->f_mode);
413  $this->setRating($row->rating);
414 
415  $this->initFileStorage();
416  }
417 
418  protected function beforeUpdate()
419  {
420  // no meta data handling for file list files
421  if ($this->getMode() != "filelist")
422  {
423  $this->updateMetaData();
424  }
425 
426  return true;
427  }
428 
432  protected function doUpdate()
433  {
434  global $ilDB, $ilLog;
435 
436  //$ilLog->write(__METHOD__.' File type: '.$this->getFileType());
437 
438  $q = "UPDATE file_data SET file_name = ".$ilDB->quote($this->getFileName() ,'text').
439  ", file_type = ".$ilDB->quote($this->getFiletype() ,'text')." ".
440  ", file_size = ".$ilDB->quote((int) $this->getFileSize() ,'integer')." ".
441  ", version = ".$ilDB->quote($this->getVersion() ,'integer')." ".
442  ", f_mode = ".$ilDB->quote($this->getMode() ,'text')." ".
443  ", rating = ".$ilDB->quote($this->hasRating() ,'integer')." ".
444  "WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
445  $res = $ilDB->manipulate($q);
446 
447  self::handleQuotaUpdate($this);
448 
449  return true;
450  }
451 
455  protected function doUpdateMetaData()
456  {
457  // add technical section with file size and format
458  $md_obj = new ilMD($this->getId(),0,$this->getType());
459  if(!is_object($technical = $md_obj->getTechnical()))
460  {
461  $technical = $md_obj->addTechnical();
462  $technical->save();
463  }
464  $technical->setSize($this->getFileSize());
465 
466  $format_ids = $technical->getFormatIds();
467  if (count($format_ids) > 0)
468  {
469  $format = $technical->getFormat($format_ids[0]);
470  $format->setFormat($this->getFileType());
471  $format->update();
472  }
473  else
474  {
475  $format = $technical->addFormat();
476  $format->setFormat($this->getFileType());
477  $format->save();
478  }
479  $technical->update();
480  }
481 
485  function setFileName($a_name)
486  {
487  $this->filename = $a_name;
488  }
489 
490  function getFileName()
491  {
492  return $this->filename;
493  }
494 
496  {
497  global $ilLog;
498 
499 
500  $this->filetype = $a_type;
501  }
502 
503  function getFileType()
504  {
505  return $this->filetype;
506  }
507 
508  function setFileSize($a_size)
509  {
510  $this->filesize = $a_size;
511  }
512 
513  function getFileSize()
514  {
515  return $this->filesize;
516  }
523  function getDiskUsage()
524  {
525  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
526  return ilObjFileAccess::_lookupDiskUsage($this->id);
527  }
528 
529 
530  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
531  function getFile($a_hist_entry_id = null)
532  {
533  if (is_null($a_hist_entry_id))
534  {
535  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
536  }
537  else
538  {
539  require_once("./Services/History/classes/class.ilHistory.php");
540  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
541 
542  if ($entry === false)
543  {
544  return false;
545  }
546 
547  $data = $this->parseInfoParams($entry);
548  $file = $this->getDirectory($data["version"])."/".$data["filename"];
549  }
550  return $file;
551  }
552  // END PATCH WebDAV Encapsulate file access in ilObjFile class.
553 
554  function setVersion($a_version)
555  {
556  $this->version = $a_version;
557  }
558 
559  function getVersion()
560  {
561  return $this->version ? $this->version : 1;
562  }
563 
569  function setMode($a_mode)
570  {
571  $this->mode = $a_mode;
572  }
573 
579  function getMode()
580  {
581  return $this->mode;
582  }
583 
584  static function _writeFileType($a_id ,$a_format)
585  {
586  global $ilDB;
587 
588  $q = "UPDATE file_data SET ".
589  " file_type = ".$ilDB->quote($a_format ,'text').
590  " WHERE file_id = ".$ilDB->quote($a_id ,'integer');
591  $res = $ilDB->manipulate($q);
592 
593  }
594 
595  static function _lookupFileName($a_id)
596  {
597  global $ilDB;
598 
599  $q = "SELECT * FROM file_data WHERE file_id = ".$ilDB->quote($a_id ,'integer');
600  $r = $ilDB->query($q);
602 
603  return ilUtil::stripSlashes($row->file_name);
604  }
605 
606 
608  static function _lookupFileSize($a_id)
609  {
610  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
611  return ilObjFileAccess::_lookupFileSize($a_id);
612  }
613 
617  static function _lookupVersion($a_id)
618  {
619  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
620  return ilObjFileAccess::_lookupVersion($a_id);
621  }
622 
626  function determineFileSize($a_hist_entry_id = null)
627  {
628  if (is_null($a_hist_entry_id))
629  {
630  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
631  }
632  else
633  {
634  require_once("./Services/History/classes/class.ilHistory.php");
635  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
636 
637  if ($entry === false)
638  {
639  return false;
640  }
641 
642  $data = $this->parseInfoParams($entry);
643  $file = $this->getDirectory($data["version"])."/".$data["filename"];
644  }
645  if (is_file($file))
646  {
647  $this->setFileSize(filesize($file));
648  }
649  }
650 
651  function sendFile($a_hist_entry_id = null)
652  {
653  if (is_null($a_hist_entry_id))
654  {
655  $file = $this->getDirectory($this->getVersion())."/".$this->getFileName();
656 
657  // if not found lookup for file in file object's main directory for downward c ompability
658  if (@!is_file($file))
659  {
660  $file = $this->getDirectory()."/".$this->getFileName();
661  }
662  }
663  else
664  {
665  require_once("./Services/History/classes/class.ilHistory.php");
666  $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
667 
668  if ($entry === false)
669  {
670  echo "3";return false;
671  }
672 
673  $data = $this->parseInfoParams($entry);
674  $file = $this->getDirectory($data["version"])."/".$data["filename"];
675 
676  // if not found lookup for file in file object's main directory for downward compability
677  if (@!is_file($file))
678  {
679  $file = $this->getDirectory()."/".$data[0];
680  }
681 
682  // BEGIN WebDAV removed duplicated code
683  // END WebDAV removed duplicated code
684  }
685 
686  if (@is_file($file))
687  {
688  global $ilClientIniFile;
692  require_once('./Services/FileDelivery/classes/class.ilFileDelivery.php');
693 
694  $ilFileDelivery = new ilFileDelivery($file);
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  } else {
703  // $download_file_name = basename($file);
704  /* FSX Info: basename has a Bug with Japanese and other characters, see:
705  * http://stackoverflow.com/questions/32115609/basename-fail-when-file-name-start-by-an-accent
706  * Therefore we can no longer use basename();
707  */
708  $parts = explode(DIRECTORY_SEPARATOR, $file);
709  $download_file_name = end($parts);
710  $ilFileDelivery->setDownloadFileName($download_file_name);
711  }
712  $ilFileDelivery->deliver();
713 
714  return true;
715  }
716 
717  return false;
718  }
719 
720  // BEGIN WebDAV: Get file extension, determine if file is inline, guess file type.
725  function getFileExtension() {
726  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
728  }
734  function isInline() {
735  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
736  return ilObjFileAccess::_isFileInline($this->getTitle());
737  }
741  function isHidden() {
742  require_once 'Modules/File/classes/class.ilObjFileAccess.php';
743  return ilObjFileAccess::_isFileHidden($this->getTitle());
744  }
745  // END WebDAV: Get file extension, determine if file is inline, guess file type.
746 
753  function guessFileType($a_file = "") {
754 
755  $path = pathinfo($a_file);
756  if ($path["extension"] != "")
757  {
758  $filename = $path["basename"];
759  }
760  else
761  {
762  $filename = "dummy.".$this->getFileExtension();
763  }
764  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
765  $mime = ilMimeTypeUtil::getMimeType($a_file, $filename, $this->getFileType());
766  return $mime;
767 
768 /*
769  $fileType = $this->getFileType();
770  if (strlen($fileType) == 0) {
771  $fileType = 'application/octet-stream';
772  }
773 
774  // Firefox browser assigns 'application/x-pdf' to PDF files, but
775  // it can only handle them if the have the mime-type 'application/pdf'.
776  if ($fileType == 'application/x-pdf')
777  {
778  $fileType = 'application/pdf';
779  }
780 
781  if ($fileType == 'application/octet-stream')
782  {
783  $fileExtension = $this->getFileExtension();
784  $mimeArray = array(
785  'mpeg' => 'video/mpeg',
786  'mp3' => 'audio/mpeg',
787  'pdf' => 'application/pdf',
788  'gif' => 'image/gif',
789  'jpg' => 'image/jpg',
790  'png' => 'image/png',
791  'htm' => 'text/html',
792  'html' => 'text/html',
793  'wma' => 'video/x-ms-wma',
794  'wmv' => 'video/x-ms-wmv',
795  'swf' => 'application/x-shockwave-flash',
796  );
797  if (array_key_exists($fileExtension, $mimeArray))
798  {
799  $fileType = $mimeArray[$fileExtension];
800  }
801  }
802  return $fileType;
803 */
804  }
805 
815  protected function doCloneObject($a_new_obj,$a_target_id,$a_copy_id = 0)
816  {
817  global $ilDB;
818 
819  $a_new_obj->createDirectory();
820  $this->cloneMetaData($a_new_obj);
821 
822  // Copy all file versions
823  ilUtil::rCopy($this->getDirectory(),$a_new_obj->getDirectory());
824 
825  // object created now copy other settings
826  $query = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,rating,f_mode) VALUES (".
827  $ilDB->quote($a_new_obj->getId() ,'integer').",".
828  $ilDB->quote($this->getFileName() ,'text').",".
829  $ilDB->quote($this->getFileType() ,'text').",".
830  $ilDB->quote((int) $this->getFileSize() ,'integer').", ".
831  $ilDB->quote($this->getVersion() ,'integer').", ".
832  $ilDB->quote($this->hasRating() ,'integer').", ".
833  $ilDB->quote($this->getMode() ,'text').")";
834  $res = $ilDB->manipulate($query);
835 
836  // copy all previews
837  require_once("./Services/Preview/classes/class.ilPreview.php");
838  ilPreview::copyPreviews($this->getId(), $a_new_obj->getId());
839 
840  // copy history entries
841  require_once("./Services/History/classes/class.ilHistory.php");
842  ilHistory::_copyEntriesForObject($this->getId(),$a_new_obj->getId());
843 
844  // Copy learning progress settings
845  include_once('Services/Tracking/classes/class.ilLPObjSettings.php');
846  $obj_settings = new ilLPObjSettings($this->getId());
847  $obj_settings->cloneSettings($a_new_obj->getId());
848  unset($obj_settings);
849 
850  // add news notification
851  $a_new_obj->addNewsNotification("file_created");
852 
853  return $a_new_obj;
854  }
855 
856  protected function beforeDelete()
857  {
858  global $ilDB;
859 
860  // check, if file is used somewhere
861  $usages = $this->getUsages();
862  if (count($usages) == 0)
863  {
864  return true;
865  }
866  return false;
867  }
868 
869  protected function doDelete()
870  {
871  global $ilDB;
872 
873  // delete file data entry
874  $q = "DELETE FROM file_data WHERE file_id = ".$ilDB->quote($this->getId() ,'integer');
875  $this->ilias->db->query($q);
876 
877  // delete history entries
878  require_once("./Services/History/classes/class.ilHistory.php");
880 
881  // delete entire directory and its content
882  if (@is_dir($this->getDirectory()))
883  {
884  ilUtil::delDir($this->getDirectory());
885  }
886 
887  // delete meta data
888  if ($this->getMode() != "filelist")
889  {
890  $this->deleteMetaData();
891  }
892 
893  self::handleQuotaUpdate($this);
894 
895  // delete preview
896  $this->deletePreview();
897  }
898 
906  function export($a_target_dir)
907  {
908  $subdir = "il_".IL_INST_ID."_file_".$this->getId();
909  ilUtil::makeDir($a_target_dir."/objects/".$subdir);
910 
911  $filedir = $this->getDirectory($this->getVersion());
912 
913  if (@!is_dir($filedir))
914  {
915  $filedir = $this->getDirectory();
916  }
917 
918  ilUtil::rCopy($filedir, $a_target_dir."/objects/".$subdir);
919  }
920 
924  static function _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
925  {
926  global $ilDB;
927 
928  $and_hist = ($a_usage_hist_nr !== false)
929  ? " AND usage_hist_nr = ".$ilDB->quote($a_usage_hist_nr, "integer")
930  : "";
931 
932  $file_ids = array();
933  $set = $ilDB->query("SELECT id FROM file_usage".
934  " WHERE usage_type = ".$ilDB->quote($a_type, "text").
935  " AND usage_id= ".$ilDB->quote($a_id, "integer").
936  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
937  $and_hist);
938  while($row = $ilDB->fetchAssoc($set))
939  {
940  $file_ids[] = $row["id"];
941  }
942 
943  $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = ".
944  $ilDB->quote($a_type, "text").
945  " AND usage_id = ".$ilDB->quote((int) $a_id, "integer").
946  " AND usage_lang= ".$ilDB->quote($a_usage_lang, "text").
947  " AND usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer"));
948 
949  foreach($file_ids as $file_id)
950  {
951  self::handleQuotaUpdate(new self($file_id, false));
952  }
953  }
954 
958  static function _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
959  {
960  global $ilDB;
961 
962  // check if file really exists
963  if (ilObject::_lookupType($a_file_id) != "file")
964  {
965  return;
966  }
967  // #15143
968  $ilDB->replace("file_usage",
969  array(
970  "id" => array("integer", (int) $a_file_id),
971  "usage_type" => array("text", (string) $a_type),
972  "usage_id" => array("integer", (int) $a_id),
973  "usage_hist_nr" => array("integer", (int) $a_usage_hist_nr),
974  "usage_lang" => array("text", $a_usage_lang)
975  ),
976  array()
977  );
978 
979  self::handleQuotaUpdate(new self($a_file_id, false));
980  }
981 
985  function getUsages()
986  {
987  global $ilDB;
988 
989  // get usages in learning modules
990  $q = "SELECT * FROM file_usage WHERE id = ".$ilDB->quote($this->getId(), "integer");
991  $us_set = $ilDB->query($q);
992  $ret = array();
993  while($us_rec = $ilDB->fetchAssoc($us_set))
994  {
995  $ret[] = array("type" => $us_rec["usage_type"],
996  "id" => $us_rec["usage_id"],
997  "lang" => $us_rec["usage_lang"],
998  "hist_nr" => $us_rec["usage_hist_nr"]);
999  }
1000 
1001  return $ret;
1002  }
1003 
1012  static function _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
1013  {
1014  global $ilDB;
1015 
1016  $lstr = "";
1017  if ($a_usage_lang != "")
1018  {
1019  $lstr = "usage_lang = ".$ilDB->quote((string) $a_usage_lang, "text")." AND ";
1020  }
1021 
1022  // get usages in learning modules
1023  $q = "SELECT * FROM file_usage WHERE ".
1024  "usage_id = ".$ilDB->quote((int) $a_id, "integer")." AND ".
1025  "usage_type = ".$ilDB->quote((string) $a_type, "text")." AND ".
1026  $lstr.
1027  "usage_hist_nr = ".$ilDB->quote((int) $a_usage_hist_nr, "integer");
1028  $file_set = $ilDB->query($q);
1029  $ret = array();
1030  while($file_rec = $ilDB->fetchAssoc($file_set))
1031  {
1032  $ret[$file_rec["id"]] = $file_rec["id"];
1033  }
1034 
1035  return $ret;
1036  }
1037 
1038  // TODO: What is this function good for??
1039  function getXMLZip()
1040  {
1041  global $ilias;
1042 
1043  $zip = PATH_TO_ZIP;
1044 
1045  exec($zip.' '.ilUtil::escapeShellArg($this->getDirectory().'/'.$this->getFileName())." ".
1046  ilUtil::escapeShellArg($this->getDirectory().'/'.'1.zip'));
1047 
1048  return $this->getDirectory().'/1.zip';
1049  }
1050 
1051  function addNewsNotification($a_lang_var)
1052  {
1053  // BEGIN WebDAV Suppress news notification for hidden files
1054  if ($this->isHidden()) {
1055  return;
1056  }
1057  // END WebDAV Suppress news notification for hidden files
1058 
1059  global $ilUser;
1060 
1061  // Add Notification to news
1062  include_once("./Services/News/classes/class.ilNewsItem.php");
1063  include_once("./Modules/File/classes/class.ilObjFileAccess.php");
1064  $news_item = new ilNewsItem();
1065  $news_item->setContext($this->getId(), $this->getType());
1066  $news_item->setPriority(NEWS_NOTICE);
1067  $news_item->setTitle($a_lang_var);
1068  $news_item->setContentIsLangVar(true);
1069  if ($this->getDescription() != "")
1070  {
1071  $news_item->setContent(
1072  "<p>".
1073  $this->getDescription()."</p>");
1074  }
1075  $news_item->setUserId($ilUser->getId());
1076  $news_item->setVisibility(NEWS_USERS);
1077  $news_item->create();
1078  }
1079 
1086  public function initFileStorage()
1087  {
1088  $this->file_storage = new ilFSStorageFile($this->getId());
1089  return true;
1090  }
1100  function storeUnzipedFile($a_upload_file, $a_filename)
1101  {
1102  if($this->version) {
1103  $this->setVersion($this->version + 1);
1104  }
1105 
1106  if (@!is_dir($this->getDirectory($this->getVersion())))
1107  {
1108  ilUtil::makeDir($this->getDirectory($this->getVersion()));
1109  }
1110 
1111  $file = $this->getDirectory($this->getVersion())."/".$a_filename;
1112  require_once('./Services/Utilities/classes/class.ilFileUtils.php');
1113  ilFileUtils::rename($a_upload_file, $file);
1114 
1115  // create preview
1116  $this->createPreview();
1117  }
1118 
1123  public static function _lookupAbsolutePath ($obj_id, $a_version = null)
1124  {
1125  $file_storage = new ilFSStorageFile($obj_id);
1126  $filename = ilObjFile::_lookupFileName($obj_id);
1127  $version_subdir = "";
1128 
1129  if (!is_numeric($a_version))
1130  {
1131  $a_version = ilObjFile::_lookupVersion ($obj_id);
1132  }
1133  $version_subdir = DIRECTORY_SEPARATOR.sprintf("%03d", $a_version);
1134  return $file_storage->getAbsolutePath().$version_subdir.DIRECTORY_SEPARATOR.$filename;
1135  }
1136 
1141  public function checkFileExtension($new_filename,$new_title)
1142  {
1143  include_once './Modules/File/classes/class.ilObjFileAccess.php';
1144  $fileExtension = ilObjFileAccess::_getFileExtension($new_filename);
1145  $titleExtension = ilObjFileAccess::_getFileExtension($new_title);
1146  if ($titleExtension != $fileExtension && strlen($fileExtension) > 0)
1147  {
1148  // remove old extension
1149  $pi = pathinfo($this->getFileName());
1150  $suffix = $pi["extension"];
1151  if ($suffix != "")
1152  {
1153  if (substr($new_title,
1154  strlen($new_title) - strlen($suffix) - 1)
1155  == ".".$suffix)
1156  {
1157  $new_title = substr($new_title, 0, strlen($new_title) - strlen($suffix) - 1);
1158  }
1159  }
1160  $new_title .= '.'.$fileExtension;
1161  }
1162  return $new_title;
1163  }
1164 
1171  public function getVersions($version_ids = null)
1172  {
1173  include_once("./Services/History/classes/class.ilHistory.php");
1174  $versions = ilHistory::_getEntriesForObject($this->getId(), $this->getType());
1175 
1176  if ($version_ids != null && count($version_ids) > 0)
1177  {
1178  foreach ($versions as $index => $version)
1179  {
1180  if (!in_array($version["hist_entry_id"], $version_ids, true))
1181  {
1182  unset($versions[$index]);
1183  }
1184  }
1185  }
1186 
1187  // add custom entries
1188  foreach ($versions as $index => $version)
1189  {
1190  $params = $this->parseInfoParams($version);
1191  $versions[$index] = array_merge($version, $params);
1192  }
1193 
1194  // sort by version number (hist_entry_id will do for that)
1195  usort($versions, array($this, "compareVersions"));
1196 
1197  return $versions;
1198  }
1199 
1206  public function getSpecificVersion($version_id)
1207  {
1208  include_once("./Services/History/classes/class.ilHistory.php");
1210  if ($version === false)
1211  return false;
1212 
1213  // ilHistory returns different keys in _getEntryByHistoryID and _getEntriesForObject
1214  // so this makes it the same
1215  $version["hist_entry_id"] = $version["id"];
1216  $version["user_id"] = $version["usr_id"];
1217  $version["date"] = $version["hdate"];
1218  unset($version["id"], $version["usr_id"], $version["hdate"]);
1219 
1220  // parse params
1221  $params = $this->parseInfoParams($version);
1222  return array_merge($version, $params);
1223  }
1224 
1231  public function rollback($version_id)
1232  {
1233  global $ilDB, $ilUser;
1234 
1235  $source = $this->getSpecificVersion($version_id);
1236  if ($source === false)
1237  {
1238  $this->ilErr->raiseError($this->lng->txt("obj_not_found"), $this->ilErr->MESSAGE);
1239  }
1240 
1241  // get the new version number
1242  $new_version_nr = $this->getVersion() + 1;
1243 
1244  // copy file
1245  $source_path = $this->getDirectory($source["version"]) . "/" . $source["filename"];
1246  $dest_dir = $this->getDirectory($new_version_nr);
1247  if (@!is_dir($dest_dir))
1248  ilUtil::makeDir($dest_dir);
1249 
1250  copy($source_path, $dest_dir . "/" . $source["filename"]);
1251 
1252  // create new history entry based on the old one
1253  include_once("./Services/History/classes/class.ilHistory.php");
1255  $this->getId(),
1256  "rollback",
1257  $source["filename"] . "," . $new_version_nr . "|" . $source["version"] . "|" . $ilUser->getId());
1258 
1259  // get id of newest entry
1260  $new_version = $this->getSpecificVersion($ilDB->getLastInsertId());
1261 
1262  // change user back to the original uploader
1263  ilHistory::_changeUserId($new_version["hist_entry_id"], $source["user_id"]);
1264 
1265  // update this file with the new version
1266  $this->updateWithVersion($new_version);
1267 
1268  $this->addNewsNotification("file_updated");
1269 
1270  return $new_version;
1271  }
1272 
1278  protected function updateWithVersion($version)
1279  {
1280  // update title (checkFileExtension must be called before setFileName!)
1281  $this->setTitle($this->checkFileExtension($version["filename"], $this->getTitle()));
1282 
1283  $this->setVersion($version["version"]);
1284  $this->setFileName($version["filename"]);
1285 
1286  // evaluate mime type (reset file type before)
1287  $this->setFileType("");
1288  $this->setFileType($this->guessFileType($version["filename"]));
1289 
1290  // set filesize
1291  $this->determineFileSize();
1292 
1293  $this->update();
1294 
1295  // refresh preview
1296  $this->createPreview(true);
1297  }
1298 
1306  function compareVersions($v1, $v2)
1307  {
1308  // v2 - v1 because version should be descending
1309  return (int)$v2["version"] - (int)$v1["version"];
1310  }
1311 
1318  function parseInfoParams($entry)
1319  {
1320  $data = preg_split("/(.*),(.*)/", $entry["info_params"], 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
1321 
1322  // bugfix: first created file had no version number
1323  // this is a workaround for all files created before the bug was fixed
1324  if (empty($data[1]))
1325  $data[1] = "1";
1326 
1327  $result = array("filename" => $data[0], "version" => $data[1], "rollback_version" => "", "rollback_user_id" => "");
1328 
1329  // if rollback, the version contains the rollback version as well
1330  if ($entry["action"] == "rollback")
1331  {
1332  $tokens = explode("|", $result["version"]);
1333  if (count($tokens) > 1)
1334  {
1335  $result["version"] = $tokens[0];
1336  $result["rollback_version"] = $tokens[1];
1337 
1338  if (count($tokens) > 2)
1339  $result["rollback_user_id"] = $tokens[2];
1340  }
1341  }
1342 
1343  return $result;
1344  }
1345 
1346  protected static function handleQuotaUpdate(ilObjFile $a_file)
1347  {
1348  include_once "Services/MediaObjects/classes/class.ilObjMediaObject.php";
1349  $mob = new ilObjMediaObject();
1350 
1351  // file itself could be workspace item
1352  $parent_obj_ids = array($a_file->getId());
1353 
1354  foreach($a_file->getUsages() as $item)
1355  {
1356  $parent_obj_id = $mob->getParentObjectIdForUsage($item);
1357  if($parent_obj_id &&
1358  !in_array($parent_obj_id, $parent_obj_ids))
1359  {
1360  $parent_obj_ids[]= $parent_obj_id;
1361  }
1362  }
1363 
1364  include_once "Services/DiskQuota/classes/class.ilDiskQuotaHandler.php";
1366  $a_file->getId(),
1367  $a_file->getDiskUsage(),
1368  $parent_obj_ids);
1369  }
1370 
1376  protected function createPreview($force = false)
1377  {
1378  // only normal files are supported
1379  if ($this->getMode() != "object")
1380  return;
1381 
1382  require_once("./Services/Preview/classes/class.ilPreview.php");
1383  ilPreview::createPreview($this, $force);
1384  }
1385 
1389  protected function deletePreview()
1390  {
1391  // only normal files are supported
1392  if ($this->getMode() != "object")
1393  return;
1394 
1395  require_once("./Services/Preview/classes/class.ilPreview.php");
1396  ilPreview::deletePreview($this->getId());
1397  }
1398 
1399  public function setRating($a_value)
1400  {
1401  $this->rating = (bool)$a_value;
1402  }
1403 
1404  public function hasRating()
1405  {
1406  return $this->rating;
1407  }
1408 
1409 } // END class.ilObjFile
1410 ?>
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static _writeFileType($a_id, $a_format)
setFileType($a_type)
$path
Definition: aliased.php:25
createProperties($a_upload=false)
The basic properties of a file object are stored in table object_data.
static _lookupDiskUsage($a_id)
Returns the number of bytes used on the harddisk by the file object with the specified object id...
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.
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
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
static _getEntryByHistoryID($a_hist_entry_id)
returns a single history entry
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='')
$a_type
Definition: workflow.php:93
doRead()
read file properties
$r
Definition: example_031.php:79
static _copyEntriesForObject($a_src_id, $a_dst_id)
copy all history entries for an object
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.
$ilUser
Definition: imgupload.php:18
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.
static _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.
createPreview($force=false)
Creates a preview for the file object.
getSpecificVersion($version_id)
Gets a specific file version.
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
static _getEntriesForObject($a_obj_id, $a_obj_type="")
get all history entries for an object
addNewsNotification($a_lang_var)
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
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.
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.
Class ilFileDelivery.
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
$ret
Definition: parser.php:6
static _getDefaultVisibilityForRefId($a_ref_id)
Get default visibility for reference id.
static _removeEntriesForObject($a_obj_id)
remove all history entries for an object
Class ilObject2 This is an intermediate progress of ilObject class.
static getLogger($a_component_id)
Get component logger.
raiseUploadError($a_raise=true)
const NEWS_USERS
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
doMDUpdateListener($a_element)
static _lookupVersion($a_id)
lookup version
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.