ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilObjFile.php
Go to the documentation of this file.
1<?php
25
34{
36 use ilObjFileUsages;
37 use ilObjFilePreviewHandler;
38 use ilObjFileNews;
40
41 public const MODE_FILELIST = "filelist";
42 public const MODE_OBJECT = "object";
43
47 protected $implementation;
48
52 protected $page_count = 0;
56 protected $rating = false;
60 protected $log;
61
62 // ABSTRACT
66 protected $filename = '';
70 protected $filetype = '';
74 protected $filesize;
78 protected $version = 1;
82 protected $max_version = 1;
86 protected $action;
87 // ABSTRACT
88
92 protected $resource_id;
93
101 protected $manager;
105 protected $upload;
109 protected $stakeholder;
110
116 public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
117 {
118 global $DIC;
122 $this->manager = $DIC->resourceStorage()->manage();
123 $this->stakeholder = new ilObjFileStakeholder($DIC->user()->getId());
124 $this->upload = $DIC->upload();
125 $this->version = 0;
126 $this->max_version = 0;
127 $this->log = ilLoggerFactory::getLogger('file');
128
129 parent::__construct($a_id, $a_call_by_reference);
130 }
131
132 protected function initImplementation() : void
133 {
134 if ($this->resource_id && ($id = $this->manager->find($this->resource_id)) !== null) {
135 $resource = $this->manager->getResource($id);
136 $this->implementation = new ilObjFileImplementationStorage(
137 $resource,
138 (int) $this->getId()
139 );
140 $this->setMaxVersion($resource->getMaxRevision());
141 $this->setVersion($resource->getMaxRevision());
142 } else {
143 $this->implementation = new ilObjFileImplementationLegacy(
144 (int) $this->getId(),
145 (int) $this->getVersion(),
146 (string) $this->getFileName()
147 );
148 $s = new FilePathSanitizer($this);
149 $s->sanitizeIfNeeded();
150 }
151 }
152
153 private function updateObjectFromRevision(Revision $r, bool $create_previews = true) : void
154 {
155 $this->setTitle($r->getTitle());
156 $this->setFileName($r->getInformation()->getTitle());
157 $this->setVersion($r->getVersionNumber());
158 $this->setMaxVersion($r->getVersionNumber());
159 $this->setFileSize($r->getInformation()->getSize());
160 $this->setFileType($r->getInformation()->getMimeType());
161 $this->update();
162 if ($create_previews) {
163 $this->createPreview(true);
164 }
165 }
166
167 private function appendSuffixToTitle(string $title, string $filename) : string
168 {
169 // bugfix mantis 0026160 && 0030391 and 0032340
170 $title_info = new SplFileInfo($title);
171 $filename_info = new SplFileInfo($filename);
172
173 $filename = str_replace('.' . $title_info->getExtension(), '', $title_info->getPathname());
174 $extension = $filename_info->getExtension();
175
176 return $this->secure($filename . '.' . $extension);
177 }
178
182 public function appendStream(FileStream $stream, string $title) : int
183 {
184 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
185 $revision = $this->manager->appendNewRevisionFromStream($i, $stream, $this->stakeholder, $title);
186 } else {
187 $i = $this->manager->stream($stream, $this->stakeholder, $title);
188 $revision = $this->manager->getCurrentRevision($i);
189 $this->setResourceId($i->serialize());
190 $this->initImplementation();
191 }
192 $this->updateObjectFromRevision($revision);
193
194 return $revision->getVersionNumber();
195 }
196
200 public function appendUpload(UploadResult $result, string $title) : int
201 {
202 $title = $this->appendSuffixToTitle($title, $result->getName());
203 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
204 $revision = $this->manager->appendNewRevision($i, $result, $this->stakeholder, $title);
205 } else {
206 $i = $this->manager->upload($result, $this->stakeholder, $title);
207 $revision = $this->manager->getCurrentRevision($i);
208 $this->setResourceId($i->serialize());
209 $this->initImplementation();
210 }
213 }
214 $this->updateObjectFromRevision($revision);
215
216 return $revision->getVersionNumber();
217 }
218
222 public function replaceWithStream(FileStream $stream, string $title) : int
223 {
224 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
225 $revision = $this->manager->replaceWithStream($i, $stream, $this->stakeholder, $title);
226 } else {
227 throw new LogicException('only files with existing resource and revision can be replaced');
228 }
229 $this->updateObjectFromRevision($revision);
230
231 return $revision->getVersionNumber();
232 }
233
237 public function replaceWithUpload(UploadResult $result, string $title) : int
238 {
239 $title = $this->appendSuffixToTitle($title, $result->getName());
240 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
241 $revision = $this->manager->replaceWithUpload($i, $result, $this->stakeholder, $title);
242 } else {
243 throw new LogicException('only files with existing resource and revision can be replaced');
244 }
245 if ($result->getMetaData()->has(ilCountPDFPagesPreProcessors::PAGE_COUNT)) {
247 }
248 $this->updateObjectFromRevision($revision);
249
250 return $revision->getVersionNumber();
251 }
252
258 public function getFile($a_hist_entry_id = null)
259 {
260 return $this->implementation->getFile($a_hist_entry_id);
261 }
262
263 public function getDirectory($a_version = 0)
264 {
265 return $this->implementation->getDirectory($a_version);
266 }
267
268 public function getVersion()
269 {
270 return $this->version;
271 }
272
273 public function setVersion($a_version)
274 {
275 $this->version = $a_version;
276 }
277
281 public function getFileName()
282 {
283 return $this->filename;
284 }
285
289 public function setFileName($a_name)
290 {
291 $this->filename = $a_name;
292 }
293
297 public function setRating($a_value)
298 {
299 $this->rating = (bool) $a_value;
300 }
301
306 public function setResourceId(?string $resource_id) : ilObjFile
307 {
308 $this->resource_id = $resource_id;
309 return $this;
310 }
311
312 public function getResourceId() : ?string
313 {
314 return $this->resource_id ?? '-';
315 }
316
317 public function getStorageID() : ?string
318 {
319 return $this->implementation->getStorageID();
320 }
321
325 public function getMode()
326 {
327 return $this->mode;
328 }
329
333 public function setMode($a_mode)
334 {
335 $this->mode = $a_mode;
336 }
337
338 public function getFileSize()
339 {
340 return $this->filesize;
341 }
342
346 public function setFileSize($a_size)
347 {
348 $this->filesize = $a_size;
349 }
350
354 public function getFileType()
355 {
356 return $this->filetype;
357 }
358
362 public function setFileType($a_type)
363 {
364 $this->filetype = $a_type;
365 }
366
370 public function hasRating()
371 {
372 return $this->rating;
373 }
374
375 public function getMaxVersion()
376 {
377 return $this->max_version;
378 }
379
380 public function setMaxVersion($a_max_version)
381 {
382 $this->max_version = $a_max_version;
383 }
384
388 public function getPageCount()
389 {
390 return $this->page_count;
391 }
392
396 public function setPageCount($page_count)
397 {
398 $this->page_count = $page_count;
399 }
400
405 public function getAction()
406 {
407 return $this->action;
408 }
409
414 public function setAction($a_action)
415 {
416 $this->action = $a_action;
417 }
418
419 public function handleChangedObjectTitle(string $new_title)
420 {
421 $this->setTitle($new_title);
422 $this->implementation->handleChangedObjectTitle($new_title);
423 }
424
425
426 // CRUD
427
431 protected function doCreate($a_upload = false)
432 {
433 $this->createProperties($a_upload);
434 $this->notifyCreation($this->getId(), $this->getDescription());
435 }
436
437 protected function doRead()
438 {
439 global $DIC;
444 $q = "SELECT * FROM file_data WHERE file_id = %s";
445 $r = $DIC->database()->queryF($q, ['integer'], [$this->getId()]);
446 $row = $r->fetchObject();
447
448 $this->setFileName($this->secure($row->file_name ?? ''));
449 $this->setFileType($row->file_type);
450 $this->setFileSize($row->file_size);
451 $this->setVersion($row->version ? $row->version : 1);
452 $this->setMaxVersion($row->max_version ? $row->max_version : 1);
453 $this->setMode($row->f_mode);
454 $this->setRating($row->rating);
455 $this->setPageCount($row->page_count);
456 $this->setPageCount($row->page_count);
457 $this->setResourceId($row->rid);
458
459 $this->initImplementation();
460 }
461
462 protected function doCloneObject($new_object, $a_target_id, $a_copy_id = 0)
463 {
467 $this->cloneMetaData($new_object);
468
469 // object created now copy other settings
470 $this->db->manipulateF(
471 "INSERT INTO file_data (file_id, file_name, file_type, file_size, version, rating, f_mode) VALUES (%s, %s, %s, %s, %s, %s, %s)",
472 [
473 'integer', // file_id
474 'text', // file_name
475 'text', // file_type
476 'integer', // file_size
477 'integer', // version
478 'integer', // rating
479 'integer' // f_mode
480 ],
481 [
482 (int) $new_object->getId(),
483 $this->getFileName(),
484 $this->getFileType(),
485 (int) $this->getFileSize(),
486 (int) $this->getVersion(),
487 (int) $this->hasRating(),
488 (int) $this->getMode()
489 ]
490 );
491
492 // Copy Resource
493 if ($this->resource_id
494 && ($identification = $this->manager->find($this->resource_id)) instanceof ResourceIdentification) {
495 $new_resource_identification = $this->manager->clone($identification);
496 $new_current_revision = $this->manager->getCurrentRevision($new_resource_identification);
497 $new_object->setResourceId($new_resource_identification->serialize());
498 $new_object->initImplementation();
499 $new_object->updateObjectFromRevision($new_current_revision, false); // Previews are already copied in 453
500 $new_object->setTitle($this->getTitle()); // see https://mantis.ilias.de/view.php?id=31375
501 $new_object->update();
502 } else {
503 // migrate
504 global $DIC;
506 $DIC->fileSystem()->storage(),
507 $DIC->database(),
508 rtrim(CLIENT_DATA_DIR, "/") . '/ilFile/migration_log.csv'
509 );
510 $migration->setMigrateToNewObjectId((int) $new_object->getId());
511 $migration->migrate(new ilFileObjectToStorageDirectory($this->getId(), $this->getDirectory()));
512 }
513
514 // copy all previews
515 ilPreview::copyPreviews($this->getId(), $new_object->getId());
516
517 // Copy learning progress settings
518 $obj_settings = new ilLPObjSettings($this->getId());
519 $obj_settings->cloneSettings($new_object->getId());
520 unset($obj_settings);
521
522 return $new_object;
523 }
524
525 protected function doUpdate()
526 {
527 global $DIC;
528
529 $a_columns = $this->getArrayForDatabase();
530 $DIC->database()->update('file_data', $a_columns, [
531 'file_id' => [
532 'integer',
533 $this->getId(),
534 ],
535 ]);
536
537 // update metadata with the current file version
538 $meta_version_column = ['meta_version' => ['integer', (int) $this->getVersion()]];
539 $DIC->database()->update('il_meta_lifecycle', $meta_version_column, [
540 'rbac_id' => [
541 'integer',
542 $this->getId(),
543 ],
544 ]);
545
546 $this->notifyUpdate($this->getId(), $this->getDescription());
547
548 return true;
549 }
550
551 protected function beforeUpdate()
552 {
553 // no meta data handling for file list files
554 if ($this->getMode() != self::MODE_FILELIST) {
555 $this->updateMetaData();
556 }
557
558 return true;
559 }
560
561 protected function beforeDelete()
562 {
563 // check, if file is used somewhere
564 $usages = $this->getUsages();
565 if (count($usages) == 0) {
566 return true;
567 }
568
569 return false;
570 }
571
572 protected function doDelete()
573 {
574 global $DIC;
575
576 // delete file data entry
577 $DIC->database()->manipulateF("DELETE FROM file_data WHERE file_id = %s", ['integer'], [$this->getId()]);
578
579 // delete history entries
581
582 // delete meta data
583 if ($this->getMode() != self::MODE_FILELIST) {
584 $this->deleteMetaData();
585 }
586
587 // delete preview
588 $this->deletePreview();
589
590 // delete resource
591 $identification = $this->getResourceId();
592 if ($identification && $identification != '-') {
593 $resource = $this->manager->find($identification);
594 if ($resource !== null) {
595 $this->manager->remove($resource, $this->stakeholder);
596 }
597 }
598 }
599
603 private function getArrayForDatabase() : array
604 {
605 return [
606 'file_id' => ['integer', $this->getId()],
607 'file_name' => ['text', $this->getFileName()],
608 'file_type' => ['text', $this->getFileType()],
609 'file_size' => ['integer', (int) $this->getFileSize()],
610 'version' => ['integer', (int) $this->getVersion()],
611 'max_version' => ['integer', (int) $this->getMaxVersion()],
612 'f_mode' => ['text', $this->getMode()],
613 'page_count' => ['text', $this->getPageCount()],
614 'rating' => ['integer', $this->hasRating()],
615 'rid' => ['text', $this->resource_id ?? ''],
616 ];
617 }
618
619 public function initType()
620 {
621 $this->type = "file";
622 }
623
624 public function createDirectory()
625 {
626 // we no longer create directories
627 }
628
629 public function raiseUploadError($raise = false)
630 {
631 // we no longer support that
632 }
633
634 // Upload Handling
635 public function replaceFile($a_upload_file, $a_filename)
636 {
637 return null;
638 }
639
640 private function prepareUpload() : void
641 {
642 if (true !== $this->upload->hasBeenProcessed()) {
643 if (defined('PATH_TO_GHOSTSCRIPT') && PATH_TO_GHOSTSCRIPT !== "") {
644 $this->upload->register(new ilCountPDFPagesPreProcessors());
645 }
646
647 $this->upload->process();
648 }
649 }
650
656 public function getUploadFile($a_upload_file, string $title, bool $a_prevent_preview = false) : bool
657 {
658 $this->prepareUpload();
659
660 $results = $this->upload->getResults();
661 $upload = $results[$a_upload_file];
662
663 $this->appendUpload($upload, $title);
664
665 return true;
666 }
667
672 public function isHidden()
673 {
675 }
676
681 public function clearDataDirectory()
682 {
683 $this->implementation->clearDataDirectory();
684 }
685
690 public function deleteVersions($a_hist_entry_ids = null)
691 {
692 $this->implementation->deleteVersions($a_hist_entry_ids);
693 }
694
699 public function sendFile($a_hist_entry_id = null) : void
700 {
701 $this->implementation->sendFile($a_hist_entry_id);
702 }
703
708 public function isInline()
709 {
711 }
712
717 public function export(string $target_dir) : void
718 {
719 $this->implementation->export($target_dir);
720 }
721
730 public function storeUnzipedFile($a_upload_file, $a_filename)
731 {
732 $this->setVersion($this->getVersion() + 1);
733
734 if (@!is_dir($this->getDirectory($this->getVersion()))) {
735 ilUtil::makeDir($this->getDirectory($this->getVersion()));
736 }
737
738 $file = $this->getDirectory($this->getVersion()) . "/" . $a_filename;
739
740 $file = ilFileUtils::getValidFilename($file);
741
742 ilFileUtils::rename($a_upload_file, $file);
743
744 // create preview
745 $this->createPreview();
746 }
747
752 public function getVersions($version_ids = null) : array
753 {
754 return $this->implementation->getVersions($version_ids);
755 }
756
761 public function rollback(int $version_id) : void
762 {
763 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
764 $this->manager->rollbackRevision($i, $version_id);
765 $latest_revision = $this->manager->getCurrentRevision($i);
766 $this->updateObjectFromRevision($latest_revision);
767 } else {
768 throw new LogicException('only files with existing resource and revision can be replaced');
769 }
770 }
771
778 public function checkFileExtension($new_filename, $new_title)
779 {
780 $fileExtension = ilObjFileAccess::_getFileExtension($new_filename);
781 $titleExtension = ilObjFileAccess::_getFileExtension($new_title);
782 if ($titleExtension != $fileExtension && strlen($fileExtension) > 0) {
783 // remove old extension
784 $pi = pathinfo($this->getFileName());
785 $suffix = $pi["extension"];
786 if ($suffix != "") {
787 if (substr($new_title, strlen($new_title) - strlen($suffix) - 1) == "." . $suffix) {
788 $new_title = substr($new_title, 0, strlen($new_title) - strlen($suffix) - 1);
789 }
790 }
791 $new_title .= '.' . $fileExtension;
792 }
793
794 return $new_title;
795 }
796
801 public function getFileExtension()
802 {
803 return $this->implementation->getFileExtension();
804 }
805}
$result
An exception for terminatinating execution or to throw for unit testing.
Customizing of pimple-DIC for ILIAS.
Definition: Container.php:19
Class ilCountPDFPagesPreProcessors.
Class ilFileObjectToStorageDirectory.
static getValidFilename($a_filename)
Get valid filename.
static rename($a_source, $a_target)
Rename a file.
static _removeEntriesForObject($a_obj_id)
remove all history entries for an object
static getLogger($a_component_id)
Get component logger.
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.
Class ilObjFileImplementationLegacy.
Class ilObjFileImplementationStorage.
Class ilObjFileStakeholder.
Class ilObjFile.
handleChangedObjectTitle(string $new_title)
setMaxVersion($a_max_version)
setFileSize($a_size)
clearDataDirectory()
@ineritdoc
appendStream(FileStream $stream, string $title)
const MODE_FILELIST
export(string $target_dir)
const MODE_OBJECT
doCreate($a_upload=false)
appendSuffixToTitle(string $title, string $filename)
setAction($a_action)
getFile($a_hist_entry_id=null)
updateObjectFromRevision(Revision $r, bool $create_previews=true)
replaceWithUpload(UploadResult $result, string $title)
sendFile($a_hist_entry_id=null)
setFileType($a_type)
replaceWithStream(FileStream $stream, string $title)
getVersions($version_ids=null)
setMode($a_mode)
deleteVersions($a_hist_entry_ids=null)
@ineritdoc
setFileName($a_name)
replaceFile($a_upload_file, $a_filename)
rollback(int $version_id)
Makes the specified version the current one.
setResourceId(?string $resource_id)
appendUpload(UploadResult $result, string $title)
checkFileExtension($new_filename, $new_title)
getDirectory($a_version=0)
setRating($a_value)
raiseUploadError($raise=false)
setPageCount($page_count)
getUploadFile($a_upload_file, string $title, bool $a_prevent_preview=false)
@description This Method is used to append a fileupload by it's POST-name to the current ilObjFile
setVersion($a_version)
storeUnzipedFile($a_upload_file, $a_filename)
storeUnzipedFile Stores Files unzipped from uploaded archive in filesystem
Class ilObject2 This is an intermediate progress of ilObject class.
setTitle($a_title)
set object title
cloneMetaData($target_obj)
Copy meta data.
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getDescription()
get object description
update()
update object in db
__construct($a_id=0, $a_reference=true)
Constructor @access public.
getTitle()
get object title @access public
doCloneObject($new_obj, $a_target_id, $a_copy_id=null)
getId()
get object id @access public
static copyPreviews($a_src_id, $a_dest_id)
Copies the preview images from one preview to a new preview object.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
const CLIENT_DATA_DIR
Definition: constants.php:44
global $DIC
Definition: goto.php:24
Interface FileStream The base interface for all filesystem streams.
Definition: FileStream.php:18
Interface ilObjFileImplementationInterface.
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$results
trait ilObjFileMetadata
Trait ilObjFileMetadata.
createProperties($a_upload=false)
The basic properties of a file object are stored in table object_data.
trait ilObjFileNews
Trait ilObjFileNews.
notifyCreation(int $obj_id, string $additional_message=null)
notifyUpdate(int $obj_id, string $additional_message=null)
trait ilObjFileSecureString
Trait ilObjFileSecureString.