Completed
Push — bugfix/correct-scrutinizer ( 90b955...b7599b )
by Benjamin
04:19
created

AjaxController::getTreeFoldersAction()   A

Complexity

Conditions 6
Paths 21

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 17
nc 21
nop 1
dl 0
loc 22
rs 9.0777
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
/*
5
 * This file is part of the package lns/digital-asset-management.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE file that was distributed with this source code.
9
 */
10
11
namespace TYPO3\CMS\DigitalAssetManagement\Controller;
12
13
use Psr\Http\Message\ServerRequestInterface;
14
use TYPO3\CMS\Backend\Routing\UriBuilder;
15
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
16
use TYPO3\CMS\Core\Http\JsonResponse;
17
use TYPO3\CMS\Core\Resource\DuplicationBehavior;
18
use TYPO3\CMS\Core\Resource\Exception as ResourceException;
19
use TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException;
20
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
21
use TYPO3\CMS\Core\Resource\Folder;
22
use TYPO3\CMS\Core\Resource\ResourceFactory;
23
use TYPO3\CMS\Core\Utility\GeneralUtility;
24
use TYPO3\CMS\DigitalAssetManagement\Entity\FileMount;
25
use TYPO3\CMS\DigitalAssetManagement\Entity\FileOperationResult;
26
use TYPO3\CMS\DigitalAssetManagement\Entity\FolderItemFile;
27
use TYPO3\CMS\DigitalAssetManagement\Entity\FolderItemFolder;
28
use TYPO3\CMS\DigitalAssetManagement\Entity\FolderItemImage;
29
use TYPO3\CMS\DigitalAssetManagement\Entity\Storage;
30
use TYPO3\CMS\DigitalAssetManagement\Entity\TreeItemFolder;
31
use TYPO3\CMS\DigitalAssetManagement\Exception\ControllerException;
32
use TYPO3\CMS\DigitalAssetManagement\Http\FileExistsResponse;
33
use TYPO3\CMS\DigitalAssetManagement\Http\FileOperationResponse;
34
use TYPO3\CMS\DigitalAssetManagement\Http\FolderItemsResponse;
35
use TYPO3\CMS\DigitalAssetManagement\Http\JsonExceptionResponse;
36
use TYPO3\CMS\DigitalAssetManagement\Http\StoragesAndMountsResponse;
37
38
/**
39
 * Main API endpoint. These are ajax actions called by JS side.
40
 *
41
 * Look up the end points in Configuration/Backend/Routes.php: A typical
42
 * path is something like /ajax/dam/getStoragesAndMounts which maps to a method
43
 * with the same name plus word "Action": getStoragesAndMountsAction().
44
 *
45
 * All actions return a JsonResponse, if all is good, the return code is
46
 * 200. A different code, usually in 4xx range will be returned if the
47
 * client sent a bogus request, often with some exception details.
48
 */
