ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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
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,
267 $this->file_name
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}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Definition: Streams.php:32
language handling
__construct(private readonly ?int $object_id=null)
FlavourDefinition $fallback_flavour_definition
@readonly
FlavourDefinition $flavour_definition
@readonly
ILIAS Refinery Factory $refinery
@readonly
static _getAllReferences(int $id)
get all reference ids for object ID
A lightbox Image page represents a page displaying a media element, such as image,...
This is how the factory for UI elements looks.
Definition: Factory.php:38
An entity that renders components to a string output.
Definition: Renderer.php:31
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:66
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68
$response
Definition: xapitoken.php:93