Completed
Push — master ( a18085...d4249c )
by Fabien
03:34
created

AssetController::updateAction()   C

Complexity

Conditions 9
Paths 37

Size

Total Lines 49
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 49
rs 5.7446
cc 9
eloc 34
nc 37
nop 1
1
<?php
2
namespace Fab\Media\Controller;
3
4
/**
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use Fab\Media\Module\MediaModule;
18
use TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException;
19
use TYPO3\CMS\Core\Resource\Exception\IllegalFileExtensionException;
20
use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderWritePermissionsException;
21
use TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException;
22
use TYPO3\CMS\Core\Resource\Exception\UploadException;
23
use TYPO3\CMS\Core\Resource\Exception\UploadSizeException;
24
use TYPO3\CMS\Core\Resource\File;
25
use TYPO3\CMS\Core\Resource\ResourceFactory;
26
use TYPO3\CMS\Core\Resource\ResourceStorage;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
29
use Fab\Media\FileUpload\UploadedFileInterface;
30
use Fab\Media\Thumbnail\ThumbnailInterface;
31
use Fab\Media\Thumbnail\ThumbnailService;
32
use Fab\Vidi\Persistence\MatcherObjectFactory;
33
use Fab\Vidi\Tca\Tca;
34
35
/**
36
 * Controller which handles actions related to Asset.
37
 */
