ILIAS  release_8 Revision v8.24
class.ilObjFile.php
Go to the documentation of this file.
1<?php
2
26
35{
37 use ilObjFileUsages;
38 use ilObjFilePreviewHandler;
39 use ilObjFileNews;
41
42 public const MODE_FILELIST = "filelist";
43 public const MODE_OBJECT = "object";
44 public const OBJECT_TYPE = "file";
46
48
49 protected int $page_count = 0;
50 protected bool $rating = false;
51 protected ?ilLogger $log;
52 protected string $filename = '';
53 protected string $filetype = '';
54 protected int $filesize;
55 protected int $version = 1;
56 protected int $max_version = 1;
57 protected string $action = '';
58 protected ?string $resource_id = null;
59 public string $mode = self::MODE_OBJECT;
60 protected Manager $manager;
63
69 public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
70 {
71 global $DIC;
75 $this->manager = $DIC->resourceStorage()->manage();
76 $this->implementation = new ilObjFileImplementationEmpty();
77 $this->stakeholder = new ilObjFileStakeholder($DIC->user()->getId());
78 $this->upload = $DIC->upload();
79 $this->version = 0;
80 $this->max_version = 0;
81 $this->log = ilLoggerFactory::getLogger(self::OBJECT_TYPE);
82
83 parent::__construct($a_id, $a_call_by_reference);
84 $this->initFileInfo($a_id, $a_call_by_reference);
85 }
86
87 protected function initFileInfo(int $id, bool $is_ref_id): void
88 {
89 $repository = new ilObjFileInfoRepository(true);
90 if ($is_ref_id) {
91 $this->file_info = $repository->getByRefId($id);
92 } else {
93 $this->file_info = ($repository)->getByObjectId($id);
94 }
95 }
96
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($this->resource_id)) !== null) {
105 $resource = $this->manager->getResource($id);
106 $this->implementation = new ilObjFileImplementationStorage($resource);
107 $this->max_version = $resource->getMaxRevision();
108 $this->version = $resource->getMaxRevision();
109 }
110 $this->initFileInfo($this->getId(), false);
111 }
112
113 public function updateObjectFromCurrentRevision(): void
114 {
116 $this->manager->getCurrentRevision($this->manager->find($this->getResourceId())),
117 false
118 );
119 }
120
121 private function updateObjectFromRevision(Revision $r, bool $create_previews = true): void
122 {
123 $this->initFileInfo($this->getId(), false);
124 $this->setTitle(
125 $this->ensureSuffix(
126 $r->getTitle(),
127 $this->extractSuffixFromFilename($r->getInformation()->getTitle())
128 )
129 );
130 $this->setFileName($r->getInformation()->getTitle());
131 $this->update();
132 if ($create_previews) {
133 $this->createPreview(true);
134 }
135 }
136
137 public function appendSuffixToTitle(string $title, string $filename): string
138 {
139 $suffix = $this->file_info->getSuffix();
140 $filename_suffix = $this->extractSuffixFromFilename($filename);
141 if (empty($suffix) || $suffix !== $filename_suffix) {
142 $suffix = $filename_suffix;
143 }
144
145 $title = $this->ensureSuffix($title, $suffix);
146
147 return $title;
148 }
149
153 public function appendStream(FileStream $stream, string $title): int
154 {
155 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
156 $revision = $this->manager->appendNewRevisionFromStream($i, $stream, $this->stakeholder, $title);
157 } else {
158 $i = $this->manager->stream($stream, $this->stakeholder, $title);
159 $revision = $this->manager->getCurrentRevision($i);
160 $this->setResourceId($i->serialize());
161 $this->initImplementation();
162 }
163 $this->updateObjectFromRevision($revision);
164
165 return $revision->getVersionNumber();
166 }
167
171 public function appendUpload(UploadResult $result, string $title): int
172 {
173 $title = $this->appendSuffixToTitle($title, $result->getName());
174 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
175 $revision = $this->manager->appendNewRevision($i, $result, $this->stakeholder, $title);
176 } else {
177 $i = $this->manager->upload($result, $this->stakeholder, $title);
178 $revision = $this->manager->getCurrentRevision($i);
179 $this->setResourceId($i->serialize());
180 $this->initImplementation();
181 }
184 }
185 $this->updateObjectFromRevision($revision);
186
187 return $revision->getVersionNumber();
188 }
189
193 public function replaceWithStream(FileStream $stream, string $title): int
194 {
195 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
196 $revision = $this->manager->replaceWithStream($i, $stream, $this->stakeholder, $title);
197 } else {
198 throw new LogicException('only files with existing resource and revision can be replaced');
199 }
200 $this->updateObjectFromRevision($revision);
201
202 return $revision->getVersionNumber();
203 }
204
208 public function replaceWithUpload(UploadResult $result, string $title): int
209 {
210 $title = $this->appendSuffixToTitle($title, $result->getName());
211 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
212 $revision = $this->manager->replaceWithUpload($i, $result, $this->stakeholder, $title);
213 } else {
214 throw new LogicException('only files with existing resource and revision can be replaced');
215 }
218 }
219 $this->updateObjectFromRevision($revision);
220
221 return $revision->getVersionNumber();
222 }
223
227 public function getFile(?int $a_hist_entry_id = null): string
228 {
229 $this->initImplementation();
230 return $this->implementation->getFile($a_hist_entry_id);
231 }
232
233 public function getDirectory($a_version = 0): string
234 {
235 return $this->implementation->getDirectory($a_version);
236 }
237
238 public function getVersion(): int
239 {
240 return $this->implementation->getVersion();
241 }
242
243 public function setVersion(int $a_version): void
244 {
245 $this->version = $a_version;
246 }
247
248 public function getFileName(): string
249 {
250 return $this->filename;
251 }
252
253 public function setFileName(string $a_name): void
254 {
255 $this->filename = $a_name;
256 }
257
258 public function setRating(bool $a_value): void
259 {
260 $this->rating = $a_value;
261 }
262
263 public function setResourceId(?string $resource_id): self
264 {
265 $this->resource_id = $resource_id;
266 return $this;
267 }
268
269 public function getResourceId(): string
270 {
271 return $this->resource_id ?? '-';
272 }
273
274 public function getStorageID(): ?string
275 {
276 return $this->implementation->getStorageID();
277 }
278
279 public function getMode(): string
280 {
281 return $this->mode;
282 }
283
287 public function setMode(string $a_mode): void
288 {
289 $this->mode = $a_mode;
290 }
291
292 public function getFileSize(): int
293 {
294 return $this->implementation->getFileSize();
295 }
296
297 public function setFileSize(int $a_size): void
298 {
299 throw new LogicException('cannot change filesize');
300 }
301
302 public function getFileType(): string
303 {
304 return $this->implementation->getFileType();
305 }
306
307 public function setFileType(string $a_type): void
308 {
309 throw new LogicException('cannot change filetype');
310 }
311
312 public function hasRating(): bool
313 {
314 return $this->rating;
315 }
316
317 public function getMaxVersion(): int
318 {
319 return $this->max_version;
320 }
321
322 public function setMaxVersion(int $a_max_version): void
323 {
324 throw new LogicException('cannot change max-version');
325 }
326
327 public function getPageCount(): int
328 {
329 return $this->page_count;
330 }
331
332 public function setPageCount(int $page_count): void
333 {
334 $this->page_count = $page_count;
335 }
336
340 public function getAction(): string
341 {
342 return $this->action;
343 }
344
349 public function setAction(string $a_action): void
350 {
351 throw new LogicException('cannot change action');
352 }
353
354 public function handleChangedObjectTitle(string $new_title): void
355 {
356 $new_title = $this->ensureSuffix($new_title, $this->file_info->getSuffix());
357 $this->setTitle($new_title);
358 $this->implementation->handleChangedObjectTitle($new_title);
359 }
360
361
362 protected function doCreate(bool $clone_mode = false): void
363 {
364 $this->createProperties(true);
365 $this->notifyCreation($this->getId(), $this->getDescription());
366 }
367
368 protected function doRead(): void
369 {
370 global $DIC;
375 $q = "SELECT * FROM file_data WHERE file_id = %s";
376 $r = $DIC->database()->queryF($q, ['integer'], [$this->getId()]);
377 $row = $r->fetchObject();
378
379 $this->filename = $this->secure($row->file_name ?? '');
380 $this->filetype = $row->file_type ?? '';
381 $this->filesize = $row->file_size ?? 0;
382 $this->version = $row->version ?? 1;
383 $this->max_version = $row->max_version ?? 1;
384 $this->mode = $row->f_mode ?? self::MODE_OBJECT;
385 $this->rating = (bool) ($row->rating ?? false);
386 $this->page_count = (int) ($row->page_count ?? 0);
387 $this->resource_id = $row->rid ?? null;
388
389 $this->initImplementation();
390 }
391
392 protected function doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id = 0): void
393 {
394 assert($new_obj instanceof ilObjFile);
395 $identification = $this->manager->find($this->resource_id);
396 if ($identification === null) {
397 throw new RuntimeException('Cannot clone file since no corresponding resource identification was found');
398 }
399
400 $this->cloneMetaData($new_obj);
401 // object created now copy other settings
402 $new_obj->updateFileData();
403
404 // Copy Resource
405 $cloned_title = $new_obj->getTitle();
406 $new_resource_identification = $this->manager->clone($identification);
407 $new_current_revision = $this->manager->getCurrentRevision($new_resource_identification);
408 $new_obj->setResourceId($new_resource_identification->serialize());
409 $new_obj->initImplementation();
410 $new_obj->updateObjectFromRevision($new_current_revision, false); // Previews are already copied in 453
411 $new_obj->setTitle($cloned_title); // see https://mantis.ilias.de/view.php?id=31375
412 $new_obj->setPageCount($this->getPageCount());
413 $new_obj->update();
414
415 // Copy learning progress settings
416 $obj_settings = new ilLPObjSettings($this->getId());
417 $obj_settings->cloneSettings($new_obj->getId());
418 unset($obj_settings);
419 }
420
421 protected function doUpdate(): void
422 {
423 global $DIC;
424
425 $a_columns = $this->getArrayForDatabase();
426 $DIC->database()->update('file_data', $a_columns, [
427 'file_id' => [
428 'integer',
429 $this->getId(),
430 ],
431 ]);
432
433 // update metadata with the current file version
434 $meta_version_column = ['meta_version' => ['integer', $this->getVersion()]];
435 $DIC->database()->update('il_meta_lifecycle', $meta_version_column, [
436 'rbac_id' => [
437 'integer',
438 $this->getId(),
439 ],
440 ]);
441
442 $this->notifyUpdate($this->getId(), $this->getDescription());
443 $this->initImplementation();
444 }
445
446 protected function beforeUpdate(): bool
447 {
448 $this->setTitle($this->ensureSuffix($this->getTitle(), $this->file_info->getSuffix()));
449
450 // no meta data handling for file list files
451 if ($this->getMode() !== self::MODE_FILELIST) {
452 $this->updateMetaData();
453 }
454
455 return true;
456 }
457
458 protected function beforeDelete(): bool
459 {
460 // check, if file is used somewhere
461 $usages = $this->getUsages();
462 return count($usages) === 0;
463 }
464
465 protected function doDelete(): void
466 {
467 global $DIC;
468
469 // delete file data entry
470 $DIC->database()->manipulateF("DELETE FROM file_data WHERE file_id = %s", ['integer'], [$this->getId()]);
471
472 // delete history entries
474
475 // delete meta data
476 if ($this->getMode() != self::MODE_FILELIST) {
477 $this->deleteMetaData();
478 }
479
480 // delete preview
481 $this->deletePreview();
482
483 // delete resource
484 $identification = $this->getResourceId();
485 if ($identification && $identification != '-') {
486 $resource = $this->manager->find($identification);
487 if ($resource !== null) {
488 $this->manager->remove($resource, $this->stakeholder);
489 }
490 }
491 }
492
493 private function getArrayForDatabase(): array
494 {
495 return [
496 'file_id' => ['integer', $this->getId()],
497 'file_name' => ['text', $this->getFileName()],
498 'f_mode' => ['text', $this->getMode()],
499 'page_count' => ['text', $this->getPageCount()],
500 'rating' => ['integer', $this->hasRating()],
501 'rid' => ['text', $this->resource_id ?? ''],
502 ];
503 }
504
505 protected function initType(): void
506 {
507 $this->type = self::OBJECT_TYPE;
508 }
509
510 // Upload Handling
511
515 public function replaceFile($a_upload_file, $a_filename)
516 {
517 return null;
518 }
519
520 private function prepareUpload(): void
521 {
522 if (!$this->upload->hasBeenProcessed()) {
523 if (defined('PATH_TO_GHOSTSCRIPT') && PATH_TO_GHOSTSCRIPT !== "") {
524 $this->upload->register(new ilCountPDFPagesPreProcessors());
525 }
526
527 $this->upload->process();
528 }
529 }
530
536 public function getUploadFile($a_upload_file, string $title, bool $a_prevent_preview = false): bool
537 {
538 $this->prepareUpload();
539
540 $results = $this->upload->getResults();
541 $upload = $results[$a_upload_file];
542
543 $this->appendUpload($upload, $title);
544
545 return true;
546 }
547
551 public function isHidden(): bool
552 {
554 }
555
560 public function clearDataDirectory(): void
561 {
562 $this->implementation->clearDataDirectory();
563 }
564
569 public function deleteVersions($a_hist_entry_ids = null): void
570 {
571 $this->implementation->deleteVersions($a_hist_entry_ids);
572 }
573
574 public function sendFile(?int $a_hist_entry_id = null, bool $inline = true): void
575 {
576 $info = (new ilObjFileInfoRepository())->getByObjectId($this->getId());
577
578 $this->implementation->sendFile($a_hist_entry_id, $info->shouldDeliverInline());
579 }
580
584 public function export(string $a_target_dir): void
585 {
586 //
587 }
588
589
594 public function getVersions($version_ids = null): array
595 {
596 return $this->implementation->getVersions($version_ids);
597 }
598
603 public function rollback(int $version_id): void
604 {
605 if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
606 $this->manager->rollbackRevision($i, $version_id);
607 $latest_revision = $this->manager->getCurrentRevision($i);
608 $this->updateObjectFromRevision($latest_revision);
609 } else {
610 throw new LogicException('only files with existing resource and revision can be replaced');
611 }
612 }
613
617 public function checkFileExtension(string $new_filename, string $new_title): string
618 {
619 return $this->appendSuffixToTitle($new_title, $new_filename);
620 }
621
625 public function getFileExtension(): string
626 {
627 return $this->implementation->getFileExtension();
628 }
629}
Customizing of pimple-DIC for ILIAS.
Definition: Container.php:32
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
string $resource_id
setMode(string $a_mode)
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)
string $filename
setAction(string $a_action)
appendSuffixToTitle(string $title, string $filename)
setMaxVersion(int $a_max_version)
updateObjectFromRevision(Revision $r, bool $create_previews=true)
replaceWithUpload(UploadResult $result, string $title)
setFileSize(int $a_size)
checkFileExtension(string $new_filename, string $new_title)
ilLogger $log
setFileType(string $a_type)
replaceWithStream(FileStream $stream, string $title)
getVersions($version_ids=null)
getPresentationTitle()
get presentation title Normally same as title Overwritten for sessions
FileUpload $upload
deleteVersions($a_hist_entry_ids=null)
@ineritdoc
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)
getDirectory($a_version=0)
setPageCount(int $page_count)
export(string $a_target_dir)
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
setFileName(string $a_name)
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...
__construct(int $a_id=0, bool $a_reference=true)
Constructor.
cloneMetaData(ilObject $target_obj)
Copy meta data.
string $title
setTitle(string $title)
global $DIC
Definition: feed.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$i
Definition: metadata.php:41
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$results
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...
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)