ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjFile.php
Go to the documentation of this file.
1<?php
2
27
36{
38 use ilObjFileUsages;
39 use ilObjFileNews;
41
42 public const MODE_FILELIST = "filelist";
43 public const MODE_OBJECT = "object";
44 public const OBJECT_TYPE = "file";
45 public const CLICK_MODE_DOWNLOAD = 1;
46 public const CLICK_MODE_INFOPAGE = 2;
48
50
51 protected ?string $important_info = null;
52 protected int $page_count = 0;
53 protected bool $rating = false;
54 protected ?ilLogger $log;
55 protected string $filename = '';
56 protected string $filetype = '';
57 protected int $filesize;
58 protected int $version = 0;
59 protected int $max_version = 0;
60 protected ?string $copyright_id = null;
61 protected string $action = '';
62 protected ?string $resource_id = null;
63 public string $mode = self::MODE_OBJECT;
64 protected Manager $manager;
69 protected int $amount_of_downloads = 0;
70
76 public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
77 {
78 global $DIC;
79 $this->manager = $DIC->resourceStorage()->manage();
80 $this->database = $DIC->database();
81 $this->implementation = new ilObjFileImplementationEmpty();
82 $this->stakeholder = new ilObjFileStakeholder($DIC->user()->getId());
83 $this->upload = $DIC->upload();
84 $this->log = ilLoggerFactory::getLogger(self::OBJECT_TYPE);
85
86 parent::__construct($a_id, $a_call_by_reference);
87 $this->initFileInfo($a_id, $a_call_by_reference);
88 }
89
90 protected function initFileInfo(int $id, bool $is_ref_id): void
91 {
92 $repository = new ilObjFileInfoRepository();
93 $this->file_info = $is_ref_id ? $repository->getByRefId($id) : $repository->getByObjectId($id);
94 }
95
96 #[\Override]
97 public function getPresentationTitle(): string
98 {
99 return $this->file_info->getHeaderTitle();
100 }
101
102 protected function initImplementation(): void
103 {
104 if ($this->resource_id && ($id = $this->manager->find(
105 $this->resource_id
106 )) instanceof ResourceIdentification) {
107 $resource = $this->manager->getResource($id);
108 $this->implementation = new ilObjFileImplementationStorage($resource);
109 $this->max_version = $resource->getMaxRevision(false);
110 $this->version = $resource->getCurrentRevision()->getVersionNumber();
111 }
112 $this->initFileInfo($this->getId(), false);
113 }
114
115 public function updateObjectFromCurrentRevision(): void
116 {
118 $this->manager->getCurrentRevision($this->manager->find($this->getResourceId()))
119 );
120 }
121
122 private function updateObjectFromRevision(Revision $r): void
123 {
124 $this->initFileInfo($this->getId(), false);
125 $this->setTitle(
126 $this->ensureSuffix(
127 $r->getTitle(),
128 $this->extractSuffixFromFilename($r->getInformation()->getTitle())
129 )
130 );
131 $this->setFileName($r->getInformation()->getTitle());
132 $this->update();
133 }
134
135 public function appendSuffixToTitle(string $title, string $filename): string
136 {
137 $suffix = $this->file_info->getSuffix();
138 $filename_suffix = $this->extractSuffixFromFilename($filename);
139 if (empty($suffix) || $suffix !== $filename_suffix) {
140 $suffix = $filename_suffix;
141 }
142
143 return $this->ensureSuffix($title, $suffix);
144 }
145
149 public function appendStream(FileStream $stream, string $title): int
150 {
151 $title = $this->ensureSuffix(
152 $title,
153 $this->extractSuffixFromFilename($title)
154 ?? pathinfo($stream->getMetadata('uri'))['extension']
155 ?? null
156 );
157 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
158 $revision = $this->manager->appendNewRevisionFromStream($i, $stream, $this->stakeholder, $title);
159 } else {
160 $i = $this->manager->stream($stream, $this->stakeholder, $title);
161 $revision = $this->manager->getCurrentRevision($i);
162 $this->setResourceId($i->serialize());
163 $this->initImplementation();
164 }
165 $this->enableNotification();
166 $this->updateObjectFromRevision($revision);
167
168 return $revision->getVersionNumber();
169 }
170
174 public function appendUpload(UploadResult $result, string $title): int
175 {
176 $title = $this->appendSuffixToTitle($title, $result->getName());
177 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
178 $revision = $this->manager->appendNewRevision($i, $result, $this->stakeholder, $title);
179 } else {
180 $i = $this->manager->upload($result, $this->stakeholder, $title);
181 $revision = $this->manager->getCurrentRevision($i);
182 $this->setResourceId($i->serialize());
183 $this->initImplementation();
184 }
187 }
188 $this->enableNotification();
189 $this->updateObjectFromRevision($revision);
190
191 return $revision->getVersionNumber();
192 }
193
197 public function replaceWithStream(FileStream $stream, string $title): int
198 {
199 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
200 $revision = $this->manager->replaceWithStream($i, $stream, $this->stakeholder, $title);
201 } else {
202 throw new LogicException('only files with existing resource and revision can be replaced');
203 }
204 $this->enableNotification();
205 $this->updateObjectFromRevision($revision);
206
207 return $revision->getVersionNumber();
208 }
209
213 public function replaceWithUpload(UploadResult $result, string $title): int
214 {
215 $title = $this->appendSuffixToTitle($title, $result->getName());
216 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
217 $revision = $this->manager->replaceWithUpload($i, $result, $this->stakeholder, $title);
218 } else {
219 throw new LogicException('only files with existing resource and revision can be replaced');
220 }
223 }
224 $this->enableNotification();
225 $this->updateObjectFromRevision($revision);
226
227 return $revision->getVersionNumber();
228 }
229
233 public function getFile(?int $a_hist_entry_id = null): string
234 {
235 $this->initImplementation();
236 return $this->implementation->getFile($a_hist_entry_id);
237 }
238
239 public function getDirectory($a_version = 0): string
240 {
241 return $this->implementation->getDirectory($a_version);
242 }
243
244 public function getDownloadFilename(): string
245 {
246 return $this->implementation->getDownloadFilename();
247 }
248
249 public function getImportantInfo(): ?string
250 {
252 }
253
254 public function setImportantInfo(string $a_important_info): void
255 {
256 $this->important_info = empty($a_important_info) ? null : $a_important_info;
257 }
258
259 public function getVersion(bool $inclduing_drafts = false): int
260 {
261 return $this->implementation->getVersion($inclduing_drafts);
262 }
263
264 public function setVersion(int $a_version): void
265 {
266 $this->version = $a_version;
267 }
268
269 public function getFileName(): string
270 {
271 return $this->implementation->getFileName();
272 }
273
274 public function setFileName(string $a_name): void
275 {
276 $this->filename = $a_name;
277 }
278
279 public function setRating(bool $a_value): void
280 {
281 $this->rating = $a_value;
282 }
283
284 public function setResourceId(?string $resource_id): self
285 {
286 $this->resource_id = $resource_id;
287 return $this;
288 }
289
290 public function getResourceId(): string
291 {
292 return $this->resource_id ?? '-';
293 }
294
295 public function getStorageID(): ?string
296 {
297 return $this->implementation->getStorageID();
298 }
299
300 public function getMode(): string
301 {
302 return $this->mode;
303 }
304
308 public function setMode(string $a_mode): void
309 {
310 $this->mode = $a_mode;
311 }
312
313 public function getFileSize(): int
314 {
315 return $this->implementation->getFileSize();
316 }
317
321 public function setFileSize(int $a_size): void
322 {
323 throw new LogicException('cannot change filesize');
324 }
325
326 public function getFileType(): string
327 {
328 return $this->implementation->getFileType();
329 }
330
334 public function setFileType(string $a_type): void
335 {
336 throw new LogicException('cannot change filetype');
337 }
338
339 public function hasRating(): bool
340 {
341 return $this->rating;
342 }
343
344 public function getMaxVersion(): int
345 {
346 return $this->max_version;
347 }
348
352 public function setMaxVersion(int $a_max_version): void
353 {
354 throw new LogicException('cannot change max-version');
355 }
356
357 public function getCopyrightID(): ?string
358 {
359 return $this->copyright_id;
360 }
361
362 public function setCopyrightID(?string $copyright_id): void
363 {
364 $this->copyright_id = $copyright_id;
365 }
366
367 public function getPageCount(): int
368 {
369 return $this->page_count;
370 }
371
372 public function setPageCount(int $page_count): void
373 {
374 $this->page_count = $page_count;
375 }
376
380 public function getAction(): string
381 {
382 return $this->action;
383 }
384
385 public function directDownload(): bool
386 {
387 return $this->on_click_mode === self::CLICK_MODE_DOWNLOAD;
388 }
389
390 public function getOnClickMode(): int
391 {
393 }
394
395 public function setOnclickMode(int $on_click_mode): void
396 {
397 $this->on_click_mode = $on_click_mode;
398 }
399
400 public function getAmountOfDownloads(): int
401 {
403 }
404
405 public function setAmountOfDownloads(int $amount): void
406 {
407 if (0 > $amount) {
408 throw new LogicException("Amount cannot be a negative number.");
409 }
410
411 $this->amount_of_downloads = $amount;
412 }
413
414 public function getLPMode(): int
415 {
416 return ilObjectLP::getInstance($this->getId())->getCurrentMode();
417 }
418
424 public function setAction(string $a_action): void
425 {
426 throw new LogicException('cannot change action');
427 }
428
429 public function handleChangedObjectTitle(string $new_title): void
430 {
431 $new_title = $this->ensureSuffix($new_title, $this->file_info->getSuffix());
432 $this->setTitle($new_title);
433 $this->implementation->handleChangedObjectTitle($new_title);
434 }
435
436 protected function doCreate(bool $clone_mode = false): void
437 {
438 $this->createProperties(true);
439 $this->updateCopyright();
440 $this->getObjectProperties()->storePropertyIsOnline(new Online(true));
441 $this->notifyCreation($this->getId(), $this->getDescription());
442 }
443
444 protected function doRead(): void
445 {
446 $q = "SELECT * FROM file_data WHERE file_id = %s";
447 $r = $this->database->queryF($q, ['integer'], [$this->getId()]);
448 $row = $r->fetchObject();
449
450 $this->filename = $this->secure($row->file_name ?? '');
451 $this->filetype = $row->file_type ?? '';
452 $this->filesize = $row->file_size ?? 0;
453 $this->version = $row->version ?? 1;
454 $this->max_version = $row->max_version ?? 1;
455 $this->mode = $row->f_mode ?? self::MODE_OBJECT;
456 $this->important_info = $row->important_info ?? "";
457 $this->rating = (bool) ($row->rating ?? false);
458 $this->page_count = (int) ($row->page_count ?? 0);
459 $this->resource_id = $row->rid ?? null;
460 $this->on_click_mode = (int) ($row->on_click_mode ?? self::CLICK_MODE_DOWNLOAD);
461 $this->amount_of_downloads = (int) ($row->downloads ?? 0);
462
463 $this->initImplementation();
464 }
465
466 protected function doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id = 0): void
467 {
468 assert($new_obj instanceof ilObjFile);
469 $identification = $this->manager->find($this->resource_id);
470 if ($identification === null) {
471 throw new RuntimeException('Cannot clone file since no corresponding resource identification was found');
472 }
473
474 $this->cloneMetaData($new_obj);
475 // object created now copy other settings
476 $new_obj->updateFileData();
477
478 // Copy Resource
479 $cloned_title = $new_obj->getTitle();
480 $new_resource_identification = $this->manager->clone($identification);
481 $new_current_revision = $this->manager->getCurrentRevision($new_resource_identification);
482 $new_obj->setResourceId($new_resource_identification->serialize());
483 $new_obj->initImplementation();
484 $new_obj->updateObjectFromRevision($new_current_revision); // Previews are already copied in 453
485 $new_obj->setTitle($cloned_title); // see https://mantis.ilias.de/view.php?id=31375
486 $new_obj->setPageCount($this->getPageCount());
487 $new_obj->setImportantInfo($this->getImportantInfo());
488 $new_obj->setRating($this->hasRating());
489 $new_obj->setOnclickMode($this->getOnClickMode());
490 $new_obj->update();
491
492 $new_obj->getObjectProperties()->storePropertyIsOnline(new Online(true));
493
494 // Copy learning progress settings
495 $obj_settings = new ilLPObjSettings($this->getId());
496 $obj_settings->cloneSettings($new_obj->getId());
497 unset($obj_settings);
498 }
499
500 protected function doUpdate(): void
501 {
502 $a_columns = $this->getArrayForDatabase();
503 $this->database->update('file_data', $a_columns, [
504 'file_id' => [
505 'integer',
506 $this->getId(),
507 ],
508 ]);
509
510 $this->notifyUpdate($this->getId(), $this->getDescription());
511 $this->initImplementation();
512 }
513
514 #[\Override]
515 protected function beforeUpdate(): bool
516 {
517 $suffix = $this->file_info->getSuffix();
518 if (empty($suffix)) {
519 $suffix = $this->extractSuffixFromFilename($this->getTitle());
520 }
521 $this->setTitle($this->ensureSuffix($this->getTitle(), $suffix));
522
523 // no meta data handling for file list files
524 if ($this->getMode() !== self::MODE_FILELIST) {
525 $this->updateMetaData();
526 $this->updateCopyright();
527 }
528
529 return true;
530 }
531
532 #[\Override]
533 protected function beforeDelete(): bool
534 {
535 // check, if file is used somewhere
536 $usages = $this->getUsages();
537 return $usages === [];
538 }
539
540 protected function doDelete(): void
541 {
542 // delete file data entry
543 $this->database->manipulateF("DELETE FROM file_data WHERE file_id = %s", ['integer'], [$this->getId()]);
544
545 // delete history entries
547
548 // delete meta data
549 if ($this->getMode() !== self::MODE_FILELIST) {
550 $this->deleteMetaData();
551 }
552
553 // delete resource
554 $identification = $this->getResourceId();
555 if ($identification && $identification !== '-') {
556 $resource = $this->manager->find($identification);
557 if ($resource !== null) {
558 $this->manager->remove($resource, $this->stakeholder);
559 }
560 }
561 }
562
566 private function getArrayForDatabase(): array
567 {
568 return [
569 'file_id' => ['integer', $this->getId()],
570 'file_name' => ['text', $this->getFileName()],
571 'f_mode' => ['text', $this->getMode()],
572 'important_info' => ['text', $this->getImportantInfo()],
573 'page_count' => ['text', $this->getPageCount()],
574 'rating' => ['integer', $this->hasRating()],
575 'rid' => ['text', $this->resource_id ?? ''],
576 'on_click_mode' => ['integer', $this->getOnClickMode()],
577 'downloads' => ['integer', $this->getAmountOfDownloads()],
578 ];
579 }
580
581 protected function initType(): void
582 {
583 $this->type = self::OBJECT_TYPE;
584 }
585
586 // Upload Handling
587
591 public function replaceFile($a_upload_file, $a_filename): null
592 {
593 return null;
594 }
595
596 private function prepareUpload(): void
597 {
598 if (!$this->upload->hasBeenProcessed()) {
599 if (defined('PATH_TO_GHOSTSCRIPT') && PATH_TO_GHOSTSCRIPT !== "") {
600 $this->upload->register(new ilCountPDFPagesPreProcessors());
601 }
602
603 $this->upload->process();
604 }
605 }
606
612 public function getUploadFile($a_upload_file, string $title, bool $a_prevent_preview = false): bool
613 {
614 $this->prepareUpload();
615
616 $results = $this->upload->getResults();
617 $upload = $results[$a_upload_file];
618
619 $this->appendUpload($upload, $title);
620
621 return true;
622 }
623
627 public function isHidden(): bool
628 {
630 }
631
636 public function clearDataDirectory(): void
637 {
638 $this->implementation->clearDataDirectory();
639 }
640
645 public function deleteVersions($a_hist_entry_ids = null): void
646 {
647 $this->implementation->deleteVersions($a_hist_entry_ids);
648 // update file object as the deletion of versions might affect its attributes (title, max_version etc.)
649 if ($this->getResourceId() && $rid = $this->manager->find($this->getResourceId())) {
650 $latest_revision = $this->manager->getCurrentRevision($rid);
651 $this->updateObjectFromRevision($latest_revision);
652 }
653 }
654
655 public function sendFile(?int $a_hist_entry_id = null, bool $inline = true): void
656 {
657 // increment file download count by one.
658 $this->setAmountOfDownloads($this->getAmountOfDownloads() + 1);
659 $this->update();
660 $info = (new ilObjFileInfoRepository())->getByObjectId($this->getId());
661 $this->implementation->sendFile($a_hist_entry_id, $info->shouldDeliverInline());
662 }
663
667 public function export(string $a_target_dir): void
668 {
669 //
670 }
671
676 public function getVersions($version_ids = null): array
677 {
678 return $this->implementation->getVersions($version_ids);
679 }
680
685 public function rollback(int $version_id): void
686 {
687 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
688 $this->manager->rollbackRevision($i, $version_id);
689 $latest_revision = $this->manager->getCurrentRevision($i);
690 $this->updateObjectFromRevision($latest_revision);
691 } else {
692 throw new LogicException('only files with existing resource and revision can be replaced');
693 }
694 }
695
699 public function checkFileExtension(string $new_filename, string $new_title): string
700 {
701 return $this->appendSuffixToTitle($new_title, $new_filename);
702 }
703
704 public function getFileExtension(): string
705 {
706 return $this->implementation->getFileExtension();
707 }
708
709 public function stripTitleOfFileExtension(string $a_title): string
710 {
711 return $this->secure(preg_replace('/\.[^.]*$/', '', $a_title));
712 }
713}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Class ilCountPDFPagesPreProcessors.
static _removeEntriesForObject(int $a_obj_id)
remove all history entries for an object
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static _isFileHidden(string $a_file_name)
Returns true, if a file with the specified name, is usually hidden from the user.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilObjFileImplementationStorage.
Class ilObjFileStakeholder.
Class ilObjFile.
updateObjectFromCurrentRevision()
handleChangedObjectTitle(string $new_title)
string $filetype
__construct(int $a_id=0, bool $a_call_by_reference=true)
ilObjFile constructor.
string $resource_id
setMode(string $a_mode)
setAmountOfDownloads(int $amount)
clearDataDirectory()
@ineritdoc
appendStream(FileStream $stream, string $title)
setRating(bool $a_value)
ilObjFileImplementationInterface $implementation
const MODE_FILELIST
const MODE_OBJECT
sendFile(?int $a_hist_entry_id=null, bool $inline=true)
setCopyrightID(?string $copyright_id)
string $filename
setAction(string $a_action)
appendSuffixToTitle(string $title, string $filename)
setMaxVersion(int $a_max_version)
string $copyright_id
string $important_info
replaceWithUpload(UploadResult $result, string $title)
setFileSize(int $a_size)
checkFileExtension(string $new_filename, string $new_title)
ilLogger $log
getVersion(bool $inclduing_drafts=false)
setFileType(string $a_type)
stripTitleOfFileExtension(string $a_title)
replaceWithStream(FileStream $stream, string $title)
int $amount_of_downloads
getVersions($version_ids=null)
getPresentationTitle()
get presentation title Normally same as title Overwritten for sessions
FileUpload $upload
deleteVersions($a_hist_entry_ids=null)
@ineritdoc
setImportantInfo(string $a_important_info)
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)
setVersion(int $a_version)
updateObjectFromRevision(Revision $r)
getDirectory($a_version=0)
setPageCount(int $page_count)
ilDBInterface $database
const CLICK_MODE_DOWNLOAD
export(string $a_target_dir)
const CLICK_MODE_INFOPAGE
string $action
initFileInfo(int $id, bool $is_ref_id)
const OBJECT_TYPE
getFile(?int $a_hist_entry_id=null)
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
setOnclickMode(int $on_click_mode)
setFileName(string $a_name)
getFileExtension()
Returns the extension of the file name converted to lower-case.
doCreate(bool $clone_mode=false)
ilObjFileStakeholder $stakeholder
Manager $manager
doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id=0)
ilObjFileInfo $file_info
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
cloneMetaData(ilObject $target_obj)
Copy meta data.
static getInstance(int $obj_id)
string $title
setTitle(string $title)
$info
Definition: entry_point.php:21
The base interface for all filesystem streams.
Definition: FileStream.php:32
Interface ilDBInterface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$results
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
createProperties(bool $a_upload=false)
The basic properties of a file object are stored in table object_data.
trait ilObjFileMetadata
Trait ilObjFileMetadata.
trait ilObjFileNews
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
enableNotification()
notifyCreation(int $obj_id, ?string $additional_message=null)
notifyUpdate(int $obj_id, ?string $additional_message=null)
trait ilObjFileSecureString
Trait ilObjFileSecureString.
ensureSuffix(string $title, ?string $suffix=null)
extractSuffixFromFilename(string $filename)