ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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
7
8require_once("Services/Object/classes/class.ilObject2.php");
9require_once('Modules/File/classes/class.ilFSStorageFile.php');
10
20class ilObjFile extends ilObject2
21{
22 const MODE_FILELIST = "filelist";
23 const MODE_OBJECT = "object";
31 protected $filename = '';
35 protected $filetype = '';
39 protected $filemaxsize = "20000000"; // not used yet
43 protected $filesize;
55 protected $page_count = 0;
59 protected $rating = false;
63 private $file_storage = null;
67 protected $log = null;
71 protected $version = 1;
72
73
80 public function __construct($a_id = 0, $a_call_by_reference = true)
81 {
82 $this->version = 0;
83 $this->raise_upload_error = true;
84
85 $this->log = ilLoggerFactory::getLogger('file');
86
87 parent::__construct($a_id, $a_call_by_reference);
88
89 if ($this->getId()) {
90 $this->initFileStorage();
91 }
92 }
93
94
95 public function initType()
96 {
97 $this->type = "file";
98 }
99
100
106 protected function doCreate($a_upload = false)
107 {
108 $this->createProperties($a_upload);
109 }
110
111
119 public function createProperties($a_upload = false)
120 {
121 global $DIC;
122
123 // Create file directory
124 $this->initFileStorage();
125 $this->file_storage->create();
126
127 if ($a_upload) {
128 return true;
129 }
130
131 // not upload mode
132 ilHistory::_createEntry($this->getId(), "create", $this->getFileName() . ",1");
133 $this->addNewsNotification("file_created");
134
135 // New Item
136 $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET['ref_id']);
137 if ($default_visibility == "public") {
138 ilBlockSetting::_write("news", "public_notifications", 1, 0, $this->getId());
139 }
140
141 // log creation
142 $this->log->debug("ilObjFile::createProperties, ID: " . $this->getId() . ", Name: "
143 . $this->getFileName() . ", Type: " . $this->getFileType() . ", Size: "
144 . $this->getFileSize() . ", Mode: " . $this->getMode() . ", Name(Bytes): "
145 . implode(":", ilStr::getBytesForString($this->getFileName())));
146 $this->log->logStack(ilLogLevel::DEBUG);
147
148 $DIC->database()->insert('file_data', $this->getArrayForDatabase());
149
150 // no meta data handling for file list files
151 if ($this->getMode() != self::MODE_FILELIST) {
152 $this->createMetaData();
153 }
154 }
155
156
160 public function setNoMetaDataCreation($a_status)
161 {
162 $this->no_meta_data_creation = (bool) $a_status;
163 }
164
165
166 protected function beforeCreateMetaData()
167 {
168 return !(bool) $this->no_meta_data_creation;
169 }
170
171
172 protected function beforeUpdateMetaData()
173 {
174 return !(bool) $this->no_meta_data_creation;
175 }
176
177
181 protected function doCreateMetaData()
182 {
183 // add technical section with file size and format
184 $md_obj = new ilMD($this->getId(), 0, $this->getType());
185 $technical = $md_obj->addTechnical();
186 $technical->setSize($this->getFileSize());
187 $technical->save();
188 $format = $technical->addFormat();
189 $format->setFormat($this->getFileType());
190 $format->save();
191 $technical->update();
192 }
193
194
195 protected function beforeMDUpdateListener($a_element)
196 {
197 // Check file extension
198 // Removing the file extension is not allowed
199 include_once 'Services/MetaData/classes/class.ilMD.php';
200 $md = new ilMD($this->getId(), 0, $this->getType());
201 if (!is_object($md_gen = $md->getGeneral())) {
202 return false;
203 }
204 $title = $this->checkFileExtension($this->getFileName(), $md_gen->getTitle());
205 $md_gen->setTitle($title);
206 $md_gen->update();
207
208 return true;
209 }
210
211
212 protected function doMDUpdateListener($a_element)
213 {
214 // handling for technical section
215 include_once 'Services/MetaData/classes/class.ilMD.php';
216
217 switch ($a_element) {
218 case 'Technical':
219
220 // Update Format (size is not stored in db)
221 $md = new ilMD($this->getId(), 0, $this->getType());
222 if (!is_object($md_technical = $md->getTechnical())) {
223 return false;
224 }
225
226 foreach ($md_technical->getFormatIds() as $id) {
227 $md_format = $md_technical->getFormat($id);
228 ilObjFile::_writeFileType($this->getId(), $md_format->getFormat());
229 $this->setFileType($md_format->getFormat());
230 break;
231 }
232
233 break;
234 }
235
236 return true;
237 }
238
239
245 public function getDirectory($a_version = 0)
246 {
247 $version_subdir = "";
248
249 if ($a_version) {
250 // BEGIN WebDAV Avoid double slash before version subdirectory
251 $version_subdir = sprintf("%03d", $a_version);
252 // END WebDAV Avoid double slash before version subdirectory
253 }
254
255 if (!is_object($this->file_storage)) {
256 $this->initFileStorage();
257 }
258
259 $str = $this->file_storage->getAbsolutePath() . '/' . $version_subdir;
260
261 return $str;
262 }
263
264
265 public function createDirectory()
266 {
268 }
269
270
271 public function raiseUploadError($a_raise = true)
272 {
273 $this->raise_upload_error = $a_raise;
274 }
275
276
286 public function getUploadFile($a_upload_file, $a_filename, $a_prevent_preview = false)
287 {
288 global $DIC;
289
290 $upload = $DIC->upload();
291 $result = null;
292
293 if ($upload->hasUploads()) {
294 if ($upload->hasBeenProcessed() !== true) {
295 if (PATH_TO_GHOSTSCRIPT !== "") {
296 $upload->register(new ilCountPDFPagesPreProcessors());
297 }
298 $upload->process();
299 }
303 $result = $upload->getResults()[$a_upload_file];
304 if ($result->getStatus()->getCode() === \ILIAS\FileUpload\DTO\ProcessingStatus::OK) {
305 $metadata = $result->getMetaData();
308 $this->doUpdate();
309 }
310 $a_name = $result->getName();
311 $this->setFileName($a_name);
312
313 $this->setVersion($this->getVersion() + 1);
314
315 if (!is_dir($this->getDirectory($this->getVersion()))) {
317 }
318
319 $target_directory = $this->getDirectory($this->getVersion()) . "/";
320 $relative_path_to_file = LegacyPathHelper::createRelativePath($target_directory);
321
322 $upload->moveOneFileTo($result, $relative_path_to_file, Location::STORAGE);
323
324 $this->handleQuotaUpdate($this);
325
326 // create preview?
327 if (!$a_prevent_preview) {
328 $this->createPreview(false);
329 }
330 } else {
331 throw new ilFileException('not supported File');
332 }
333 }
334
335 return $result;
336 }
337
338
346 public function replaceFile($a_upload_file, $a_filename)
347 {
348 if ($result = $this->getUploadFile($a_upload_file, $a_filename, true)) {
349 ilHistory::_createEntry($this->getId(), "replace", $a_filename . "," . $this->getVersion());
350 $this->addNewsNotification("file_updated");
351
352 // create preview
353 $this->createPreview(true);
354 }
355
356 return $result;
357 }
358
359
360 public function addFileVersion($a_upload_file, $a_filename)
361 {
362 if ($result = $this->getUploadFile($a_upload_file, $a_filename, true)) {
363 ilHistory::_createEntry($this->getId(), "new_version", $result->getName() . "," . $this->getVersion());
364 $this->addNewsNotification("file_updated");
365
366 // create preview
367 $this->createPreview($this->getVersion() > 1);
368 }
369
370 return $result;
371 }
372
373
377 public function copy($a_source, $a_destination)
378 {
379 return copy($a_source, $this->getDirectory() . "/" . $a_destination);
380 }
381
382
386 public function clearDataDirectory()
387 {
389 $this->createDirectory();
390 }
391
392
398 public function deleteVersions($a_hist_entry_ids = null)
399 {
400 global $DIC;
401 $ilDB = $DIC['ilDB'];
402
403 if ($a_hist_entry_ids == null || count($a_hist_entry_ids) < 1) {
404 $ilDB->manipulate("UPDATE file_data SET version = 1 WHERE file_id = "
405 . $ilDB->quote($this->getId(), 'integer'));
406 $this->setVersion(0);
407 $this->clearDataDirectory();
408
410
412 } else {
413 $actualVersionDeleted = false;
414
415 // get all versions
416 $versions = $this->getVersions();
417
418 // delete each version
419 foreach ($a_hist_entry_ids as $hist_id) {
420 $entry = null;
421
422 // get version
423 foreach ($versions as $index => $version) {
424 if ($version["hist_entry_id"] == $hist_id) {
425 // remove each history entry
427
428 // delete directory
429 $version_dir = $this->getDirectory($version["version"]);
430 ilUtil::delDir($version_dir);
431
432 // is actual version?
433 if ($version["version"] == $this->getVersion()) {
434 $actualVersionDeleted = true;
435 }
436
437 // remove from array
438 unset($versions[$index]);
439 break;
440 }
441 }
442 }
443
444 // update actual version if it was deleted before
445 if ($actualVersionDeleted) {
446 // get newest version (already sorted by getVersions)
447 $version = reset($versions);
449 } else {
450 // updateWithVersion() will trigger quota, too
452 }
453 }
454 }
455
456
457 protected function doRead()
458 {
459 global $DIC;
460
461 $q = "SELECT * FROM file_data WHERE file_id = %s";
462 $r = $DIC->database()->queryF($q, ['integer'], [$this->getId()]);
463 $row = $r->fetchObject();
464
465 $this->setFileName($row->file_name);
466 $this->setFileType($row->file_type);
467 $this->setFileSize($row->file_size);
468 $this->setVersion($row->version ? $row->version : 1);
469 $this->setMode($row->f_mode);
470 $this->setRating($row->rating);
471 $this->setPageCount($row->page_count);
472
473 $this->initFileStorage();
474 }
475
476
477 protected function beforeUpdate()
478 {
479 // no meta data handling for file list files
480 if ($this->getMode() != self::MODE_FILELIST) {
481 $this->updateMetaData();
482 }
483
484 return true;
485 }
486
487
488 protected function doUpdate()
489 {
490 global $DIC;
491
492 $a_columns = $this->getArrayForDatabase();
493 $DIC->database()->update('file_data', $a_columns, [
494 'file_id' => [
495 'integer',
496 $this->getId(),
497 ],
498 ]);
499
501
502 return true;
503 }
504
505
509 protected function doUpdateMetaData()
510 {
511 // add technical section with file size and format
512 $md_obj = new ilMD($this->getId(), 0, $this->getType());
513 if (!is_object($technical = $md_obj->getTechnical())) {
514 $technical = $md_obj->addTechnical();
515 $technical->save();
516 }
517 $technical->setSize($this->getFileSize());
518
519 $format_ids = $technical->getFormatIds();
520 if (count($format_ids) > 0) {
521 $format = $technical->getFormat($format_ids[0]);
522 $format->setFormat($this->getFileType());
523 $format->update();
524 } else {
525 $format = $technical->addFormat();
526 $format->setFormat($this->getFileType());
527 $format->save();
528 }
529 $technical->update();
530 }
531
532
536 public function setFileName($a_name)
537 {
538 $this->filename = $a_name;
539 }
540
541
545 public function getFileName()
546 {
547 return $this->filename;
548 }
549
550
554 public function setFileType($a_type)
555 {
556 $this->filetype = $a_type;
557 }
558
559
563 public function getFileType()
564 {
565 return $this->filetype;
566 }
567
568
572 public function setFileSize($a_size)
573 {
574 $this->filesize = $a_size;
575 }
576
577
578 public function getFileSize()
579 {
580 return $this->filesize;
581 }
582
583
590 public function getDiskUsage()
591 {
592 require_once("./Modules/File/classes/class.ilObjFileAccess.php");
593
594 return ilObjFileAccess::_lookupDiskUsage($this->id);
595 }
596
597
598 // END PATCH WebDAV Encapsulate file access in ilObjFile class.
599 public function getFile($a_hist_entry_id = null)
600 {
601 if (is_null($a_hist_entry_id)) {
602 $file = $this->getDirectory($this->getVersion()) . "/" . $this->getFileName();
603 } else {
604 require_once("./Services/History/classes/class.ilHistory.php");
605 $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
606
607 if ($entry === false) {
608 return false;
609 }
610
611 $data = $this->parseInfoParams($entry);
612 $file = $this->getDirectory($data["version"]) . "/" . $data["filename"];
613 }
614
615 return $file;
616 }
617
618
619 // END PATCH WebDAV Encapsulate file access in ilObjFile class.
620
621 public function setVersion($a_version)
622 {
623 $this->version = $a_version;
624 }
625
626
627 public function getVersion()
628 {
629 return $this->version;
630 }
631
632
638 public function setMode($a_mode)
639 {
640 $this->mode = $a_mode;
641 }
642
643
649 public function getMode()
650 {
651 return $this->mode;
652 }
653
654
655 public static function _writeFileType($a_id, $a_format)
656 {
657 global $DIC;
658 $ilDB = $DIC['ilDB'];
659
660 $q = "UPDATE file_data SET " . " file_type = " . $ilDB->quote($a_format, 'text')
661 . " WHERE file_id = " . $ilDB->quote($a_id, 'integer');
662 $res = $ilDB->manipulate($q);
663 }
664
665
672 public static function _lookupFileName($a_id)
673 {
674 global $DIC;
675 $ilDB = $DIC['ilDB'];
676
677 $q = "SELECT * FROM file_data WHERE file_id = " . $ilDB->quote($a_id, 'integer');
678 $r = $ilDB->query($q);
680
681 $strip_slashes = ilUtil::stripSlashes($row->file_name);
682
683 return $strip_slashes;
684 }
685
686
688 public static function _lookupFileSize($a_id)
689 {
690 require_once("./Modules/File/classes/class.ilObjFileAccess.php");
691
693 }
694
695
699 public static function _lookupVersion($a_id)
700 {
701 require_once("./Modules/File/classes/class.ilObjFileAccess.php");
702
704 }
705
706
710 public function determineFileSize($a_hist_entry_id = null)
711 {
712 if (is_null($a_hist_entry_id)) {
713 $file = $this->getDirectory($this->getVersion()) . "/" . $this->getFileName();
714 } else {
715 require_once("./Services/History/classes/class.ilHistory.php");
716 $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
717
718 if ($entry === false) {
719 return false;
720 }
721
722 $data = $this->parseInfoParams($entry);
723 $file = $this->getDirectory($data["version"]) . "/" . $data["filename"];
724 }
725 if (is_file($file)) {
726 $this->setFileSize(filesize($file));
727 }
728 }
729
730
736 public function sendFile($a_hist_entry_id = null)
737 {
738 $s = new FilePathSanitizer($this);
739 $s->sanitizeIfNeeded();
740
741 if (is_null($a_hist_entry_id)) {
742 $file = $this->getDirectory($this->getVersion()) . "/" . $this->getFileName();
743 } else {
744 $entry = ilHistory::_getEntryByHistoryID($a_hist_entry_id);
745 $data = $this->parseInfoParams($entry);
746 $file = $this->getDirectory($data["version"]) . "/" . $data["filename"];
747 }
748
750
751 if ($this->file_storage->fileExists($file)) {
752 global $DIC;
753 $ilClientIniFile = $DIC['ilClientIniFile'];
758 $ilFileDelivery = new ilFileDelivery($file);
759 $ilFileDelivery->setDisposition($this->isInline() ? ilFileDelivery::DISP_INLINE : ilFileDelivery::DISP_ATTACHMENT);
760 $ilFileDelivery->setMimeType($this->guessFileType($file));
761 $ilFileDelivery->setConvertFileNameToAsci((bool) !$ilClientIniFile->readVariable('file_access', 'disable_ascii'));
762
763 // also returning the 'real' filename if a history file is delivered
764 if ($ilClientIniFile->readVariable('file_access', 'download_with_uploaded_filename')
765 != '1'
766 && is_null($a_hist_entry_id)
767 ) {
768 $ilFileDelivery->setDownloadFileName(ilFileUtils::getValidFilename($this->getTitle()));
769 } else {
770 // $download_file_name = basename($file);
771 /* FSX Info: basename has a Bug with Japanese and other characters, see:
772 * http://stackoverflow.com/questions/32115609/basename-fail-when-file-name-start-by-an-accent
773 * Therefore we can no longer use basename();
774 */
775 $parts = explode(DIRECTORY_SEPARATOR, $file);
776 $download_file_name = end($parts);
777 $download_file_name = ilFileUtils::getValidFilename($download_file_name);
778 $ilFileDelivery->setDownloadFileName($download_file_name);
779 }
780 $ilFileDelivery->deliver();
781
782 return true;
783 }
784
785 throw new \ILIAS\Filesystem\Exception\FileNotFoundException("This file cannot be found in ILIAS or has been blocked due to security reasons.");
786 }
787
788
793 public function getFileExtension()
794 {
795 require_once 'Modules/File/classes/class.ilObjFileAccess.php';
796
798 }
799
800
806 public function isInline()
807 {
808 require_once 'Modules/File/classes/class.ilObjFileAccess.php';
809
811 }
812
813
817 public function isHidden()
818 {
819 require_once 'Modules/File/classes/class.ilObjFileAccess.php';
820
822 }
823 // END WebDAV: Get file extension, determine if file is inline, guess file type.
824
825
832 public function guessFileType($a_file = "")
833 {
834 $path = pathinfo($a_file);
835 if ($path["extension"] != "") {
836 $filename = $path["basename"];
837 } else {
838 $filename = "dummy." . $this->getFileExtension();
839 }
840 include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
841 $mime = ilMimeTypeUtil::getMimeType($a_file, $filename, $this->getFileType());
842
843 return $mime;
844 }
845
846
857 protected function doCloneObject($a_new_obj, $a_target_id, $a_copy_id = 0)
858 {
859 global $DIC;
860 $ilDB = $DIC['ilDB'];
861
862 $a_new_obj->createDirectory();
863 $this->cloneMetaData($a_new_obj);
864
865 // Copy all file versions
866 ilUtil::rCopy($this->getDirectory(), $a_new_obj->getDirectory());
867
868 // object created now copy other settings
869 $query = "INSERT INTO file_data (file_id,file_name,file_type,file_size,version,rating,f_mode) VALUES ("
870 . $ilDB->quote($a_new_obj->getId(), 'integer') . ","
871 . $ilDB->quote($this->getFileName(), 'text') . ","
872 . $ilDB->quote($this->getFileType(), 'text') . ","
873 . $ilDB->quote((int) $this->getFileSize(), 'integer') . ", "
874 . $ilDB->quote($this->getVersion(), 'integer') . ", "
875 . $ilDB->quote($this->hasRating(), 'integer') . ", "
876 . $ilDB->quote($this->getMode(), 'text') . ")";
877 $res = $ilDB->manipulate($query);
878
879 // copy all previews
880 require_once("./Services/Preview/classes/class.ilPreview.php");
881 ilPreview::copyPreviews($this->getId(), $a_new_obj->getId());
882
883 // copy history entries
884 require_once("./Services/History/classes/class.ilHistory.php");
885 ilHistory::_copyEntriesForObject($this->getId(), $a_new_obj->getId());
886
887 // Copy learning progress settings
888 include_once('Services/Tracking/classes/class.ilLPObjSettings.php');
889 $obj_settings = new ilLPObjSettings($this->getId());
890 $obj_settings->cloneSettings($a_new_obj->getId());
891 unset($obj_settings);
892
893 // add news notification
894 $a_new_obj->addNewsNotification("file_created");
895
896 return $a_new_obj;
897 }
898
899
900 protected function beforeDelete()
901 {
902 global $DIC;
903 $ilDB = $DIC['ilDB'];
904
905 // check, if file is used somewhere
906 $usages = $this->getUsages();
907 if (count($usages) == 0) {
908 return true;
909 }
910
911 return false;
912 }
913
914
915 protected function doDelete()
916 {
917 global $DIC;
918 $ilDB = $DIC['ilDB'];
919
920 // delete file data entry
921 $q = "DELETE FROM file_data WHERE file_id = " . $ilDB->quote($this->getId(), 'integer');
922 $this->ilias->db->query($q);
923
924 // delete history entries
925 require_once("./Services/History/classes/class.ilHistory.php");
927
929
930 // delete entire directory and its content
931 if (@is_dir($this->getDirectory())) {
933 }
934
935 // delete meta data
936 if ($this->getMode() != self::MODE_FILELIST) {
937 $this->deleteMetaData();
938 }
939
940 // delete preview
941 $this->deletePreview();
942 }
943
944
952 public function export($a_target_dir)
953 {
954 $subdir = "il_" . IL_INST_ID . "_file_" . $this->getId();
955 ilUtil::makeDir($a_target_dir . "/objects/" . $subdir);
956
957 $filedir = $this->getDirectory($this->getVersion());
958
959 if (@!is_dir($filedir)) {
960 $filedir = $this->getDirectory();
961 }
962
963 ilUtil::rCopy($filedir, $a_target_dir . "/objects/" . $subdir);
964 }
965
966
970 public static function _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
971 {
972 global $DIC;
973 $ilDB = $DIC['ilDB'];
974
975 $and_hist = ($a_usage_hist_nr !== false) ? " AND usage_hist_nr = "
976 . $ilDB->quote($a_usage_hist_nr, "integer") : "";
977
978 $file_ids = array();
979 $set = $ilDB->query("SELECT id FROM file_usage" . " WHERE usage_type = "
980 . $ilDB->quote($a_type, "text") . " AND usage_id= "
981 . $ilDB->quote($a_id, "integer") . " AND usage_lang= "
982 . $ilDB->quote($a_usage_lang, "text") . $and_hist);
983 while ($row = $ilDB->fetchAssoc($set)) {
984 $file_ids[] = $row["id"];
985 }
986
987 $ilDB->manipulate("DELETE FROM file_usage WHERE usage_type = "
988 . $ilDB->quote($a_type, "text") . " AND usage_id = "
989 . $ilDB->quote((int) $a_id, "integer") . " AND usage_lang= "
990 . $ilDB->quote($a_usage_lang, "text") . " AND usage_hist_nr = "
991 . $ilDB->quote((int) $a_usage_hist_nr, "integer"));
992
993 foreach ($file_ids as $file_id) {
994 self::handleQuotaUpdate(new self($file_id, false));
995 }
996 }
997
998
1002 public static function _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
1003 {
1004 global $DIC;
1005 $ilDB = $DIC['ilDB'];
1006
1007 // check if file really exists
1008 if (ilObject::_lookupType($a_file_id) != "file") {
1009 return;
1010 }
1011 // #15143
1012 $ilDB->replace("file_usage", array(
1013 "id" => array("integer", (int) $a_file_id),
1014 "usage_type" => array("text", (string) $a_type),
1015 "usage_id" => array("integer", (int) $a_id),
1016 "usage_hist_nr" => array("integer", (int) $a_usage_hist_nr),
1017 "usage_lang" => array("text", $a_usage_lang),
1018 ), array());
1019
1020 self::handleQuotaUpdate(new self($a_file_id, false));
1021 }
1022
1023
1027 public function getUsages()
1028 {
1029 global $DIC;
1030 $ilDB = $DIC['ilDB'];
1031
1032 // get usages in learning modules
1033 $q = "SELECT * FROM file_usage WHERE id = " . $ilDB->quote($this->getId(), "integer");
1034 $us_set = $ilDB->query($q);
1035 $ret = array();
1036 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
1037 $ret[] = array(
1038 "type" => $us_rec["usage_type"],
1039 "id" => $us_rec["usage_id"],
1040 "lang" => $us_rec["usage_lang"],
1041 "hist_nr" => $us_rec["usage_hist_nr"],
1042 );
1043 }
1044
1045 return $ret;
1046 }
1047
1048
1057 public static function _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr = 0, $a_usage_lang = "-")
1058 {
1059 global $DIC;
1060 $ilDB = $DIC['ilDB'];
1061
1062 $lstr = "";
1063 if ($a_usage_lang != "") {
1064 $lstr = "usage_lang = " . $ilDB->quote((string) $a_usage_lang, "text") . " AND ";
1065 }
1066
1067 // get usages in learning modules
1068 $q = "SELECT * FROM file_usage WHERE " . "usage_id = " . $ilDB->quote((int) $a_id, "integer")
1069 . " AND " . "usage_type = " . $ilDB->quote((string) $a_type, "text") . " AND " . $lstr
1070 . "usage_hist_nr = " . $ilDB->quote((int) $a_usage_hist_nr, "integer");
1071 $file_set = $ilDB->query($q);
1072 $ret = array();
1073 while ($file_rec = $ilDB->fetchAssoc($file_set)) {
1074 $ret[$file_rec["id"]] = $file_rec["id"];
1075 }
1076
1077 return $ret;
1078 }
1079
1080
1081 // TODO: What is this function good for??
1082 public function getXMLZip()
1083 {
1084 global $DIC;
1085 $ilias = $DIC['ilias'];
1086
1087 $zip = PATH_TO_ZIP;
1088
1089 exec($zip . ' ' . ilUtil::escapeShellArg($this->getDirectory() . '/' . $this->getFileName())
1090 . " " . ilUtil::escapeShellArg($this->getDirectory() . '/' . '1.zip'));
1091
1092 return $this->getDirectory() . '/1.zip';
1093 }
1094
1095
1096 public function addNewsNotification($a_lang_var)
1097 {
1098 // BEGIN WebDAV Suppress news notification for hidden files
1099 if ($this->isHidden()) {
1100 return;
1101 }
1102 // END WebDAV Suppress news notification for hidden files
1103
1104 global $DIC;
1105 $ilUser = $DIC['ilUser'];
1106
1107 // Add Notification to news
1108 include_once("./Services/News/classes/class.ilNewsItem.php");
1109 include_once("./Modules/File/classes/class.ilObjFileAccess.php");
1110 $news_item = new ilNewsItem();
1111 $news_item->setContext($this->getId(), $this->getType());
1112 $news_item->setPriority(NEWS_NOTICE);
1113 $news_item->setTitle($a_lang_var);
1114 $news_item->setContentIsLangVar(true);
1115 if ($this->getDescription() != "") {
1116 $news_item->setContent("<p>" . $this->getDescription() . "</p>");
1117 }
1118 $news_item->setUserId($ilUser->getId());
1119 $news_item->setVisibility(NEWS_USERS);
1120 $news_item->create();
1121 }
1122
1123
1130 public function initFileStorage()
1131 {
1132 $this->file_storage = new ilFSStorageFile($this->getId());
1133
1134 return true;
1135 }
1136
1137
1147 public function storeUnzipedFile($a_upload_file, $a_filename)
1148 {
1149 $this->setVersion($this->getVersion() + 1);
1150
1151 if (@!is_dir($this->getDirectory($this->getVersion()))) {
1152 ilUtil::makeDir($this->getDirectory($this->getVersion()));
1153 }
1154
1155 $file = $this->getDirectory($this->getVersion()) . "/" . $a_filename;
1156
1157 ilFileUtils::rename($a_upload_file, $file);
1158
1159 // create preview
1160 $this->createPreview();
1161 }
1162
1163
1171 public static function _lookupAbsolutePath($obj_id, $a_version = null)
1172 {
1173 $file_object = new self($obj_id, false);
1174 $s = new FilePathSanitizer($file_object);
1175 $s->sanitizeIfNeeded();
1176
1177 return $file_object->getFile($a_version);
1178 }
1179
1180
1186 public function checkFileExtension($new_filename, $new_title)
1187 {
1188 include_once './Modules/File/classes/class.ilObjFileAccess.php';
1189 $fileExtension = ilObjFileAccess::_getFileExtension($new_filename);
1190 $titleExtension = ilObjFileAccess::_getFileExtension($new_title);
1191 if ($titleExtension != $fileExtension && strlen($fileExtension) > 0) {
1192 // remove old extension
1193 $pi = pathinfo($this->getFileName());
1194 $suffix = $pi["extension"];
1195 if ($suffix != "") {
1196 if (substr($new_title, strlen($new_title) - strlen($suffix) - 1) == "." . $suffix) {
1197 $new_title = substr($new_title, 0, strlen($new_title) - strlen($suffix) - 1);
1198 }
1199 }
1200 $new_title .= '.' . $fileExtension;
1201 }
1202
1203 return $new_title;
1204 }
1205
1206
1215 public function getVersions($version_ids = null)
1216 {
1217 include_once("./Services/History/classes/class.ilHistory.php");
1218 $versions = ilHistory::_getEntriesForObject($this->getId(), $this->getType());
1219
1220 if ($version_ids != null && count($version_ids) > 0) {
1221 foreach ($versions as $index => $version) {
1222 if (!in_array($version["hist_entry_id"], $version_ids, true)) {
1223 unset($versions[$index]);
1224 }
1225 }
1226 }
1227
1228 // add custom entries
1229 foreach ($versions as $index => $version) {
1231 $versions[$index] = array_merge($version, $params);
1232 }
1233
1234 // sort by version number (hist_entry_id will do for that)
1235 usort($versions, array($this, "compareVersions"));
1236
1237 return $versions;
1238 }
1239
1240
1248 public function getSpecificVersion($version_id)
1249 {
1250 include_once("./Services/History/classes/class.ilHistory.php");
1252 if ($version === false) {
1253 return false;
1254 }
1255
1256 // ilHistory returns different keys in _getEntryByHistoryID and _getEntriesForObject
1257 // so this makes it the same
1258 $version["hist_entry_id"] = $version["id"];
1259 $version["user_id"] = $version["usr_id"];
1260 $version["date"] = $version["hdate"];
1261 unset($version["id"], $version["usr_id"], $version["hdate"]);
1262
1263 // parse params
1265
1266 return array_merge($version, $params);
1267 }
1268
1269
1277 public function rollback($version_id)
1278 {
1279 global $DIC;
1280 $ilDB = $DIC['ilDB'];
1281 $ilUser = $DIC['ilUser'];
1282
1283 $source = $this->getSpecificVersion($version_id);
1284 if ($source === false) {
1285 $this->ilErr->raiseError($this->lng->txt("obj_not_found"), $this->ilErr->MESSAGE);
1286 }
1287
1288 // get the new version number
1289 $new_version_nr = $this->getVersion() + 1;
1290
1291 // copy file
1292 $source_path = $this->getDirectory($source["version"]) . "/" . $source["filename"];
1293 $dest_dir = $this->getDirectory($new_version_nr);
1294 if (@!is_dir($dest_dir)) {
1295 ilUtil::makeDir($dest_dir);
1296 }
1297
1298 copy($source_path, $dest_dir . "/" . $source["filename"]);
1299
1300 // create new history entry based on the old one
1301 include_once("./Services/History/classes/class.ilHistory.php");
1302 ilHistory::_createEntry($this->getId(), "rollback", $source["filename"] . ","
1303 . $new_version_nr . "|"
1304 . $source["version"] . "|"
1305 . $ilUser->getId());
1306
1307 // get id of newest entry
1308 // bugfix mantis 23596
1309 $entries = ilHistory::_getEntriesForObject($this->getId());
1310 $newest_entry_id = 0;
1311 foreach ($entries as $entry) {
1312 if ($entry["action"] == "rollback") {
1313 $newest_entry_id = $entry["hist_entry_id"];
1314 }
1315 }
1316 $new_version = $this->getSpecificVersion($newest_entry_id);
1317
1318 // change user back to the original uploader
1319 ilHistory::_changeUserId($new_version["hist_entry_id"], $source["user_id"]);
1320
1321 // update this file with the new version
1322 $this->updateWithVersion($new_version);
1323
1324 $this->addNewsNotification("file_updated");
1325
1326 return $new_version;
1327 }
1328
1329
1335 protected function updateWithVersion($version)
1336 {
1337 // update title (checkFileExtension must be called before setFileName!)
1338 $this->setTitle($this->checkFileExtension($version["filename"], $this->getTitle()));
1339
1340 $this->setVersion($version["version"]);
1341 $this->setFileName($version["filename"]);
1342
1343 // evaluate mime type (reset file type before)
1344 $this->setFileType("");
1345 $this->setFileType($this->guessFileType($version["filename"]));
1346
1347 // set filesize
1348 $this->determineFileSize();
1349
1350 $this->update();
1351
1352 // refresh preview
1353 $this->createPreview(true);
1354 }
1355
1356
1367 public function compareVersions($v1, $v2)
1368 {
1369 // v2 - v1 because version should be descending
1370 return (int) $v2["version"] - (int) $v1["version"];
1371 }
1372
1373
1382 public function parseInfoParams($entry)
1383 {
1384 $data = preg_split("/(.*),(.*)/", $entry["info_params"], 0, PREG_SPLIT_DELIM_CAPTURE
1385 | PREG_SPLIT_NO_EMPTY);
1386
1387 // bugfix: first created file had no version number
1388 // this is a workaround for all files created before the bug was fixed
1389 if (empty($data[1])) {
1390 $data[1] = "1";
1391 }
1392
1393 $result = array(
1394 "filename" => $data[0],
1395 "version" => $data[1],
1396 "rollback_version" => "",
1397 "rollback_user_id" => "",
1398 );
1399
1400 // if rollback, the version contains the rollback version as well
1401 if ($entry["action"] == "rollback") {
1402 $tokens = explode("|", $result["version"]);
1403 if (count($tokens) > 1) {
1404 $result["version"] = $tokens[0];
1405 $result["rollback_version"] = $tokens[1];
1406
1407 if (count($tokens) > 2) {
1408 $result["rollback_user_id"] = $tokens[2];
1409 }
1410 }
1411 }
1412
1413 return $result;
1414 }
1415
1416
1417 protected static function handleQuotaUpdate(ilObjFile $a_file)
1418 {
1419 include_once "Services/MediaObjects/classes/class.ilObjMediaObject.php";
1420 $mob = new ilObjMediaObject();
1421
1422 // file itself could be workspace item
1423 $parent_obj_ids = array($a_file->getId());
1424
1425 foreach ($a_file->getUsages() as $item) {
1426 $parent_obj_id = $mob->getParentObjectIdForUsage($item);
1427 if ($parent_obj_id
1428 && !in_array($parent_obj_id, $parent_obj_ids)
1429 ) {
1430 $parent_obj_ids[] = $parent_obj_id;
1431 }
1432 }
1433
1434 include_once "Services/DiskQuota/classes/class.ilDiskQuotaHandler.php";
1435 ilDiskQuotaHandler::handleUpdatedSourceObject($a_file->getType(), $a_file->getId(), $a_file->getDiskUsage(), $parent_obj_ids);
1436 }
1437
1438
1445 protected function createPreview($force = false)
1446 {
1447 // only normal files are supported
1448 if ($this->getMode() != self::MODE_OBJECT) {
1449 return;
1450 }
1451
1452 require_once("./Services/Preview/classes/class.ilPreview.php");
1453 ilPreview::createPreview($this, $force);
1454 }
1455
1456
1460 protected function deletePreview()
1461 {
1462 // only normal files are supported
1463 if ($this->getMode() != self::MODE_OBJECT) {
1464 return;
1465 }
1466
1467 require_once("./Services/Preview/classes/class.ilPreview.php");
1469 }
1470
1471
1475 public function setRating($a_value)
1476 {
1477 $this->rating = (bool) $a_value;
1478 }
1479
1480
1484 public function hasRating()
1485 {
1486 return $this->rating;
1487 }
1488
1489
1493 public function getPageCount()
1494 {
1495 return $this->page_count;
1496 }
1497
1498
1502 public function setPageCount($page_count)
1503 {
1504 $this->page_count = $page_count;
1505 }
1506
1507
1511 private function getArrayForDatabase()
1512 {
1513 return [
1514 'file_id' => ['integer', $this->getId()],
1515 'file_name' => ['text', $this->getFileName()],
1516 'file_type' => ['text', $this->getFileType()],
1517 'file_size' => ['integer', (int) $this->getFileSize()],
1518 'version' => ['integer', (int) $this->getVersion()],
1519 'f_mode' => ['text', $this->getMode()],
1520 'page_count' => ['text', $this->getPageCount()],
1521 'rating' => ['integer', $this->hasRating()],
1522 ];
1523 }
1524}
sprintf('%.4f', $callTime)
$result
$metadata['__DYNAMIC:1__']
$source
Definition: linkback.php:22
$_GET["client_id"]
An exception for terminatinating execution or to throw for unit testing.
const NEWS_USERS
const NEWS_NOTICE
static _write($a_type, $a_setting, $a_value, $a_user=0, $a_block_id=0)
Write setting to database.
Class ilCountPDFPagesPreProcessors.
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 ilFSStorageFile.
Class ilFileDelivery.
Class to report exception.
static getValidFilename($a_filename)
Get valid filename.
static rename($a_source, $a_target)
Rename a file.
static _removeEntryByHistoryID($a_hist_entry_id)
Removes a single entry from the history.
static _changeUserId($a_hist_entry_id, $new_user_id)
Changes the user id of the specified history entry.
static _removeEntriesForObject($a_obj_id)
remove all history entries for an object
static _getEntriesForObject($a_obj_id, $a_obj_type="")
get all history entries for an object
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.
static _copyEntriesForObject($a_src_id, $a_dst_id)
copy all history entries for an object
static _getEntryByHistoryID($a_hist_entry_id)
returns a single history entry
static getLogger($a_component_id)
Get component logger.
static getMimeType($a_file='', $a_filename='', $a_mime='')
static _getDefaultVisibilityForRefId($a_ref_id)
Get default visibility for reference id.
static _lookupFileSize($a_id)
Quickly looks up the file size from the database and returns the number of bytes.
static _lookupVersion($a_id)
lookup version
static _getFileExtension($a_file_name)
Gets the file extension of the specified file name.
static _isFileHidden($a_file_name)
Returns true, if a file with the specified name, is usually hidden from the user.
static _isFileInline($a_file_name)
Returns true, if the specified file shall be displayed inline in the browser.
static _lookupDiskUsage($a_id)
Returns the number of bytes used on the harddisk by the file object with the specified object id.
Class ilObjFile.
static _lookupFileSize($a_id)
Lookups the file size of the file in bytes.
static _lookupFileName($a_id)
raiseUploadError($a_raise=true)
setFileSize($a_size)
clearDataDirectory()
clear data directory
static handleQuotaUpdate(ilObjFile $a_file)
updateWithVersion($version)
Updates the file object with the specified file version.
static _getFilesOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
get all files of an object
const MODE_FILELIST
const MODE_OBJECT
doCreate($a_upload=false)
create object
addFileVersion($a_upload_file, $a_filename)
createProperties($a_upload=false)
The basic properties of a file object are stored in table object_data.
getFile($a_hist_entry_id=null)
doUpdateMetaData()
update meta data
initFileStorage()
init file storage object
static _saveUsage($a_file_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
save usage
beforeMDUpdateListener($a_element)
copy($a_source, $a_destination)
copy file
createPreview($force=false)
Creates a preview for the file object.
setFileType($a_type)
doMDUpdateListener($a_element)
isInline()
Returns true, if this file should be displayed inline in a browser window.
__construct($a_id=0, $a_call_by_reference=true)
ilObjFile constructor.
getSpecificVersion($version_id)
Gets a specific file version.
static _lookupAbsolutePath($obj_id, $a_version=null)
doCreateMetaData()
create file object meta data
getVersions($version_ids=null)
Gets the file versions for this object.
setMode($a_mode)
mode is object or filelist
deleteVersions($a_hist_entry_ids=null)
Deletes the specified history entries or all entries if no ids are specified.
setFileName($a_name)
replaceFile($a_upload_file, $a_filename)
doCloneObject($a_new_obj, $a_target_id, $a_copy_id=0)
Clone.
export($a_target_dir)
export files of object to target directory note: target directory must be the export target directory...
setNoMetaDataCreation($a_status)
checkFileExtension($new_filename, $new_title)
Check if the file extension does still exist after an update of the title.
static _deleteAllUsages($a_type, $a_id, $a_usage_hist_nr=0, $a_usage_lang="-")
static delete all usages of
getDirectory($a_version=0)
getMode()
mode is object or filelist
setRating($a_value)
deletePreview()
Deletes the preview of the file object.
compareVersions($v1, $v2)
Compares two file versions.
static _writeFileType($a_id, $a_format)
addNewsNotification($a_lang_var)
determineFileSize($a_hist_entry_id=null)
Determine File Size.
setPageCount($page_count)
setVersion($a_version)
getUsages()
get all usages of file object
getFileExtension()
Returns the extension of the file name converted to lower-case.
static _lookupVersion($a_id)
lookup version
getDiskUsage()
Gets the disk usage of the object in bytes.
parseInfoParams($entry)
Parses the info parameters ("info_params") of the specified history entry.
guessFileType($a_file="")
Guesses the file type based on the current values returned by getFileType() and getFileExtension().
rollback($version_id)
Makes the specified version the current one and returns theSummary of rollbackVersion.
storeUnzipedFile($a_upload_file, $a_filename)
storeUnzipedFile
isHidden()
Returns true, if this file should be hidden in the repository view.
Class ilObjMediaObject.
Class ilObject2 This is an intermediate progress of ilObject class.
setTitle($a_title)
set object title
createMetaData()
create meta data entry
cloneMetaData($target_obj)
Copy meta data.
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getType()
get object type @access public
getDescription()
get object description
update()
update object in db
getId()
get object id @access public
getTitle()
get object title @access public
static _lookupType($a_id, $a_reference=false)
lookup object type
static copyPreviews($a_src_id, $a_dest_id)
Copies the preview images from one preview to a new preview object.
static deletePreview($a_obj_id)
Deletes the preview for the object with the specified id.
static createPreview($a_obj, $a_force=false)
Creates the preview for the object with the specified id.
static getBytesForString($a_str)
Return string as byte array Note: Use this for debugging purposes only.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static escapeShellArg($a_arg)
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
$r
Definition: example_031.php:79
Interface Location.
Definition: Location.php:17
$format
Definition: metadata.php:141
$index
Definition: metadata.php:60
Class BaseForm.
redirection script todo: (a better solution should control the processing via a xml file)
$ret
Definition: parser.php:6
$query
$s
Definition: pwgen.php:45
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
echo;exit;}function LogoutNotification($SessionID){ global $ilDB;$q="SELECT session_id, data FROM usr_session WHERE expires > (\w+)\|/" PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE
global $ilDB
$ilUser
Definition: imgupload.php:18
$a_type
Definition: workflow.php:92
$params
Definition: disable.php:11