Completed
Push — vuejs ( 7de45f...a62f8c )
by Frank
05:00 queued 02:20
created

AjaxController::fileExistsAction()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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