49
class AjaxController
50
{
51
    /**
52
     * @return JsonResponse
53
     */
54
    public function getNewStorageUrlAction(): JsonResponse
55
    {
56
        $backendUser = $this->getBackendUser();
57
        if (!$backendUser->isAdmin()) {
58
            return new JsonExceptionResponse(new ControllerException('User is not admin', 1554380677));
59
        }
60
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
61
        $urlParameters = [
62
            'edit' => [
63
                'sys_file_storage' => [
64
                    0 => 'new',
65
                ],
66
            ],
67
            'returnUrl' => (string)$uriBuilder->buildUriFromRoute('file_DigitalAssetManagement'),
68
        ];
69
        return new JsonResponse([ (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters) ]);
70
    }
71
72
    /**
73
     * Set module state of BE user. Send a json array as ['data'] POST
74
     *
75
     * @param ServerRequestInterface $request
76
     * @return JsonResponse
77
     */
78
    public function setStateAction(ServerRequestInterface $request): JsonResponse
79
    {
80
        $backendUser = $this->getBackendUser();
81
        $backendUser->uc['digital_asset_management'] = $request->getParsedBody()['data'] ?? [];
82
        $backendUser->writeUC();
83
        return new JsonResponse();
84
    }
85
86
    /**
87
     * @return JsonResponse
88
     */
89
    public function getStateAction(): JsonResponse
90
    {
91
        return new JsonResponse([ 'data' => $this->getBackendUser()->uc['digital_asset_management'] ?? []]);
92
    }
93
94
    /**
95
     * @param ServerRequestInterface $request
96
     *
97
     * @return JsonResponse
98
     */
99
    public function createFolderAction(ServerRequestInterface $request): JsonResponse
100
    {
101
        $identifier = $request->getQueryParams()['identifier'] ?? '';
102
        if (empty($identifier)) {
103
            return new JsonExceptionResponse(new ControllerException('Identifier needed', 1554204780));
104
        }
105
        try {
106
            $folder = $this->createFolderRecursive($identifier);
107
            return new JsonResponse([new FolderItemFolder($folder)]);
108
        } catch (ResourceException $e) {
109
            return new JsonExceptionResponse($e);
110
        }
111
    }
112
113
    /**
114
     * @param ServerRequestInterface $request
115
     *
116
     * @return JsonResponse
117
     */
118
    public function fileUploadAction(ServerRequestInterface $request): JsonResponse
119
    {
120
        $identifier = $request->getQueryParams()['identifier'] ?? '';
121
        $conflictMode = $request->getQueryParams()['conflictMode'] ?? '';
122
        $tempFilename = '';
123
        try {
124
            if (empty($identifier)) {
125
                throw new ControllerException('Identifier needed', 1554132801);
126
            }
127
            if (empty($conflictMode) || !in_array($conflictMode, ['replace', 'cancel', 'rename'], true)) {
128
                throw new ControllerException('conflictMode must be one of "replace", "cancel", "rename"');
129
            }
130
            $folderIdentifier = dirname($identifier) . '/';
131
            $fileIdentifier = basename($identifier);
132
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
133
            try {
134
                $folder = $resourceFactory->retrieveFileOrFolderObject($folderIdentifier);
135
            } catch (ResourceDoesNotExistException $e) {
136
                $folder = $this->createFolderRecursive($folderIdentifier);
137
            }
138
            $tempFilename = tempnam(sys_get_temp_dir(), 'upload_');
139
            file_put_contents($tempFilename, $request->getBody());
140
            $file = $folder->addFile($tempFilename, $fileIdentifier, (string)DuplicationBehavior::cast($conflictMode));
141
            $fileExtension = strtolower($file->getExtension());
142
            if (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)
143
                || GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['mediafile_ext'], $fileExtension)
144
            ) {
145
                return new JsonResponse([new FolderItemImage($file)]);
146
            }
147
            return new JsonResponse([new FolderItemFile($file)]);
148
        } catch (ResourceException $e) {
149
            if (!empty($tempFilename) && file_exists($tempFilename)) {
150
                unlink($tempFilename);
151
            }
152
            return new JsonExceptionResponse($e);
153
        } catch (ControllerException $e) {
154
            return new JsonExceptionResponse($e);
155
        }
156
    }
157
158
    /**
159
     * @param string $folderIdentifier
160
     *
161
     * @return Folder
162
     */
163
    protected function createFolderRecursive(string $folderIdentifier): Folder
164
    {
165
        $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
166
        $stack = [];
167
        while (true) {
168
            $parentName = dirname($folderIdentifier);
169
            $folderName = basename($folderIdentifier);
170
            $stack[] = $folderName;
171
            try {
172
                $parentObject = $resourceFactory->retrieveFileOrFolderObject($parentName);
173
                break;
174
            } catch (ResourceDoesNotExistException $e) {
175
                $folderIdentifier = $parentName;
176
            }
177
        }
178
        while ($folderName = array_pop($stack)) {
179
            try {
180
                $parentObject = $parentObject->createFolder($folderName);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parentObject does not seem to be defined for all execution paths leading up to this point.
Loading history...
181
            } catch (ResourceException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
182
            }
183
        }
184
        return $parentObject;
185
    }
