ILIAS  trunk Revision v11.0_alpha-1843-g9e1fad99175
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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  #[\Override]
96  public function getPresentationTitle(): string
97  {
98  return $this->file_info->getHeaderTitle();
99  }
100 
101  protected function initImplementation(): void
102  {
103  if ($this->resource_id && ($id = $this->manager->find(
104  $this->resource_id
105  )) instanceof ResourceIdentification) {
106  $resource = $this->manager->getResource($id);
107  $this->implementation = new ilObjFileImplementationStorage($resource);
108  $this->max_version = $resource->getMaxRevision(false);
109  $this->version = $resource->getCurrentRevision()->getVersionNumber();
110  }
111  $this->initFileInfo($this->getId(), false);
112  }
113 
114  public function updateObjectFromCurrentRevision(): void
115  {
117  $this->manager->getCurrentRevision($this->manager->find($this->getResourceId()))
118  );
119  }
120 
121  private function updateObjectFromRevision(Revision $r): 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  }
133 
134  public function appendSuffixToTitle(string $title, string $filename): string
135  {
136  $suffix = $this->file_info->getSuffix();
137  $filename_suffix = $this->extractSuffixFromFilename($filename);
138  if (empty($suffix) || $suffix !== $filename_suffix) {
139  $suffix = $filename_suffix;
140  }
141 
142  return $this->ensureSuffix($title, $suffix);
143  }
144 
148  public function appendStream(FileStream $stream, string $title): int
149  {
150  $title = $this->ensureSuffix(
151  $title,
152  $this->extractSuffixFromFilename($title)
153  ?? pathinfo($stream->getMetadata('uri'))['extension']
154  ?? null
155  );
156  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
157  $revision = $this->manager->appendNewRevisionFromStream($i, $stream, $this->stakeholder, $title);
158  } else {
159  $i = $this->manager->stream($stream, $this->stakeholder, $title);
160  $revision = $this->manager->getCurrentRevision($i);
161  $this->setResourceId($i->serialize());
162  $this->initImplementation();
163  }
164  $this->enableNotification();
165  $this->updateObjectFromRevision($revision);
166 
167  return $revision->getVersionNumber();
168  }
169 
173  public function appendUpload(UploadResult $result, string $title): int
174  {
175  $title = $this->appendSuffixToTitle($title, $result->getName());
176  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
177  $revision = $this->manager->appendNewRevision($i, $result, $this->stakeholder, $title);
178  } else {
179  $i = $this->manager->upload($result, $this->stakeholder, $title);
180  $revision = $this->manager->getCurrentRevision($i);
181  $this->setResourceId($i->serialize());
182  $this->initImplementation();
183  }
186  }
187  $this->enableNotification();
188  $this->updateObjectFromRevision($revision);
189 
190  return $revision->getVersionNumber();
191  }
192 
196  public function replaceWithStream(FileStream $stream, string $title): int
197  {
198  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
199  $revision = $this->manager->replaceWithStream($i, $stream, $this->stakeholder, $title);
200  } else {
201  throw new LogicException('only files with existing resource and revision can be replaced');
202  }
203  $this->enableNotification();
204  $this->updateObjectFromRevision($revision);
205 
206  return $revision->getVersionNumber();
207  }
208 
212  public function replaceWithUpload(UploadResult $result, string $title): int
213  {
214  $title = $this->appendSuffixToTitle($title, $result->getName());
215  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
216  $revision = $this->manager->replaceWithUpload($i, $result, $this->stakeholder, $title);
217  } else {
218  throw new LogicException('only files with existing resource and revision can be replaced');
219  }
222  }
223  $this->enableNotification();
224  $this->updateObjectFromRevision($revision);
225 
226  return $revision->getVersionNumber();
227  }
228 
232  public function getFile(?int $a_hist_entry_id = null): string
233  {
234  $this->initImplementation();
235  return $this->implementation->getFile($a_hist_entry_id);
236  }
237 
238  public function getDirectory($a_version = 0): string
239  {
240  return $this->implementation->getDirectory($a_version);
241  }
242 
243  public function getDownloadFilename(): string
244  {
245  return $this->implementation->getDownloadFilename();
246  }
247 
248  public function getImportantInfo(): ?string
249  {
250  return $this->important_info;
251  }
252 
253  public function setImportantInfo(string $a_important_info): void
254  {
255  $this->important_info = empty($a_important_info) ? null : $a_important_info;
256  }
257 
258  public function getVersion(bool $inclduing_drafts = false): int
259  {
260  return $this->implementation->getVersion($inclduing_drafts);
261  }
262 
263  public function setVersion(int $a_version): void
264  {
265  $this->version = $a_version;
266  }
267 
268  public function getFileName(): string
269  {
270  return $this->implementation->getFileName();
271  }
272 
273  public function setFileName(string $a_name): void
274  {
275  $this->filename = $a_name;
276  }
277 
278  public function setRating(bool $a_value): void
279  {
280  $this->rating = $a_value;
281  }
282 
283  public function setResourceId(?string $resource_id): self
284  {
285  $this->resource_id = $resource_id;
286  return $this;
287  }
288 
289  public function getResourceId(): string
290  {
291  return $this->resource_id ?? '-';
292  }
293 
294  public function getStorageID(): ?string
295  {
296  return $this->implementation->getStorageID();
297  }
298 
299  public function getMode(): string
300  {
301  return $this->mode;
302  }
303 
307  public function setMode(string $a_mode): void
308  {
309  $this->mode = $a_mode;
310  }
311 
312  public function getFileSize(): int
313  {
314  return $this->implementation->getFileSize();
315  }
316 
320  public function setFileSize(int $a_size): void
321  {
322  throw new LogicException('cannot change filesize');
323  }
324 
325  public function getFileType(): string
326  {
327  return $this->implementation->getFileType();
328  }
329 
333  public function setFileType(string $a_type): void
334  {
335  throw new LogicException('cannot change filetype');
336  }
337 
338  public function hasRating(): bool
339  {
340  return $this->rating;
341  }
342 
343  public function getMaxVersion(): int
344  {
345  return $this->max_version;
346  }
347 
351  public function setMaxVersion(int $a_max_version): void
352  {
353  throw new LogicException('cannot change max-version');
354  }
355 
356  public function getCopyrightID(): ?string
357  {
358  return $this->copyright_id;
359  }
360 
361  public function setCopyrightID(?string $copyright_id): void
362  {
363  $this->copyright_id = $copyright_id;
364  }
365 
366  public function getPageCount(): int
367  {
368  return $this->page_count;
369  }
370 
371  public function setPageCount(int $page_count): void
372  {
373  $this->page_count = $page_count;
374  }
375 
379  public function getAction(): string
380  {
381  return $this->action;
382  }
383 
384  public function directDownload(): bool
385  {
386  return $this->on_click_mode === self::CLICK_MODE_DOWNLOAD;
387  }
388 
389  public function getOnClickMode(): int
390  {
391  return $this->on_click_mode;
392  }
393 
394  public function setOnclickMode(int $on_click_mode): void
395  {
396  $this->on_click_mode = $on_click_mode;
397  }
398 
399  public function getAmountOfDownloads(): int
400  {
402  }
403 
404  public function setAmountOfDownloads(int $amount): void
405  {
406  if (0 > $amount) {
407  throw new LogicException("Amount cannot be a negative number.");
408  }
409 
410  $this->amount_of_downloads = $amount;
411  }
412 
413  public function getLPMode(): int
414  {
415  return ilObjectLP::getInstance($this->getId())->getCurrentMode();
416  }
417 
423  public function setAction(string $a_action): void
424  {
425  throw new LogicException('cannot change action');
426  }
427 
428  public function handleChangedObjectTitle(string $new_title): void
429  {
430  $new_title = $this->ensureSuffix($new_title, $this->file_info->getSuffix());
431  $this->setTitle($new_title);
432  $this->implementation->handleChangedObjectTitle($new_title);
433  }
434 
435  protected function doCreate(bool $clone_mode = false): void
436  {
437  $this->createProperties(true);
438  $this->updateCopyright();
439  $this->getObjectProperties()->storePropertyIsOnline(new ilObjectPropertyIsOnline(true));
440  $this->notifyCreation($this->getId(), $this->getDescription());
441  }
442 
443  protected function doRead(): void
444  {
445  $q = "SELECT * FROM file_data WHERE file_id = %s";
446  $r = $this->database->queryF($q, ['integer'], [$this->getId()]);
447  $row = $r->fetchObject();
448 
449  $this->filename = $this->secure($row->file_name ?? '');
450  $this->filetype = $row->file_type ?? '';
451  $this->filesize = $row->file_size ?? 0;
452  $this->version = $row->version ?? 1;
453  $this->max_version = $row->max_version ?? 1;
454  $this->mode = $row->f_mode ?? self::MODE_OBJECT;
455  $this->important_info = $row->important_info ?? "";
456  $this->rating = (bool) ($row->rating ?? false);
457  $this->page_count = (int) ($row->page_count ?? 0);
458  $this->resource_id = $row->rid ?? null;
459  $this->on_click_mode = (int) ($row->on_click_mode ?? self::CLICK_MODE_DOWNLOAD);
460  $this->amount_of_downloads = (int) ($row->downloads ?? 0);
461 
462  $this->initImplementation();
463  }
464 
465  protected function doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id = 0): void
466  {
467  assert($new_obj instanceof ilObjFile);
468  $identification = $this->manager->find($this->resource_id);
469  if ($identification === null) {
470  throw new RuntimeException('Cannot clone file since no corresponding resource identification was found');
471  }
472 
473  $this->cloneMetaData($new_obj);
474  // object created now copy other settings
475  $new_obj->updateFileData();
476 
477  // Copy Resource
478  $cloned_title = $new_obj->getTitle();
479  $new_resource_identification = $this->manager->clone($identification);
480  $new_current_revision = $this->manager->getCurrentRevision($new_resource_identification);
481  $new_obj->setResourceId($new_resource_identification->serialize());
482  $new_obj->initImplementation();
483  $new_obj->updateObjectFromRevision($new_current_revision); // Previews are already copied in 453
484  $new_obj->setTitle($cloned_title); // see https://mantis.ilias.de/view.php?id=31375
485  $new_obj->setPageCount($this->getPageCount());
486  $new_obj->update();
487 
488  $new_obj->getObjectProperties()->storePropertyIsOnline(new ilObjectPropertyIsOnline(true));
489 
490  // Copy learning progress settings
491  $obj_settings = new ilLPObjSettings($this->getId());
492  $obj_settings->cloneSettings($new_obj->getId());
493  unset($obj_settings);
494  }
495 
496  protected function doUpdate(): void
497  {
498  $a_columns = $this->getArrayForDatabase();
499  $this->database->update('file_data', $a_columns, [
500  'file_id' => [
501  'integer',
502  $this->getId(),
503  ],
504  ]);
505 
506  $this->notifyUpdate($this->getId(), $this->getDescription());
507  $this->initImplementation();
508  }
509 
510  #[\Override]
511  protected function beforeUpdate(): bool
512  {
513  $suffix = $this->file_info->getSuffix();
514  if (empty($suffix)) {
515  $suffix = $this->extractSuffixFromFilename($this->getTitle());
516  }
517  $this->setTitle($this->ensureSuffix($this->getTitle(), $suffix));
518 
519  // no meta data handling for file list files
520  if ($this->getMode() !== self::MODE_FILELIST) {
521  $this->updateMetaData();
522  $this->updateCopyright();
523  }
524 
525  return true;
526  }
527 
528  #[\Override]
529  protected function beforeDelete(): bool
530  {
531  // check, if file is used somewhere
532  $usages = $this->getUsages();
533  return $usages === [];
534  }
535 
536  protected function doDelete(): void
537  {
538  // delete file data entry
539  $this->database->manipulateF("DELETE FROM file_data WHERE file_id = %s", ['integer'], [$this->getId()]);
540 
541  // delete history entries
543 
544  // delete meta data
545  if ($this->getMode() !== self::MODE_FILELIST) {
546  $this->deleteMetaData();
547  }
548 
549  // delete resource
550  $identification = $this->getResourceId();
551  if ($identification && $identification !== '-') {
552  $resource = $this->manager->find($identification);
553  if ($resource !== null) {
554  $this->manager->remove($resource, $this->stakeholder);
555  }
556  }
557  }
558 
562  private function getArrayForDatabase(): array
563  {
564  return [
565  'file_id' => ['integer', $this->getId()],
566  'file_name' => ['text', $this->getFileName()],
567  'f_mode' => ['text', $this->getMode()],
568  'important_info' => ['text', $this->getImportantInfo()],
569  'page_count' => ['text', $this->getPageCount()],
570  'rating' => ['integer', $this->hasRating()],
571  'rid' => ['text', $this->resource_id ?? ''],
572  'on_click_mode' => ['integer', $this->getOnClickMode()],
573  'downloads' => ['integer', $this->getAmountOfDownloads()],
574  ];
575  }
576 
577  protected function initType(): void
578  {
579  $this->type = self::OBJECT_TYPE;
580  }
581 
582  // Upload Handling
583 
587  public function replaceFile($a_upload_file, $a_filename): null
588  {
589  return null;
590  }
591 
592  private function prepareUpload(): void
593  {
594  if (!$this->upload->hasBeenProcessed()) {
595  if (defined('PATH_TO_GHOSTSCRIPT') && PATH_TO_GHOSTSCRIPT !== "") {
596  $this->upload->register(new ilCountPDFPagesPreProcessors());
597  }
598 
599  $this->upload->process();
600  }
601  }
602 
608  public function getUploadFile($a_upload_file, string $title, bool $a_prevent_preview = false): bool
609  {
610  $this->prepareUpload();
611 
612  $results = $this->upload->getResults();
613  $upload = $results[$a_upload_file];
614 
615  $this->appendUpload($upload, $title);
616 
617  return true;
618  }
619 
623  public function isHidden(): bool
624  {
625  return ilObjFileAccess::_isFileHidden($this->getTitle());
626  }
627 
632  public function clearDataDirectory(): void
633  {
634  $this->implementation->clearDataDirectory();
635  }
636 
641  public function deleteVersions($a_hist_entry_ids = null): void
642  {
643  $this->implementation->deleteVersions($a_hist_entry_ids);
644  // update file object as the deletion of versions might affect its attributes (title, max_version etc.)
645  if ($this->getResourceId() && $rid = $this->manager->find($this->getResourceId())) {
646  $latest_revision = $this->manager->getCurrentRevision($rid);
647  $this->updateObjectFromRevision($latest_revision);
648  }
649  }
650 
651  public function sendFile(?int $a_hist_entry_id = null, bool $inline = true): void
652  {
653  // increment file download count by one.
654  $this->setAmountOfDownloads($this->getAmountOfDownloads() + 1);
655  $this->update();
656  $info = (new ilObjFileInfoRepository())->getByObjectId($this->getId());
657  $this->implementation->sendFile($a_hist_entry_id, $info->shouldDeliverInline());
658  }
659 
663  public function export(string $a_target_dir): void
664  {
665  //
666  }
667 
672  public function getVersions($version_ids = null): array
673  {
674  return $this->implementation->getVersions($version_ids);
675  }
676 
681  public function rollback(int $version_id): void
682  {
683  if ($this->getResourceId() && $i = $this->manager->find($this->getResourceId())) {
684  $this->manager->rollbackRevision($i, $version_id);
685  $latest_revision = $this->manager->getCurrentRevision($i);
686  $this->updateObjectFromRevision($latest_revision);
687  } else {
688  throw new LogicException('only files with existing resource and revision can be replaced');
689  }
690  }
691 
695  public function checkFileExtension(string $new_filename, string $new_title): string
696  {
697  return $this->appendSuffixToTitle($new_title, $new_filename);
698  }
699 
700  public function getFileExtension(): string
701  {
702  return $this->implementation->getFileExtension();
703  }
704 
705  public function stripTitleOfFileExtension(string $a_title): string
706  {
707  return $this->secure(preg_replace('/\.[^.]*$/', '', $a_title));
708  }
709 }
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
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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:22
setPageCount(int $page_count)
string $resource_id
ilObjFileInfo $file_info
ilDBInterface $database
string $filetype
extractSuffixFromFilename(string $filename)
$results
Class FileUpload.
Definition: FileUpload.php:37
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:23
__construct(Container $dic, ilPlugin $plugin)
$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)
notifyCreation(int $obj_id, ?string $additional_message=null)
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)
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