38
class AssetController extends ActionController
39
{
40
41
    /**
42
     * @var \TYPO3\CMS\Core\Page\PageRenderer
43
     * @inject
44
     */
45
    protected $pageRenderer;
46
47
    /**
48
     * @var string
49
     */
50
    protected $dataType = 'sys_file';
51
52
    /**
53
     * @throws \Fab\Media\Exception\StorageNotOnlineException
54
     */
55 View Code Duplication
    public function initializeAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56
    {
57
        $this->pageRenderer->addInlineLanguageLabelFile('EXT:media/Resources/Private/Language/locallang.xlf');
58
59
        // Configure property mapping to retrieve the file object.
60
        if ($this->arguments->hasArgument('file')) {
61
62
            /** @var \Fab\Media\TypeConverter\FileConverter $typeConverter */
63
            $typeConverter = $this->objectManager->get('Fab\Media\TypeConverter\FileConverter');
64
65
            $propertyMappingConfiguration = $this->arguments->getArgument('file')->getPropertyMappingConfiguration();
66
            $propertyMappingConfiguration->setTypeConverter($typeConverter);
67
        }
68
    }
69
70
    /**
71
     * Force download of the file.
72
     *
73
     * @param File $file
74
     * @param bool $forceDownload
75
     * @return bool|string
76
     */
77
    public function downloadAction(File $file, $forceDownload = FALSE)
78
    {
79
80
        if ($file->exists() && $file->getStorage()->isWithinFileMountBoundaries($file->getParentFolder())) {
81
82
            // Emit signal before downloading the file.
83
            $this->emitBeforeDownloadSignal($file);
84
85
            // Read the file and dump it with the flag "forceDownload" set to TRUE or FALSE.
86
            $file->getStorage()->dumpFileContents($file, $forceDownload);
87
88
            $result = TRUE;
89
        } else {
90
            $result = 'Access denied!';
91
        }
92
93
        return $result;
94
    }
95
96
    /**
97
     * Handle file upload for a new file.
98
     *
99
     * @param string $combinedIdentifier
100
     * @validate $combinedIdentifier \Fab\Media\Domain\Validator\StorageValidator
101
     * @return string
102
     */
103
    public function createAction($combinedIdentifier)
104
    {
105
        /** @var UploadedFileInterface $uploadedFile */
106
        $uploadedFile = $this->handleUpload();
107
        if (!is_object($uploadedFile)) {
108
            return htmlspecialchars(json_encode($uploadedFile), ENT_NOQUOTES);
109
        }
110
111
        // Get the target folder.
112
        if ($this->getMediaModule()->hasFolderTree()) {
113
            $targetFolder = $this->getMediaModule()->getFolderForCombinedIdentifier($combinedIdentifier);
114
        } else {
115
            $storage = ResourceFactory::getInstance()->getStorageObjectFromCombinedIdentifier($combinedIdentifier);
116
            $targetFolder = $this->getMediaModule()->getTargetFolderForUploadedFile($uploadedFile, $storage);
117
        }
118
119
        try {
120
            $conflictMode = 'changeName';
121
            $fileName = $uploadedFile->getName();
122
            $file = $targetFolder->addFile($uploadedFile->getFileWithAbsolutePath(), $fileName, $conflictMode);
123
124
            // Run the indexer for extracting metadata.
125
            $this->getMediaIndexer($file->getStorage())
126
                ->extractMetadata($file)
127
                ->applyDefaultCategories($file);
128
129
            $response = array(
130
                'success' => TRUE,
131
                'uid' => $file->getUid(),
132
                'name' => $file->getName(),
133
                'thumbnail' => $this->getThumbnailService($file)->create(),
134
            );
135
        } catch (UploadException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\Exception\UploadException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
136
            $response = array('error' => 'The upload has failed, no uploaded file found!');
137
        } catch (InsufficientUserPermissionsException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...serPermissionsException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
138
            $response = array('error' => 'You are not allowed to upload files!');
139
        } catch (UploadSizeException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...ion\UploadSizeException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
140
            $response = array('error' => vsprintf('The uploaded file "%s" exceeds the size-limit', array($uploadedFile->getName())));
141
        } catch (InsufficientFolderWritePermissionsException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...itePermissionsException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
142
            $response = array('error' => vsprintf('Destination path "%s" was not within your mount points!', array($targetFolder->getIdentifier())));
143
        } catch (IllegalFileExtensionException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...lFileExtensionException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
144
            $response = array('error' => vsprintf('Extension of file name "%s" is not allowed in "%s"!', array($uploadedFile->getName(), $targetFolder->getIdentifier())));
145
        } catch (ExistingTargetFileNameException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...TargetFileNameException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
146
            $response = array('error' => vsprintf('No unique filename available in "%s"!', array($targetFolder->getIdentifier())));
147
        } catch (\RuntimeException $e) {
148
            $response = array('error' => vsprintf('Uploaded file could not be moved! Write-permission problem in "%s"?', array($targetFolder->getIdentifier())));
149
        }
150
151
        // to pass data through iframe you will need to encode all html tags
152
        header("Content-Type: text/plain");
153
        return htmlspecialchars(json_encode($response), ENT_NOQUOTES);
154
    }
155
156
    /**
157
     * Handle file upload for an existing file.
158
     *
159
     * @param File $file
160
     * @return string
161
     */
162
    public function updateAction(File $file)
163
    {
164
        $uploadedFile = $this->handleUpload();
165
        if (!is_object($uploadedFile)) {
166
            return htmlspecialchars(json_encode($uploadedFile), ENT_NOQUOTES);
167
        }
168
169
        /** @var $file File */
170
        $targetFolder = $file->getStorage()->getFolder(dirname($file->getIdentifier()));
171
172
        try {
173
            $storage = $file->getStorage();
174
            $storage->replaceFile($file, $uploadedFile->getFileWithAbsolutePath());
175
176
            // Run the indexer for extracting metadata.
177
            $this->getMediaIndexer($file->getStorage())
178
                ->updateIndex($file)
179
                ->extractMetadata($file);
180
181
            // Clear cache on pages holding a reference to this file.
182
            $this->getCacheService()->clearCache($file);
183
184
            $response = array(
185
                'success' => TRUE,
186
                'uid' => $file->getUid(),
187
                'name' => $file->getName(),
188
                'thumbnail' => $this->getThumbnailService($file)->create(),
189
                'fileInfo' => $this->getMetadataViewHelper()->render($file),
190
            );
191
        } catch (UploadException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\Exception\UploadException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
192
            $response = array('error' => 'The upload has failed, no uploaded file found!');
193
        } catch (InsufficientUserPermissionsException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...serPermissionsException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
194
            $response = array('error' => 'You are not allowed to upload files!');
195
        } catch (UploadSizeException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...ion\UploadSizeException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
196
            $response = array('error' => vsprintf('The uploaded file "%s" exceeds the size-limit', array($uploadedFile->getName())));
197
        } catch (InsufficientFolderWritePermissionsException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...itePermissionsException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
198
            $response = array('error' => vsprintf('Destination path "%s" was not within your mount points!', array($targetFolder->getIdentifier())));
199
        } catch (IllegalFileExtensionException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...lFileExtensionException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
200
            $response = array('error' => vsprintf('Extension of file name "%s" is not allowed in "%s"!', array($uploadedFile->getName(), $targetFolder->getIdentifier())));
201
        } catch (ExistingTargetFileNameException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Core\Resource\...TargetFileNameException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
202
            $response = array('error' => vsprintf('No unique filename available in "%s"!', array($targetFolder->getIdentifier())));
203
        } catch (\RuntimeException $e) {
204
            $response = array('error' => vsprintf('Uploaded file could not be moved! Write-permission problem in "%s"?', array($targetFolder->getIdentifier())));
205
        }
206
207
        // to pass data through iframe you will need to encode all html tags
208
        header("Content-Type: text/plain");
209
        return htmlspecialchars(json_encode($response), ENT_NOQUOTES);
210
    }
211
212
    /**
213
     * Returns an editing form for moving Files between storage.
214
     *
215
     * @param array $matches
216
     * @throws \Exception
217
     */
218
    public function editStorageAction(array $matches = array())
219
    {
220
221
        $this->view->assign('storages', $this->getMediaModule()->getAllowedStorages());
222
        $this->view->assign('storageTitle', Tca::table('sys_file_storage')->getTitle());
223
224
        $fieldName = 'storage';
225
226
        // Instantiate the Matcher object according different rules.
227
        $matcher = MatcherObjectFactory::getInstance()->getMatcher($matches, $this->dataType);
228
229
        // Fetch objects via the Content Service.
230
        $contentService = $this->getContentService()->findBy($matcher);
231
232
        $fieldType = Tca::table($this->dataType)->field($fieldName)->getType();
233
234
        $this->view->assign('fieldType', ucfirst($fieldType));
235
        $this->view->assign('dataType', $this->dataType);
236
        $this->view->assign('matches', $matches);
237
        $this->view->assign('fieldNameAndPath', $fieldName);
238
        $this->view->assign('numberOfObjects', $contentService->getNumberOfObjects());
239
        $this->view->assign('editWholeSelection', empty($matches['uid'])); // necessary??
240
    }
241
242
    /**
243
     * Handle file upload.
244
     *
245
     * @return \Fab\Media\FileUpload\UploadedFileInterface|array
246
     */
247
    protected function handleUpload()
248
    {
249
250
        /** @var $uploadManager \Fab\Media\FileUpload\UploadManager */
251
        $uploadManager = GeneralUtility::makeInstance('Fab\Media\FileUpload\UploadManager');
252
253
        try {
254
            /** @var $result \Fab\Media\FileUpload\UploadedFileInterface */
255
            $result = $uploadManager->handleUpload();
256
        } catch (\Exception $e) {
257
            $result = array('error' => $e->getMessage());
258
        }
259
260
        return $result;
261
    }
262
263
    /**
264
     * @return \Fab\Media\ViewHelpers\MetadataViewHelper
265
     */
266
    protected function getMetadataViewHelper()
267
    {
268
        return GeneralUtility::makeInstance('Fab\Media\ViewHelpers\MetadataViewHelper');
269
    }
270
271
    /**
272
     * @param File $file
273
     * @return ThumbnailService
274
     */
275
    protected function getThumbnailService(File $file)
276
    {
277
278
        /** @var $thumbnailService ThumbnailService */
279
        $thumbnailService = GeneralUtility::makeInstance('Fab\Media\Thumbnail\ThumbnailService', $file);
280
        $thumbnailService->setAppendTimeStamp(TRUE)
281
            ->setOutputType(ThumbnailInterface::OUTPUT_IMAGE_WRAPPED);
282
        return $thumbnailService;
283
    }
284
285
    /**
286
     * Get the instance of the Indexer service to update the metadata of the file.
287
     *
288
     * @param int|ResourceStorage $storage
289
     * @return \Fab\Media\Index\MediaIndexer
290
     */
291
    protected function getMediaIndexer($storage)
292
    {
293
        return GeneralUtility::makeInstance('Fab\Media\Index\MediaIndexer', $storage);
294
    }
295
296
    /**
297
     * @return \Fab\Media\Cache\CacheService
298
     */
299
    protected function getCacheService()
300
    {
301
        return GeneralUtility::makeInstance('Fab\Media\Cache\CacheService');
302
    }
303
304
    /**
305
     * Signal that is emitted before a file is downloaded.
306
     *
307
     * @param File $file
308
     * @return void
309
     * @signal
310
     */
311
    protected function emitBeforeDownloadSignal(File $file)
312
    {
313
        $this->getSignalSlotDispatcher()->dispatch('Fab\Media\Controller\Backend\AssetController', 'beforeDownload', array($file));
314
    }
315
316
    /**
317
     * Get the SignalSlot dispatcher.
318
     *
319
     * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
320
     */
321
    protected function getSignalSlotDispatcher()
322
    {
323
        return $this->objectManager->get('TYPO3\CMS\Extbase\SignalSlot\Dispatcher');
324
    }
325
326
    /**
327
     * Get the Vidi Module Loader.
328
     *
329
     * @return \Fab\Vidi\Service\ContentService
330
     */
331
    protected function getContentService()
332
    {
333
        return GeneralUtility::makeInstance('Fab\Vidi\Service\ContentService', $this->dataType);
334
    }
335
336
    /**
337
     * @return MediaModule
338
     */
339
    protected function getMediaModule()
340
    {
341
        return GeneralUtility::makeInstance('Fab\Media\Module\MediaModule');
342
    }
343
344
}
345