186
187
    /**
188
     * @param ServerRequestInterface $request
189
     *
190
     * @return JsonResponse
191
     */
192
    public function fileExistsAction(ServerRequestInterface $request): JsonResponse
193
    {
194
        $identifier = $request->getQueryParams()['identifier'];
195
        if (empty($identifier)) {
196
            return new JsonExceptionResponse(new ControllerException('Identifier needed', 1554125449));
197
        }
198
        $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
199
        $folderIdentifier = dirname($identifier) . '/';
200
        $fileIdentifier = basename($identifier);
201
        try {
202
            $folder = $resourceFactory->retrieveFileOrFolderObject($folderIdentifier);
203
        } catch (ResourceDoesNotExistException $e) {
204
            return new FileExistsResponse(FileExistsResponse::PARENT_FOLDER_DOES_NOT_EXIST);
205
        }
206
        $fileName = $folder->getStorage()->sanitizeFileName($fileIdentifier, $folder);
207
        if ($folder->hasFile($fileName)) {
208
            $file = $resourceFactory->getFileObjectFromCombinedIdentifier($folderIdentifier . $fileName);
209
            // If file is an image or media, create image object, else file object
210
            $fileExtension = strtolower($file->getExtension());
211
            if (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)
212
                || GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['mediafile_ext'], $fileExtension)
213
            ) {
214
                return new JsonResponse([new FolderItemImage($file)]);
215
            }
216
            return new JsonResponse([new FolderItemFile($file)]);
217
        } else {
218
            return new FileExistsResponse(FileExistsResponse::FILE_DOES_NOT_EXIST);
219
        }
220
    }
221
222
    /**
223
     * Return item list (folders, files, images) of a storage:path
224
     * FAL folder identifier. GET request with identifier argument.
225
     *
226
     * @param ServerRequestInterface $request
227
     *
228
     * @return JsonResponse
229
     */
230
    public function getFolderItemsAction(ServerRequestInterface $request): JsonResponse
231
    {
232
        try {
233
            $identifier = $request->getQueryParams()['identifier'] ?? '';
234
            if (empty($identifier)) {
235
                throw new ControllerException('Identifier needed', 1553699828);
236
            }
237
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
238
            $folderObject = $resourceFactory->getObjectFromCombinedIdentifier($identifier);
239
            if (!$folderObject instanceof Folder) {
240
                throw new ControllerException('Identifier is not a folder', 1553701684);
241
            }
242
            $subFolders = $folderObject->getSubfolders();
243
            $folders = [];
244
            foreach ($subFolders as $subFolder) {
245
                $folders[] = new FolderItemFolder($subFolder);
246
            }
247
            $allFiles = $folderObject->getFiles();
248
            $files = [];
249
            $images = [];
250
            foreach ($allFiles as $file) {
251
                // If file is an image or media, create image object, else file object
252
                $fileExtension = strtolower($file->getExtension());
253
                if (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)
254
                    || GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['mediafile_ext'], $fileExtension)
255
                ) {
256
                    $images[] = new FolderItemImage($file);
257
                } else {
258
                    $files[] = new FolderItemFile($file);
259
                }
260
            }
261
            return new FolderItemsResponse($folders, $files, $images);
262
        } catch (ResourceException $e) {
263
            return new JsonExceptionResponse($e);
264
        } catch (ControllerException $e) {
265
            return new JsonExceptionResponse($e);
266
        }
267
    }
268
269
    /**
270
     * Returns list of storages (admins), or file mounts (non-admin). Admins
271
     * do NOT receive a list of file mounts, just the storages.
272
     *
273
     * Storages are returned in no particular order, file mounts are ordered
274
     * by 'sorting' DB field.
275
     *
276
     * Return structure is an array of Storage or FileMount objects.
277
     *
278
     * @return JsonResponse
279
     */
