ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilMailAttachmentGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\Refinery\Factory as Refinery;
30
34{
35 use FileDataRCHandling;
36
38 private readonly ilLanguage $lng;
39 private readonly ilObjUser $user;
40 private readonly ilFormatMail $umail;
41 private readonly ilFileDataMail $fdm;
42 private readonly Refinery $refinery;
43 private readonly \ILIAS\UI\Factory $ui_factory;
44 private readonly \ILIAS\UI\Renderer $ui_renderer;
45 private readonly ilTabsGUI $tabs;
46 private AttachmentManagement $mode = AttachmentManagement::MANAGE;
48
49 public function __construct()
50 {
51 global $DIC;
52
54 $this->tpl = $DIC->ui()->mainTemplate();
55 $this->lng = $DIC->language();
56 $this->user = $DIC->user();
57 $this->tabs = $DIC->tabs();
58 $this->refinery = $DIC->refinery();
59 $this->ui_factory = $DIC->ui()->factory();
60 $this->ui_renderer = $DIC->ui()->renderer();
61 $this->storage = $DIC->resourceStorage();
62
63 $this->ctrl->saveParameter($this, 'mobj_id');
64
65 $this->umail = new ilFormatMail($DIC->user()->getId());
66 $this->fdm = new ilFileDataMail($DIC->user()->getId());
67 }
68
69 public function getUnsafeGetCommands(): array
70 {
71 return [
73 ];
74 }
75
76 public function getSafePostCommands(): array
77 {
78 return [];
79 }
80
81 public function manage(): self
82 {
83 $this->mode = AttachmentManagement::MANAGE;
84 return $this;
85 }
86
87 public function consume(): self
88 {
90 return $this;
91 }
92
93 public function executeCommand(): void
94 {
95 $cmd = $this->ctrl->getCmd();
96 switch ($cmd) {
97 case AbstractCtrlAwareUploadHandler::CMD_UPLOAD:
98 case AbstractCtrlAwareUploadHandler::CMD_INFO:
99 case AbstractCtrlAwareUploadHandler::CMD_REMOVE:
100 parent::executeCommand();
101 break;
102
103 default:
104 if ($cmd === null || $cmd === '' || !method_exists($this, $cmd . 'Command')) {
105 $cmd = self::DEFAULT_CMD;
106 }
107 $verified_command = $cmd . 'Command';
108 $this->$verified_command();
109 break;
110 }
111 }
112
113 private function saveAttachments(): void
114 {
115 $files = [];
116
117 // Important: Do not check for uploaded files here,
118 // otherwise it is no more possible to remove files (please ignore bug reports like 10137)
119
120 $size_of_affected_files = 0;
121 $files_of_request = $this->http->wrapper()->query()->retrieve(
122 'mail_attachments_filename',
123 $this->refinery->byTrying([
124 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
125 $this->refinery->always([])
126 ])
127 );
128
129 if ($files_of_request !== [] && $files_of_request[0] === 'ALL_OBJECTS') {
130 $files_of_request = array_map(static fn(array $file): string => $file['name'], $this->fdm->getUserFilesData());
131 }
132
133 foreach ($files_of_request as $file) {
134 if (is_file($this->fdm->getMailPath() . '/' . basename($this->user->getId() . '_' . urldecode((string) $file)))) {
135 $files[] = urldecode((string) $file);
136 $size_of_affected_files += filesize(
137 $this->fdm->getMailPath() . '/' .
138 basename($this->user->getId() . '_' . urldecode((string) $file))
139 );
140 }
141 }
142
143 if ($files !== [] &&
144 $this->fdm->getAttachmentsTotalSizeLimit() !== null &&
145 $size_of_affected_files > $this->fdm->getAttachmentsTotalSizeLimit()) {
146 $this->tpl->setOnScreenMessage(
147 $this->tpl::MESSAGE_TYPE_FAILURE,
148 $this->lng->txt('mail_max_size_attachments_total_error') . ' ' .
149 ilUtil::formatSize((int) $this->fdm->getAttachmentsTotalSizeLimit())
150 );
151 $this->showAttachmentsCommand();
152 return;
153 }
154
155 $rcid_for_files = $this->getIdforCollection($files);
156 $this->umail->saveAttachments($rcid_for_files);
157
158 $this->ctrl->returnToParent($this);
159 }
160
161 private function cancelSaveAttachmentsCommand(): void
162 {
163 $this->ctrl->setParameter($this, 'type', ilMailFormGUI::MAIL_FORM_TYPE_ATTACH);
164 $this->ctrl->returnToParent($this);
165 }
166
167 private function confirmDeleteAttachments(): void
168 {
169 $files = $this->http->wrapper()->query()->retrieve(
170 'mail_attachments_filename',
171 $this->refinery->byTrying([
172 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
173 $this->refinery->always([])
174 ])
175 );
176
177 if ($files !== [] && $files[0] === 'ALL_OBJECTS') {
178 $files = array_map(static fn(array $file): string => $file['name'], $this->fdm->getUserFilesData());
179 }
180
181 if ($files === []) {
182 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_INFO, $this->lng->txt('select_one'), true);
183 $this->ctrl->redirect($this);
184 }
185
186 $this->tpl->setTitle($this->lng->txt('mail_attachments'));
187
188 $confirmation = new ilConfirmationGUI();
189 $confirmation->setFormAction($this->ctrl->getFormAction($this, self::CMD_DELETE_ATTACHMENTS));
190 $confirmation->setConfirm($this->lng->txt('confirm'), self::CMD_DELETE_ATTACHMENTS);
191 $confirmation->setCancel($this->lng->txt('cancel'), self::CMD_SHOW_ATTACHMENTS);
192 $confirmation->setHeaderText($this->lng->txt('mail_sure_delete_file'));
193
194 foreach ($files as $filename) {
195 $confirmation->addItem(
196 'filename[]',
198 ilUtil::stripSlashes(urldecode((string) $filename))
199 );
200 }
201
202 $this->tpl->setContent($confirmation->getHTML());
203 $this->tpl->printToStdout();
204 }
205
206 private function deleteAttachmentsCommand(): void
207 {
208 $files = $this->http->wrapper()->post()->retrieve(
209 'filename',
210 $this->refinery->byTrying([
211 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
212 $this->refinery->always([])
213 ])
214 );
215
216 if ($files === []) {
217 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_INFO, $this->lng->txt('mail_select_one_mail'));
218 $this->showAttachmentsCommand();
219 return;
220 }
221
222 $decoded_files = [];
223 foreach ($files as $value) {
224 $decoded_files[] = urldecode((string) $value);
225 }
226
227 $error = $this->fdm->unlinkFiles($decoded_files);
228 if ($error !== '') {
229 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('mail_error_delete_file') . ' ' . $error, true);
230 } else {
231 $mail_data = $this->umail->retrieveFromStage();
232 if (!is_null($mail_data['attachments'])) {
233 $files_to_legacy = $this->FilesFromIRSSToLegacy($mail_data['attachments']);
234 $files = $this->handleAttachments($files_to_legacy);
235 $rcid = null;
236 if (is_array($files)) {
237 foreach ($files as $attachment) {
238 $tmp = [];
239 if (!in_array($attachment, $decoded_files, true)) {
240 $tmp[] = $attachment;
241 }
242 $rcid = $this->getIdforCollection($tmp);
243 }
244 $this->umail->saveAttachments($rcid);
245 }
246 }
247
248 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('mail_files_deleted'), true);
249 }
250
251 $this->ctrl->redirect($this);
252 }
253
254 private function showAttachmentsCommand(): void
255 {
256 $this->tpl->setTitle($this->lng->txt('mail_attachments'));
257
258 if ($this->mode === AttachmentManagement::CONSUME) {
259 $this->tabs->clearTargets();
260 $this->tabs->setBackTarget(
261 $this->lng->txt('mail_manage_attachments_back_to_compose'),
262 $this->ctrl->getLinkTarget($this, self::CMD_CANCEL_SAVE_ATTACHMENTS)
263 );
264 }
265
266 $components = [];
267 if ($this->mode === AttachmentManagement::MANAGE) {
268 $dropzone = $this->ui_factory
269 ->dropzone()
270 ->file()
271 ->standard(
272 $this->lng->txt('mail_manage_attachments'),
273 $this->lng->txt('mail_manage_attachments_drop_files_msg'),
274 '#',
275 $this->ui_factory->input()->field()->file(
276 $this,
277 $this->lng->txt('file')
278 )->withMaxFiles(42) // The answer to life, universe and the rest
279 )
280 ->withBulky(true)
281 ->withUploadButton(
282 $this->ui_factory->button()->shy(
283 $this->lng->txt('upload'),
284 '#'
285 )
286 );
287 $components[] = $dropzone;
288 }
289
290 $mail_data = $this->umail->retrieveFromStage();
291 $files = $this->fdm->getUserFilesData();
292 $records = [];
293 $checked_items = [];
294 foreach ($files as $file) {
295 if (is_array($mail_data['attachments']) && in_array($file['name'], $mail_data['attachments'], true)) {
296 $checked_items[] = urlencode($file['name']);
297 }
298
299 $records[] = [
300 'filename' => $file['name'],
301 'filesize' => (int) $file['size'],
302 'filecreatedate' => (int) $file['ctime'],
303 ];
304 }
305
306 $table = new MailAttachmentTableGUI(
307 $this,
308 $this->user,
309 $records,
310 $this->ui_factory,
311 $this->ui_renderer,
312 $this->lng,
313 $this->ctrl,
314 $this->http->request(),
315 new ILIAS\Data\Factory(),
316 self::CMD_HANDLE_TABLE_ACTIONS,
317 $this->mode
318 );
319 $components[] = $table->get();
320
321 $this->tpl->setContent($this->ui_renderer->render($components));
322
323 if ($this->mode === AttachmentManagement::CONSUME) {
324 // The table above has to be rendered first, because it deselects all checkboxes
325 $this->tpl->addOnLoadCode('
326 const checked_items = ' . json_encode($checked_items, JSON_THROW_ON_ERROR) . ';
327 for (const item of checked_items) {
328 const checkbox = document.querySelector("input[type=\'checkbox\'][value=\'" + item + "\']");
329 if (checkbox) {
330 checkbox.checked = true;
331 }
332 }
333 ');
334 }
335
336 $this->tpl->printToStdout();
337 }
338
339 private function handleTableActionsCommand(): void
340 {
341 $query = $this->http->wrapper()->query();
342 if (!$query->has('mail_attachments_table_action')) {
343 return;
344 }
345
346 $action = $query->retrieve('mail_attachments_table_action', $this->refinery->to()->string());
347 match ($action) {
348 self::TABLE_ACTION_SAVE_ATTACHMENTS => $this->saveAttachments(),
349 self::TABLE_CONFIRM_DELETE_ATTACHMENTS => $this->confirmDeleteAttachments(),
350 default => $this->ctrl->redirect($this),
351 };
352 }
353
354 protected function getUploadResult(): HandlerResult
355 {
356 $this->upload->process();
357 $array = $this->upload->getResults();
358 $result = end($array);
359
360 if ($result instanceof UploadResult && $result->isOK()) {
361 $identifier = $this->fdm->storeUploadedFile($result);
362 $status = HandlerResult::STATUS_OK;
363 $message = $this->lng->txt('saved_successfully');
364 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_SUCCESS, $this->lng->txt('saved_successfully'), true);
365 } else {
366 $status = HandlerResult::STATUS_FAILED;
367 $identifier = '';
368 $message = $result->getStatus()->getMessage();
369 }
370
371 return new BasicHandlerResult($this->getFileIdentifierParameterName(), $status, $identifier, $message);
372 }
373
374 protected function getRemoveResult(string $identifier): HandlerResult
375 {
376 throw new DomainException('Not necessary for this handler');
377 }
378
379 public function getInfoResult(string $identifier): ?FileInfoResult
380 {
381 throw new DomainException('Not necessary for this handler');
382 }
383
384 public function getInfoForExistingFiles(array $file_ids): array
385 {
386 throw new DomainException('Not necessary for this handler');
387 }
388
389 public function getFileIdentifierParameterName(): string
390 {
391 return 'userfile';
392 }
393}
$filename
Definition: buildRTE.php:78
$components
Builds data types.
Definition: Factory.php:36
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
language handling
getInfoForExistingFiles(array $file_ids)
readonly ilFormatMail $umail
readonly ILIAS ResourceStorage Services $storage
executeCommand()
Since this is a ilCtrl aware UploadHandler executeCommand MUST be implemented.
readonly ilFileDataMail $fdm
readonly ILIAS UI Factory $ui_factory
getInfoResult(string $identifier)
getUnsafeGetCommands()
This method must return a list of unsafe GET commands.
readonly ilGlobalTemplateInterface $tpl
getRemoveResult(string $identifier)
getSafePostCommands()
This method must return a list of safe POST commands.
__construct()
ilUIDemoFileUploadHandlerGUI constructor.
readonly ILIAS UI Renderer $ui_renderer
AttachmentManagement $mode
final const string MAIL_FORM_TYPE_ATTACH
User class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatSize(int $size, string $a_mode='short', ?ilLanguage $a_lng=null)
Returns the specified file size value in a human friendly form.
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $DIC
Definition: shib_login.php:26