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