280
    public function getStoragesAndMountsAction(): JsonResponse
281
    {
282
        $backendUser = $this->getBackendUser();
283
        $storages = $backendUser->getFileStorages();
284
        $entities = [];
285
        if ($backendUser->isAdmin()) {
286
            foreach ($storages as $storage) {
287
                $entities[] = new Storage($storage);
288
            }
289
        } else {
290
            foreach ($storages as $storage) {
291
                $fileMounts = $storage->getFileMounts();
292
                foreach ($fileMounts as $fileMount) {
293
                    $entities[] = new FileMount($storage, $fileMount);
294
                }
295
            }
296
        }
297
        return new StoragesAndMountsResponse($entities);
298
    }
299
300
    /**
301
     * Returns list of folders only. No files, no images
302
     * Result is sorted by name
303
     *
304
     * Return structure is an array of TreeItemFolder objects.
305
     *
306
     * @param ServerRequestInterface $request
307
     *
308
     * @return JsonResponse
309
     */
310
    public function getTreeFoldersAction(ServerRequestInterface $request): JsonResponse
311
    {
312
        try {
313
            $identifier = $request->getQueryParams()['identifier'] ?? '';
314
            if (empty($identifier)) {
315
                throw new ControllerException('Identifier needed', 1553699828);
316
            }
317
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
318
            $folderObject = $resourceFactory->getObjectFromCombinedIdentifier($identifier);
319
            if (!$folderObject instanceof Folder) {
320
                throw new ControllerException('Identifier is not a folder', 1553701684);
321
            }
322
            $subFolders = $folderObject->getSubfolders();
323
            $folders = [];
324
            foreach ($subFolders as $subFolder) {
325
                $folders[] = new TreeItemFolder($subFolder);
326
            }
327
            return new JsonResponse($folders);
328
        } catch (ResourceException $e) {
329
            return new JsonExceptionResponse($e);
330
        } catch (ControllerException $e) {
331
            return new JsonExceptionResponse($e);
332
        }
333
    }
334
335
    /**
336
     * Copy files or folders
337
     * Query parameters
338
     *  'identifiers' array of identifier to copy
339
     *  'targetFolderIdentifier' string the target identifier. Must be a folder.
340
     *  'conflictMode' string one of: "replace", "cancel", "rename", as defined in \TYPO3\CMS\Core\Resource\DuplicationBehavior
341
     *
342
     * @param ServerRequestInterface $request
343
     *
344
     * @return JsonResponse
345
     */
346
    public function copyResourcesAction(ServerRequestInterface $request): JsonResponse
347
    {
348
        try {
349
            $identifiers = $request->getQueryParams()['identifiers'];
350
            $conflictMode = $request->getQueryParams()['conflictMode'] ?? '';
351
            $targetFolderIdentifier = $request->getQueryParams()['targetFolderIdentifier'];
352
            if (empty($identifiers)) {
353
                throw new ControllerException('Identifiers needed', 1553699828);
354
            }
355
            if (empty($conflictMode) || !in_array($conflictMode, ['replace', 'cancel', 'rename'], true)) {
356
                throw new ControllerException('conflictMode must be one of "replace", "cancel", "rename"');
357
            }
358
            if (empty($targetFolderIdentifier)) {
359
                throw new ControllerException(
360
                    'Target folder identifier needed',
361
                    1554122023
362
                );
363
            }
364
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
365
            $targetFolderObject = $resourceFactory->getObjectFromCombinedIdentifier($targetFolderIdentifier);
366
            if (!$targetFolderObject instanceof Folder) {
367
                throw new ControllerException('Target identifier is not a folder', 1553701684);
368
            }
369
        } catch (ResourceException $e) {
370
            return new JsonExceptionResponse($e);
371
        } catch (ControllerException $e) {
372
            return new JsonExceptionResponse($e);
373
        }
374
        $resources = [];
375
        foreach ($identifiers as $identifier) {
376
            $state = FileOperationResult::FAILED;
377
            $message = '';
378
            $resultEntity = null;
379
            try {
380
                $sourceObject = $resourceFactory->getObjectFromCombinedIdentifier($identifier);
381
                if ($resultObject = $sourceObject->copyTo($targetFolderObject, null, (string)DuplicationBehavior::cast($conflictMode))) {
382
                    if ($resultObject instanceof Folder) {
383
                        $resultEntity = new FolderItemFolder($resultObject);
384
                    } else {
385
                        $resultEntity = new FolderItemFile($resultObject);
386
                    }
387
                    $state = FileOperationResult::COPIED;
388
                }
389
            } catch (InvalidTargetFolderException $e) {
390
                $message = $e->getMessage();
391
            } catch (ResourceException $e) {
392
                $message = $e->getMessage();
393
            }
394
            $resources[] = new FileOperationResult($identifier, $state, $message, $resultEntity);
395
        }
396
        return new FileOperationResponse($resources);
397
    }
