ILIAS  trunk Revision v11.0_alpha-1753-gb21ca8c4367
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilObjFilePreviewRendererGUI.php
Go to the documentation of this file.
1 <?php
2 
30 
35 {
36  public const P_RID = "rid";
37  public const CMD_GET_ASYNC_MODAL = 'getAsyncModal';
38 
42  private ilDBInterface $db;
59  private Services $irss;
63  private \ILIAS\HTTP\Services $http;
71  private \ILIAS\Refinery\Factory $refinery;
87  private int $preview_size;
91  private int $pages_to_extract;
92  private bool $activated = false;
93  private string $file_name = '';
98 
99  public function __construct(
100  private readonly ?int $object_id = null
101  ) {
102  global $DIC;
103 
104  $settings = (new SettingsFactory())->getSettings();
105  $this->activated = $settings->isPreviewEnabled();
106 
107  $this->db = $DIC->database();
108  $this->ctrl = $DIC->ctrl();
109 
110  $this->ui_factory = $DIC->ui()->factory();
111  $this->ui_renderer = $DIC->ui()->renderer();
112  $this->irss = $DIC->resourceStorage();
113  $this->http = $DIC->http();
114  $this->http_wrapper = $DIC->http()->wrapper();
115  $this->refinery = $DIC->refinery();
116  $this->access = $DIC->access();
117  $this->language = $DIC->language();
118  $this->language->loadLanguageModule('file');
119 
120  $rid_string = $this->resolveRidString($this->object_id);
121 
122  $this->rid = $this->irss->manage()->find($rid_string);
123  $this->flavour_definition = new PagesToExtract(
124  $settings->isPersisting(),
125  $settings->getImageSize(),
126  $settings->getMaximumPreviews()
127  );
128  $this->fallback_flavour_definition = new FitToSquare(
129  $settings->isPersisting(),
130  $settings->getImageSize()
131  );
132  // Resolve File Name
133  if ($this->rid !== null) {
134  $this->file_name = $this->irss->manage()->getCurrentRevision($this->rid)->getTitle();
135  }
136  }
137 
138  public function has(): bool
139  {
140  if (!$this->activated) {
141  return false;
142  }
143  if ($this->rid === null) {
144  return false;
145  }
146  if (
147  !$this->irss->flavours()->possible(
148  $this->rid,
149  $this->flavour_definition
150  )
151  && !$this->irss->flavours()->possible(
152  $this->rid,
153  $this->fallback_flavour_definition
154  )
155  ) {
156  return false;
157  }
158  return $this->isAccessGranted();
159  }
160 
161  public function getTriggerComponents(bool $as_button = false): array
162  {
163  if (!$this->isAccessGranted()) {
164  throw new LogicException('User cannot see this resource');
165  }
166 
167  $this->ctrl->setParameterByClass(self::class, self::P_RID, $this->rid->serialize());
168 
169  $modal = $this->ui_factory->modal()
170  ->lightbox([])
171  ->withAsyncRenderUrl(
172  $this->ctrl->getLinkTargetByClass(self::class, self::CMD_GET_ASYNC_MODAL)
173  );
174 
175  if (!$as_button) {
176  $trigger = $this->ui_factory->symbol()->glyph()->preview(
177  "#"
178  )->withOnClick($modal->getShowSignal());
179  } else {
180  $trigger = $this->ui_factory->button()->standard(
181  $this->language->txt('show_preview'),
182  "#"
183  )->withOnClick($modal->getShowSignal());
184  }
185 
186  return [
187  $modal,
188  $trigger
189  ];
190  }
191 
192  public function getRenderedTriggerComponents(bool $as_button = false): string
193  {
194  return $this->ui_renderer->render($this->getTriggerComponents($as_button));
195  }
196 
197  public function executeCommand(): void
198  {
199  $cmd = $this->ctrl->getCmd();
200  match ($cmd) {
201  self::CMD_GET_ASYNC_MODAL => $this->{$cmd}(),
202  default => throw new InvalidArgumentException('Command not found: ' . $cmd),
203  };
204  }
205 
209  protected function resolveRidString(?int $object_id): string
210  {
211  if ($object_id !== null) {
212  return $this->db->fetchObject(
213  $this->db->queryF(
214  'SELECT rid FROM file_data WHERE file_id = %s',
215  ['integer'],
216  [$object_id]
217  )
218  )->rid ?? '';
219  }
220  return $this->http_wrapper->query()->has(self::P_RID)
221  ? $this->http_wrapper->query()->retrieve(
222  self::P_RID,
223  $this->refinery->to()->string()
224  ) : '';
225  }
226 
227  protected function isAccessGranted(): bool
228  {
229  // if object_id is set, we can check the access using it's ref_ids
230  if ($this->object_id !== null) {
231  foreach (ilObject::_getAllReferences($this->object_id) as $ref_id) {
232  if ($this->access->checkAccess('read', '', $ref_id)) {
233  return true;
234  }
235  }
236  return false;
237  }
238  // else we ask the stakeholders if they allow access
239  $resource = $this->irss->manage()->getResource($this->rid);
240  foreach ($resource->getStakeholders() as $stakeholder) {
241  if ($stakeholder->canBeAccessedByCurrentUser($this->rid)) {
242  return true;
243  }
244  }
245  return false;
246  }
247 
248  private function getAsyncModal(): void
249  {
250  if (!$this->isAccessGranted()) {
251  throw new LogicException('User cannot see this resource');
252  }
253 
254  // Resolve Flavour for Definition
255  $flavour = $this->irss->flavours()->get($this->rid, $this->flavour_definition);
256  $flavour_urls = $this->irss->consume()->flavourUrls($flavour)->getURLsAsArray();
257  if ($flavour_urls === []) { // Try Fallback
258  $flavour = $this->irss->flavours()->get($this->rid, $this->fallback_flavour_definition);
259  $flavour_urls = $this->irss->consume()->flavourUrls($flavour)->getURLsAsArray();
260  }
261 
262  $page_title = function (?int $index): string {
263  $index_string = $index !== null ? (($index + 1) . ' ') : '';
264  return sprintf(
265  $this->language->txt('preview_caption'),
266  $index_string,
268  );
269  };
270 
271  // Build Pages for Lightbox
272  $pages = array_map(function (string $url, $i) use ($page_title): LightboxImagePage {
273  $title = $page_title($i);
274  return $this->ui_factory->modal()->lightboxImagePage(
275  $this->ui_factory->image()->responsive(
276  $url,
277  $title
278  ),
279  $title
280  );
281  }, $flavour_urls, count($flavour_urls) > 1 ? array_keys($flavour_urls) : []);
282 
283  // Fallback to a TextPage if no Flavour Images were found
284  if ($pages === []) {
285  $pages = $this->ui_factory->modal()->lightboxTextPage(
286  sprintf(
287  $this->language->txt('preview_not_possible'),
288  'components/ILIAS/File/classes/Preview/README.md'
289  ),
290  $this->language->txt('preview')
291  );
292  }
293  $modal = $this->ui_factory->modal()->lightbox($pages);
294 
295  // Send response and end script
296  $response = $this->http->response()->withBody(Streams::ofString($this->ui_renderer->renderAsync($modal)));
297  $this->http->saveResponse($response);
298  $this->http->sendResponse();
299  }
300 }
static _getAllReferences(int $id)
get all reference ids for object ID
$response
Definition: xapitoken.php:93
$url
Definition: shib_logout.php:66
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This is how the factory for UI elements looks.
Definition: Factory.php:37
global $DIC
Definition: shib_login.php:22
A lightbox Image page represents a page displaying a media element, such as image, video.
__construct(private readonly ?int $object_id=null)
language()
description: > Example for rendring a language glyph.
Definition: language.php:41