ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilObjFile.php
Go to the documentation of this file.
1 <?php
2 
25 
34 {
36  use ilObjFileUsages;
37  use ilObjFileNews;
39 
40  public const MODE_FILELIST = "filelist";
41  public const MODE_OBJECT = "object";
42  public const OBJECT_TYPE = "file";
43  public const CLICK_MODE_DOWNLOAD = 1;
44  public const CLICK_MODE_INFOPAGE = 2;
46 
48 
49  protected ?string $important_info = null;
50  protected int $page_count = 0;
51  protected bool $rating = false;
52  protected ?ilLogger $log;
53  protected string $filename = '';
54  protected string $filetype = '';
55  protected int $filesize;
56  protected int $version = 1;
57  protected int $max_version = 1;
58  protected ?int $copyright_id = null;
59  protected string $action = '';
60  protected ?string $resource_id = null;
61  public string $mode = self::MODE_OBJECT;
62  protected Manager $manager;
63  protected FileUpload $upload;
66  protected int $on_click_mode = self::CLICK_MODE_DOWNLOAD;
67  protected int $amount_of_downloads = 0;
68 
74  public function __construct(int $a_id = 0, bool $a_call_by_reference = true)
75  {
76  global $DIC;
77  $this->manager = $DIC->resourceStorage()->manage();
78  $this->database = $DIC->database();
79  $this->implementation = new ilObjFileImplementationEmpty();
80  $this->stakeholder = new ilObjFileStakeholder($DIC->user()->getId());
81  $this->upload = $DIC->upload();
82  $this->version = 0;
83  $this->max_version = 0;
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  if ($is_ref_id) {
94  $this->file_info = $repository->getByRefId($id);
95  } else {
96  $this->file_info = $repository->getByObjectId($id);
97  }
98  }
99 
100  public function getPresentationTitle(): string
101  {
102  return $this->file_info->getHeaderTitle();
103  }
104 
105  protected function initImplementation(): void
106  {
107  if ($this->resource_id && ($id = $this->manager->find(
108  $this->resource_id
109  )) instanceof \ILIAS\ResourceStorage\Identification\ResourceIdentification) {
110  $resource = $this->manager->getResource($id);
111  $this->implementation = new ilObjFileImplementationStorage($resource);
112  $this->max_version = $resource->getMaxRevision(false);
113  $this->version = $resource->getCurrentRevision()->getVersionNumber();
114  }
115  $this->initFileInfo($this->getId(), false);
116  }
117 
118  public function updateObjectFromCurrentRevision(): void
119  {
121  $this->manager->getCurrentRevision($this->manager->find($this->getResourceId()))
122  );
123  }
124 
125  private function updateObjectFromRevision(Revision $r): void
126  {
127  $this->initFileInfo($this->getId(), false);
128  $this->setTitle(
129  $this->ensureSuffix(
130  $r->getTitle(),
131  $this->extractSuffixFromFilename($r->getInformation()->getTitle())
132  )
133  );
134  $this->setFileName($r->getInformation()->getTitle());
135  $this->update();
136  }
137 
138  public function appendSuffixToTitle(string $title, string $filename): string
139  {
140  $suffix = $this->file_info->getSuffix();
141  $filename_suffix = $this->extractSuffixFromFilename($filename);
142  if (empty($suffix) || $suffix !== $filename_suffix) {
143  $suffix = $filename_suffix;
144  }
145 
146  $title = $this->ensureSuffix($title, $suffix);
147 
148  return $title;
149  }
150 
154  public function appendStream(FileStream $stream, string $title): int
155  {
156  $title = $this->ensureSuffix(
157  $title,
158  $this->extractSuffixFromFilename($title)
159  ?? pathinfo($stream->getMetadata('uri'))['extension']
160  ?? null
161  );
162  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
163  $revision = $this->manager->appendNewRevisionFromStream($i, $stream, $this->stakeholder, $title);
164  } else {
165  $i = $this->manager->stream($stream, $this->stakeholder, $title);
166  $revision = $this->manager->getCurrentRevision($i);
167  $this->setResourceId($i->serialize());
168  $this->initImplementation();
169  }
170  $this->enableNotification();
171  $this->updateObjectFromRevision($revision);
172 
173  return $revision->getVersionNumber();
174  }
175 
179  public function appendUpload(UploadResult $result, string $title): int
180  {
181  $title = $this->appendSuffixToTitle($title, $result->getName());
182  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
183  $revision = $this->manager->appendNewRevision($i, $result, $this->stakeholder, $title);
184  } else {
185  $i = $this->manager->upload($result, $this->stakeholder, $title);
186  $revision = $this->manager->getCurrentRevision($i);
187  $this->setResourceId($i->serialize());
188  $this->initImplementation();
189  }
192  }
193  $this->enableNotification();
194  $this->updateObjectFromRevision($revision);
195 
196  return $revision->getVersionNumber();
197  }
198 
202  public function replaceWithStream(FileStream $stream, string $title): int
203  {
204  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
205  $revision = $this->manager->replaceWithStream($i, $stream, $this->stakeholder, $title);
206  } else {
207  throw new LogicException('only files with existing resource and revision can be replaced');
208  }
209  $this->enableNotification();
210  $this->updateObjectFromRevision($revision);
211 
212  return $revision->getVersionNumber();
213  }
214 
218  public function replaceWithUpload(UploadResult $result, string $title): int
219  {
220  $title = $this->appendSuffixToTitle($title, $result->getName());
221  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
222  $revision = $this->manager->replaceWithUpload($i, $result, $this->stakeholder, $title);
223  } else {
224  throw new LogicException('only files with existing resource and revision can be replaced');
225  }
228  }
229  $this->enableNotification();
230  $this->updateObjectFromRevision($revision);
231 
232  return $revision->getVersionNumber();
233  }
234 
238  public function getFile(?int $a_hist_entry_id = null): string
239  {
240  $this->initImplementation();
241  return $this->implementation->getFile($a_hist_entry_id);
242  }
243 
244  public function getDirectory($a_version = 0): string
245  {
246  return $this->implementation->getDirectory($a_version);
247  }
248 
249  public function getDownloadFilename(): string
250  {
251  return $this->implementation->getDownloadFilename();
252  }
253 
254  public function getImportantInfo(): ?string
255  {
256  return $this->important_info;
257  }
258 
259  public function setImportantInfo(string $a_important_info): void
260  {
261  $this->important_info = empty($a_important_info) ? null : $a_important_info;
262  }
263 
264  public function getVersion(bool $inclduing_drafts = false): int
265  {
266  return $this->implementation->getVersion($inclduing_drafts);
267  }
268 
269  public function setVersion(int $a_version): void
270  {
271  $this->version = $a_version;
272  }
273 
274  public function getFileName(): string
275  {
276  return $this->implementation->getFileName();
277  }
278 
279  public function setFileName(string $a_name): void
280  {
281  $this->filename = $a_name;
282  }
283 
284  public function setRating(bool $a_value): void
285  {
286  $this->rating = $a_value;
287  }
288 
289  public function setResourceId(?string $resource_id): self
290  {
291  $this->resource_id = $resource_id;
292  return $this;
293  }
294 
295  public function getResourceId(): string
296  {
297  return $this->resource_id ?? '-';
298  }
299 
300  public function getStorageID(): ?string
301  {
302  return $this->implementation->getStorageID();
303  }
304 
305  public function getMode(): string
306  {
307  return $this->mode;
308  }
309 
313  public function setMode(string $a_mode): void
314  {
315  $this->mode = $a_mode;
316  }
317 
318  public function getFileSize(): int
319  {
320  return $this->implementation->getFileSize();
321  }
322 
326  public function setFileSize(int $a_size): void
327  {
328  throw new LogicException('cannot change filesize');
329  }
330 
331  public function getFileType(): string
332  {
333  return $this->implementation->getFileType();
334  }
335 
339  public function setFileType(string $a_type): void
340  {
341  throw new LogicException('cannot change filetype');
342  }
343 
344  public function hasRating(): bool
345  {
346  return $this->rating;
347  }
348 
349  public function getMaxVersion(): int
350  {
351  return $this->max_version;
352  }
353 
357  public function setMaxVersion(int $a_max_version): void
358  {
359  throw new LogicException('cannot change max-version');
360  }
361 
362  public function getCopyrightID(): ?int
363  {
364  return $this->copyright_id;
365  }
366 
367  public function setCopyrightID(?int $copyright_id): void
368  {
369  $this->copyright_id = $copyright_id;
370  }
371 
372  public function getPageCount(): int
373  {
374  return $this->page_count;
375  }
376 
377  public function setPageCount(int $page_count): void
378  {
379  $this->page_count = $page_count;
380  }
381 
385  public function getAction(): string
386  {
387  return $this->action;
388  }
389 
390  public function directDownload(): bool
391  {
392  return $this->on_click_mode === self::CLICK_MODE_DOWNLOAD;
393  }
394 
395  public function getOnClickMode(): int
396  {
397  return $this->on_click_mode;
398  }
399 
400  public function setOnclickMode(int $on_click_mode): void
401  {
402  $this->on_click_mode = $on_click_mode;
403  }
404 
405  public function getAmountOfDownloads(): int
406  {
408  }
409 
410  public function setAmountOfDownloads(int $amount): void
411  {
412  if (0 > $amount) {
413  throw new LogicException("Amount cannot be a negative number.");
414  }
415 
416  $this->amount_of_downloads = $amount;
417  }
418 
419  public function getLPMode(): int
420  {
421  return ilObjectLP::getInstance($this->getId())->getCurrentMode();
422  }
423 
429  public function setAction(string $a_action): void
430  {
431  throw new LogicException('cannot change action');
432  }
433 
434  public function handleChangedObjectTitle(string $new_title): void
435  {
436  $new_title = $this->ensureSuffix($new_title, $this->file_info->getSuffix());
437  $this->setTitle($new_title);
438  $this->implementation->handleChangedObjectTitle($new_title);
439  }
440 
441  protected function doCreate(bool $clone_mode = false): void
442  {
443  $this->createProperties(true);
444  $this->updateCopyright();
445  $this->getObjectProperties()->storePropertyIsOnline(new ilObjectPropertyIsOnline(true));
446  $this->notifyCreation($this->getId(), $this->getDescription());
447  }
448 
449  protected function doRead(): void
450  {
451  $q = "SELECT * FROM file_data WHERE file_id = %s";
452  $r = $this->database->queryF($q, ['integer'], [$this->getId()]);
453  $row = $r->fetchObject();
454 
455  $this->filename = $this->secure($row->file_name ?? '');
456  $this->filetype = $row->file_type ?? '';
457  $this->filesize = $row->file_size ?? 0;
458  $this->version = $row->version ?? 1;
459  $this->max_version = $row->max_version ?? 1;
460  $this->mode = $row->f_mode ?? self::MODE_OBJECT;
461  $this->important_info = $row->important_info ?? "";
462  $this->rating = (bool) ($row->rating ?? false);
463  $this->page_count = (int) ($row->page_count ?? 0);
464  $this->resource_id = $row->rid ?? null;
465  $this->on_click_mode = (int) ($row->on_click_mode ?? self::CLICK_MODE_DOWNLOAD);
466  $this->amount_of_downloads = (int) ($row->downloads ?? 0);
467 
468  $this->initImplementation();
469  }
470 
471  protected function doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id = 0): void
472  {
473  assert($new_obj instanceof ilObjFile);
474  $identification = $this->manager->find($this->resource_id);
475  if ($identification === null) {
476  throw new RuntimeException('Cannot clone file since no corresponding resource identification was found');
477  }
478 
479  $this->cloneMetaData($new_obj);
480  // object created now copy other settings
481  $new_obj->updateFileData();
482 
483  // Copy Resource
484  $cloned_title = $new_obj->getTitle();
485  $new_resource_identification = $this->manager->clone($identification);
486  $new_current_revision = $this->manager->getCurrentRevision($new_resource_identification);
487  $new_obj->setResourceId($new_resource_identification->serialize());
488  $new_obj->initImplementation();
489  $new_obj->updateObjectFromRevision($new_current_revision); // Previews are already copied in 453
490  $new_obj->setTitle($cloned_title); // see https://mantis.ilias.de/view.php?id=31375
491  $new_obj->setPageCount($this->getPageCount());
492  $new_obj->update();
493 
494  $new_obj->getObjectProperties()->storePropertyIsOnline(new ilObjectPropertyIsOnline(true));
495 
496  // Copy learning progress settings
497  $obj_settings = new ilLPObjSettings($this->getId());
498  $obj_settings->cloneSettings($new_obj->getId());
499  unset($obj_settings);
500  }
501 
502  protected function doUpdate(): void
503  {
504  $a_columns = $this->getArrayForDatabase();
505  $this->database->update('file_data', $a_columns, [
506  'file_id' => [
507  'integer',
508  $this->getId(),
509  ],
510  ]);
511 
512  $this->notifyUpdate($this->getId(), $this->getDescription());
513  $this->initImplementation();
514  }
515 
516  protected function beforeUpdate(): bool
517  {
518  $suffix = $this->file_info->getSuffix();
519  if (empty($suffix)) {
520  $suffix = $this->extractSuffixFromFilename($this->getTitle());
521  }
522  $this->setTitle($this->ensureSuffix($this->getTitle(), $suffix));
523 
524  // no meta data handling for file list files
525  if ($this->getMode() !== self::MODE_FILELIST) {
526  $this->updateMetaData();
527  $this->updateCopyright();
528  }
529 
530  return true;
531  }
532 
533  protected function beforeDelete(): bool
534  {
535  // check, if file is used somewhere
536  $usages = $this->getUsages();
537  return count($usages) === 0;
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)
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  {
629  return ilObjFileAccess::_isFileHidden($this->getTitle());
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 }
string $title
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilObjFileStakeholder.
setCopyrightID(?int $copyright_id)
Class ilObjFileImplementationStorage.
setFileName(string $a_name)
static getLogger(string $a_component_id)
Get component logger.
updateObjectFromRevision(Revision $r)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
cloneMetaData(ilObject $target_obj)
replaceWithUpload(UploadResult $result, string $title)
doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id=0)
Class ChatMainBarProvider .
ilLogger $log
trait ilObjFileMetadata
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
appendSuffixToTitle(string $title, string $filename)
rollback(int $version_id)
Makes the specified version the current one.
static _isFileHidden(string $a_file_name)
Returns true, if a file with the specified name, is usually hidden from the user. ...
getDirectory($a_version=0)
string $action
const OBJECT_TYPE
setTitle(string $title)
updateObjectFromCurrentRevision()
setMode(string $a_mode)
appendUpload(UploadResult $result, string $title)
doCreate(bool $clone_mode=false)
ilObjFileImplementationInterface $implementation
replaceFile($a_upload_file, $a_filename)
global $DIC
Definition: feed.php:28
setAction(string $a_action)
setFileSize(int $a_size)
initFileInfo(int $id, bool $is_ref_id)
static _removeEntriesForObject(int $a_obj_id)
remove all history entries for an object
__construct(VocabulariesInterface $vocabularies)
getVersion(bool $inclduing_drafts=false)
appendStream(FileStream $stream, string $title)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
stripTitleOfFileExtension(string $a_title)
ilObjFileStakeholder $stakeholder
const CLICK_MODE_DOWNLOAD
getUploadFile($a_upload_file, string $title, bool $a_prevent_preview=false)
This Method is used to append a fileupload by it&#39;s POST-name to the current ilObjFile ...
Class ilObjFile.
const MODE_FILELIST
setPageCount(int $page_count)
string $resource_id
ilObjFileInfo $file_info
ilDBInterface $database
string $filetype
extractSuffixFromFilename(string $filename)
$results
Class FileUpload.
Definition: FileUpload.php:34
setVersion(int $a_version)
string $filename
setMaxVersion(int $a_max_version)
__construct(int $a_id=0, bool $a_call_by_reference=true)
ilObjFile constructor.
setOnclickMode(int $on_click_mode)
const MODE_OBJECT
deleteVersions($a_hist_entry_ids=null)
trait ilObjFileSecureString
Trait ilObjFileSecureString.
getFileExtension()
Returns the extension of the file name converted to lower-case.
setRating(bool $a_value)
enableNotification()
Manager $manager
notifyUpdate(int $obj_id, string $additional_message=null)
replaceWithStream(FileStream $stream, string $title)
notifyCreation(int $obj_id, string $additional_message=null)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$q
Definition: shib_logout.php:21
setAmountOfDownloads(int $amount)
createProperties(bool $a_upload=false)
The basic properties of a file object are stored in table object_data.
sendFile(?int $a_hist_entry_id=null, bool $inline=true)
checkFileExtension(string $new_filename, string $new_title)
Class ilCountPDFPagesPreProcessors.
setFileType(string $a_type)
FileUpload $upload
setImportantInfo(string $a_important_info)
string $important_info
setResourceId(?string $resource_id)
handleChangedObjectTitle(string $new_title)
static getInstance(int $obj_id)
The base interface for all filesystem streams.
Definition: FileStream.php:31
getVersions($version_ids=null)
int $amount_of_downloads
export(string $a_target_dir)
updateCopyright()
update copyright meta data
ensureSuffix(string $title, ?string $suffix=null)
const CLICK_MODE_INFOPAGE
trait ilObjFileNews
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getFile(?int $a_hist_entry_id=null)
$r