398
399
    /**
400
     * Move files or folders
401
     * Query parameters
402
     *  'identifiers' array of identifier to move
403
     *  'targetFolderIdentifier' string the target identifier. Must be a folder.
404
     *  'conflictMode' string one of: "replace", "cancel", "rename", as defined in \TYPO3\CMS\Core\Resource\DuplicationBehavior
405
     *
406
     * @param ServerRequestInterface $request
407
     *
408
     * @return JsonResponse
409
     */
410
    public function moveResourcesAction(ServerRequestInterface $request): JsonResponse
411
    {
412
        try {
413
            $identifiers = $request->getQueryParams()['identifiers'];
414
            $conflictMode = $request->getQueryParams()['conflictMode'] ?? '';
415
            $targetFolderIdentifier = $request->getQueryParams()['targetFolderIdentifier'];
416
            if (empty($identifiers)) {
417
                throw new ControllerException('Identifiers needed', 1553699828);
418
            }
419
            if (empty($conflictMode) || !in_array($conflictMode, ['replace', 'cancel', 'rename'], true)) {
420
                throw new ControllerException('conflictMode must be one of "replace", "cancel", "rename"');
421
            }
422
            if (empty($targetFolderIdentifier)) {
423
                throw new ControllerException('Target folder identifier needed', 1554122023);
424
            }
425
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
426
            $targetFolderObject = $resourceFactory->getObjectFromCombinedIdentifier($targetFolderIdentifier);
427
            if (!$targetFolderObject instanceof Folder) {
428
                throw new ControllerException('Target identifier is not a folder', 1553701684);
429
            }
430
        } catch (ResourceException $e) {
431
            return new JsonExceptionResponse($e);
432
        } catch (ControllerException $e) {
433
            return new JsonExceptionResponse($e);
434
        }
435
        $resources = [];
436
        foreach ($identifiers as $identifier) {
437
            $state = FileOperationResult::FAILED;
438
            $message = '';
439
            $resultEntity = null;
440
            try {
441
                $sourceObject = $resourceFactory->getObjectFromCombinedIdentifier($identifier);
442
                if ($resultObject = $sourceObject->moveTo($targetFolderObject, null, (string)DuplicationBehavior::cast($conflictMode))) {
443
                    if ($resultObject instanceof Folder) {
444
                        $resultEntity = new FolderItemFolder($resultObject);
445
                    } else {
446
                        $resultEntity = new FolderItemFile($resultObject);
447
                    }
448
                    $state = FileOperationResult::MOVED;
449
                }
450
            } catch (InvalidTargetFolderException $e) {
451
                $message = $e->getMessage();
452
            } catch (ResourceException $e) {
453
                $message = $e->getMessage();
454
            }
455
            $resources[] = new FileOperationResult($identifier, $state, $message, $resultEntity);
456
        }
457
        return new FileOperationResponse($resources);
458
    }
