FileUpload::execute()   F
last analyzed

Complexity

Conditions 31
Paths 492

Size

Total Lines 133
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 31
eloc 75
c 0
b 0
f 0
nc 492
nop 6
dl 0
loc 133
rs 0.7055

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * CKFinder
5
 * ========
6
 * http://cksource.com/ckfinder
7
 * Copyright (C) 2007-2016, CKSource - Frederico Knabben. All rights reserved.
8
 *
9
 * The software, this file and its contents are subject to the CKFinder
10
 * License. Please read the license.txt file before using, installing, copying,
11
 * modifying or distribute this file or part of its contents. The contents of
12
 * this file is part of the Source Code of CKFinder.
13
 */
14
15
namespace CKSource\CKFinder\Command;
16
17
use CKSource\CKFinder\Acl\Permission;
18
use CKSource\CKFinder\Cache\CacheManager;
19
use CKSource\CKFinder\Event\AfterCommandEvent;
20
use CKSource\CKFinder\Event\CKFinderEvent;
21
use CKSource\CKFinder\Config;
22
use CKSource\CKFinder\Error;
23
use CKSource\CKFinder\Exception\InvalidExtensionException;
24
use CKSource\CKFinder\Exception\InvalidNameException;
25
use CKSource\CKFinder\Exception\InvalidUploadException;
26
use CKSource\CKFinder\Filesystem\File\UploadedFile;
27
use CKSource\CKFinder\Event\FileUploadEvent;
28
use CKSource\CKFinder\Filesystem\Path;
29
use CKSource\CKFinder\Image;
30
use CKSource\CKFinder\Filesystem\Folder\WorkingFolder;
31
use CKSource\CKFinder\Thumbnail\ThumbnailRepository;
32
use Symfony\Component\EventDispatcher\EventDispatcher;
33
use Symfony\Component\HttpFoundation\Request;
34
35
class FileUpload extends CommandAbstract
36
{
37
    protected $requestMethod = Request::METHOD_POST;
38
39
    protected $requires = array(Permission::FILE_CREATE);
40
41
    public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, Config $config, CacheManager $cache, ThumbnailRepository $thumbsRepository)
42
    {
43
        // #111 IE9 download JSON issue workaround
44
        if ($request->get('asPlainText')) {
45
            $uploadEvents = array(
46
                CKFinderEvent::AFTER_COMMAND_FILE_UPLOAD,
47
                CKFinderEvent::AFTER_COMMAND_QUICK_UPLOAD
48
            );
49
50
            foreach ($uploadEvents as $eventName) {
51
                $dispatcher->addListener($eventName, function (AfterCommandEvent $event) {
52
                    $response = $event->getResponse();
53
                    $response->headers->set('Content-Type', 'text/plain');
54
                });
55
            }
56
        }
57
58
        $uploaded = 0;
59
60
        $warningErrorCode = null;
61
        $upload = $request->files->get('upload');
62
63
        if (null === $upload) {
64
            throw new InvalidUploadException();
65
        }
66
67
        $uploadedFile = new UploadedFile($upload, $this->app);
68
69
        if (!$uploadedFile->isValid()) {
70
            throw new InvalidUploadException($uploadedFile->getErrorMessage());
71
        }
72
73
        $uploadedFile->sanitizeFilename();
74
75
        if ($uploadedFile->wasRenamed()) {
76
            $warningErrorCode = Error::UPLOADED_INVALID_NAME_RENAMED;
77
        }
78
79
        if (!$uploadedFile->hasValidFilename() || $uploadedFile->isHiddenFile()) {
80
            throw new InvalidNameException();
81
        }
82
83
        if (!$uploadedFile->hasAllowedExtension()) {
84
            throw new InvalidExtensionException();
85
        }
86
87
        // Autorename if required
88
        $overwriteOnUpload = $config->get('overwriteOnUpload');
89
        if (!$overwriteOnUpload && $uploadedFile->autorename()) {
90
            $warningErrorCode = Error::UPLOADED_FILE_RENAMED;
91
        }
92
93
        $fileName = $uploadedFile->getFilename();
94
95
        if (!$uploadedFile->isAllowedHtmlFile() && $uploadedFile->containsHtml()) {
96
            throw new InvalidUploadException('HTML detected in disallowed file type', Error::UPLOADED_WRONG_HTML_FILE);
97
        }
98
99
        if ($config->get('secureImageUploads') && $uploadedFile->isImage() && !$uploadedFile->isValidImage()) {
100
            throw new InvalidUploadException('Invalid upload: corrupted image', Error::UPLOADED_CORRUPT);
101
        }
102
103
        $maxFileSize = $workingFolder->getResourceType()->getMaxSize();
104
105
        if (!$config->get('checkSizeAfterScaling') && $maxFileSize && $uploadedFile->getSize() > $maxFileSize) {
106
            throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG);
107
        }
108
109
        if (Image::isSupportedExtension($uploadedFile->getExtension())) {
110
            $imagesConfig = $config->get('images');
111
            $image = Image::create($uploadedFile->getContents());
112
113
            if ($imagesConfig['maxWidth'] && $image->getWidth() > $imagesConfig['maxWidth'] ||
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($imagesConfig['maxWidth...agesConfig['maxHeight'], Probably Intended Meaning: $imagesConfig['maxWidth'...gesConfig['maxHeight'])
Loading history...
114
                $imagesConfig['maxHeight'] && $image->getHeight() > $imagesConfig['maxHeight']) {
115
                $image->resize($imagesConfig['maxWidth'], $imagesConfig['maxHeight'], $imagesConfig['quality']);
116
                $imageData = $image->getData();
117
                $uploadedFile->save($imageData);
118
            }
119
120
            $cache->set(
121
                Path::combine(
122
                    $workingFolder->getResourceType()->getName(),
123
                    $workingFolder->getClientCurrentFolder(),
124
                    $fileName),
125
                $image->getInfo()
126
            );
127
128
            unset($imageData);
129
            unset($image);
130
        }
131
132
        if ($maxFileSize && $uploadedFile->getSize() > $maxFileSize) {
133
            throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG);
134
        }
135
136
        $event = new FileUploadEvent($this->app, $uploadedFile);
137
        $dispatcher->dispatch(CKFinderEvent::FILE_UPLOAD, $event);
138
139
        if (!$event->isPropagationStopped()) {
140
            $uploadedFileStream = $uploadedFile->getContentsStream();
141
            $uploaded = (int) $workingFolder->putStream($fileName, $uploadedFileStream, $uploadedFile->getMimeType());
142
143
            if (is_resource($uploadedFileStream)) {
144
                fclose($uploadedFileStream);
145
            }
146
147
            if ($overwriteOnUpload) {
148
                $thumbsRepository->deleteThumbnails(
149
                    $workingFolder->getResourceType(),
150
                    $workingFolder->getClientCurrentFolder(),
151
                    $fileName
152
                );
153
            }
154
155
            if (!$uploaded) {
156
                $warningErrorCode = Error::ACCESS_DENIED;
157
            }
158
        }
159
160
        $responseData = array(
161
            'fileName' => $fileName,
162
            'uploaded' => $uploaded
163
        );
164
165
        if ($warningErrorCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $warningErrorCode of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
166
            $errorMessage = $this->app['translator']->translateErrorMessage($warningErrorCode, array('name' => $fileName));
167
            $responseData['error'] = array(
168
                'number'  => $warningErrorCode,
169
                'message' => $errorMessage
170
            );
171
        }
172
173
        return $responseData;
174
    }
175
}
176