459
460
    /**
461
     * rename file or folder
462
     * Query parameters
463
     *  'identifier' string identifier to rename
464
     *  'targetName' string The new name of file or folder.
465
     *  'conflictMode' string one of: "replace", "cancel", "rename"
466
     *
467
     * @param ServerRequestInterface $request
468
     *
469
     * @return JsonResponse
470
     */
471
    public function renameResourcesAction(ServerRequestInterface $request): JsonResponse
472
    {
473
        try {
474
            $identifier = $request->getQueryParams()['identifier'];
475
            $targetName = $request->getQueryParams()['targetName'];
476
            $conflictMode = $request->getQueryParams()['conflictMode'] ?? '';
477
            if (empty($identifier)) {
478
                throw new ControllerException('Identifier needed', 1553699828);
479
            }
480
            if (empty($conflictMode) || !in_array($conflictMode, ['replace', 'cancel', 'rename'], true)) {
481
                throw new ControllerException('conflictMode must be one of "replace", "cancel", "rename"');
482
            }
483
            if (empty($targetName)) {
484
                throw new ControllerException('Target name needed', 1554193259);
485
            }
486
            $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
487
            $fileOrFolder = $resourceFactory->retrieveFileOrFolderObject($identifier);
488
        } catch (ResourceException $e) {
489
            return new JsonExceptionResponse($e);
490
        } catch (ControllerException $e) {
491
            return new JsonExceptionResponse($e);
492
        }
493
        $resources = [];
494
        $state = FileOperationResult::FAILED;
495
        $resultEntity = null;
496
        try {
497
            if ($fileOrFolder === null) {
498
                throw new ResourceException\ResourceDoesNotExistException('Resource does not exist');
499
            } else {
500
                $resultObject = $fileOrFolder->rename($targetName, (string)DuplicationBehavior::cast($conflictMode));
501
                if ($resultObject instanceof Folder) {
502
                    $resultEntity = new FolderItemFolder($resultObject);
503
                    $message = 'Folder was successfully renamed';
504
                } else {
505
                    $resultEntity = new FolderItemFile($resultObject);
506
                    $message = 'File was successfully renamed';
507
                }
508
                $state = FileOperationResult::RENAMED;
509
            }
510
        } catch (ResourceException $e) {
511
            $message = $e->getMessage();
512
        }
513
        $resources[] = new FileOperationResult($identifier, $state, $message, $resultEntity);
514
        return new JsonResponse($resources);
515
    }
516
517
    /**
518
     * delete file or folder
519
     * Query parameters
520
     *  'identifiers' array of strings identifier of file or folder to delete
521
     *
522
     * @param ServerRequestInterface $request
523
     *
524
     * @return JsonResponse
525
     */
526
    public function deleteResourcesAction(ServerRequestInterface $request): JsonResponse
527
    {
528
        try {
529
            $identifiers = $request->getQueryParams()['identifiers'];
530
            if (empty($identifiers)) {
531
                throw new ControllerException('Identifiers needed', 1553699828);
532
            }
533
        } catch (ControllerException $e) {
534
            return new JsonExceptionResponse($e);
535
        }
536
        $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
537
        $resources = [];
538
        foreach ($identifiers as $identifier) {
539
            try {
540
                $sourceObject = $resourceFactory->getObjectFromCombinedIdentifier($identifier);
541
                if ($sourceObject->delete(true)) {
542
                    $state = FileOperationResult::DELETED;
543
                    $message = 'Resource deleted';
544
                } else {
545
                    $state = FileOperationResult::FAILED;
546
                    $message = 'Resource could not be deleted';
547
                }
548
            } catch (ResourceException $e) {
549
                $state = FileOperationResult::FAILED;
550
                $message = $e->getMessage();
551
            }
552
            $resources[] = new FileOperationResult($identifier, $state, $message, null);
553
        }
554
        return new FileOperationResponse($resources);
555
    }
556
557
    /**
558
     * @return BackendUserAuthentication
559
     */
560
    protected function getBackendUser(): BackendUserAuthentication
561
    {
562
        return $GLOBALS['BE_USER'];
563
    }
564
}
565