Passed
Push — master ( 3b189c...342025 )
by Stream
03:51
created

LfmPath::uploadValidator()   C

Complexity

Conditions 12
Paths 13

Size

Total Lines 41
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 12
eloc 23
c 1
b 1
f 0
nc 13
nop 1
dl 0
loc 41
rs 6.9666

How to fix   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
namespace UniSharp\LaravelFilemanager;
4
5
use Illuminate\Container\Container;
6
use Intervention\Image\Facades\Image;
7
use Symfony\Component\HttpFoundation\File\UploadedFile;
8
use UniSharp\LaravelFilemanager\Events\ImageIsUploading;
9
use UniSharp\LaravelFilemanager\Events\ImageWasUploaded;
10
11
class LfmPath
12
{
13
    private $working_dir;
14
    private $item_name;
15
    private $is_thumb = false;
16
17
    private $helper;
18
19
    public function __construct(Lfm $lfm = null)
20
    {
21
        $this->helper = $lfm;
22
    }
23
24
    public function __get($var_name)
25
    {
26
        if ($var_name == 'storage') {
27
            return $this->helper->getStorage($this->path('url'));
0 ignored issues
show
Bug introduced by
The method getStorage() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
            return $this->helper->/** @scrutinizer ignore-call */ getStorage($this->path('url'));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28
        }
29
    }
30
31
    public function __call($function_name, $arguments)
32
    {
33
        return $this->storage->$function_name(...$arguments);
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
34
    }
35
36
    public function dir($working_dir)
37
    {
38
        $this->working_dir = $working_dir;
39
40
        return $this;
41
    }
42
43
    public function thumb($is_thumb = true)
44
    {
45
        $this->is_thumb = $is_thumb;
46
47
        return $this;
48
    }
49
50
    public function setName($item_name)
51
    {
52
        $this->item_name = $item_name;
53
54
        return $this;
55
    }
56
57
    public function getName()
58
    {
59
        return $this->item_name;
60
    }
61
62
    public function path($type = 'storage')
63
    {
64
        if ($type == 'working_dir') {
65
            // working directory: /{user_slug}
66
            return $this->translateToLfmPath($this->normalizeWorkingDir());
67
        } elseif ($type == 'url') {
68
            // storage: files/{user_slug}
69
            return $this->helper->getCategoryName() . $this->path('working_dir');
70
        } elseif ($type == 'storage') {
71
            // storage: files/{user_slug}
72
            // storage on windows: files\{user_slug}
73
            return str_replace(Lfm::DS, $this->helper->ds(), $this->path('url'));
74
        } else {
75
            // absolute: /var/www/html/project/storage/app/files/{user_slug}
76
            // absolute on windows: C:\project\storage\app\files\{user_slug}
77
            return $this->storage->rootPath() . $this->path('storage');
0 ignored issues
show
Bug introduced by
The method rootPath() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
            return $this->storage->/** @scrutinizer ignore-call */ rootPath() . $this->path('storage');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
78
        }
79
    }
80
81
    public function translateToLfmPath($path)
82
    {
83
        return str_replace($this->helper->ds(), Lfm::DS, $path);
84
    }
85
86
    public function url()
87
    {
88
        return $this->storage->url($this->path('url'));
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
89
    }
90
91
    public function folders()
92
    {
93
        $all_folders = array_map(function ($directory_path) {
94
            return $this->pretty($directory_path, true);
95
        }, $this->storage->directories());
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method directories() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

95
        }, $this->storage->/** @scrutinizer ignore-call */ directories());
Loading history...
96
97
        $folders = array_filter($all_folders, function ($directory) {
98
            return $directory->name !== $this->helper->getThumbFolderName();
99
        });
100
101
        return $this->sortByColumn($folders);
102
    }
103
104
    public function files()
105
    {
106
        $files = array_map(function ($file_path) {
107
            return $this->pretty($file_path);
108
        }, $this->storage->files());
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method files() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
        }, $this->storage->/** @scrutinizer ignore-call */ files());
Loading history...
109
110
        return $this->sortByColumn($files);
111
    }
112
113
    public function pretty($item_path, $isDirectory = false)
114
    {
115
        return Container::getInstance()->makeWith(LfmItem::class, [
116
            'lfm' => (clone $this)->setName($this->helper->getNameFromPath($item_path)),
117
            'helper' => $this->helper,
118
            'isDirectory' => $isDirectory
119
        ]);
120
    }
121
122
    public function delete()
123
    {
124
        if ($this->isDirectory()) {
125
            return $this->storage->deleteDirectory();
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method deleteDirectory() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

125
            return $this->storage->/** @scrutinizer ignore-call */ deleteDirectory();
Loading history...
126
        } else {
127
            return $this->storage->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

127
            return $this->storage->/** @scrutinizer ignore-call */ delete();
Loading history...
128
        }
129
    }
130
131
    /**
132
     * Create folder if not exist.
133
     *
134
     * @param  string  $path  Real path of a directory.
135
     * @return bool
136
     */
137
    public function createFolder()
138
    {
139
        if ($this->storage->exists($this)) {
0 ignored issues
show
Bug introduced by
The method exists() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

139
        if ($this->storage->/** @scrutinizer ignore-call */ exists($this)) {
Loading history...
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
140
            return false;
141
        }
142
143
        $this->storage->makeDirectory(0777, true, true);
144
    }
145
146
    public function isDirectory()
147
    {
148
        $working_dir = $this->path('working_dir');
149
        $parent_dir = substr($working_dir, 0, strrpos($working_dir, '/'));
150
151
        $parent_directories = array_map(function ($directory_path) {
152
            return app(static::class)->translateToLfmPath($directory_path);
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

152
            return /** @scrutinizer ignore-call */ app(static::class)->translateToLfmPath($directory_path);
Loading history...
153
        }, app(static::class)->dir($parent_dir)->directories());
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

153
        }, /** @scrutinizer ignore-call */ app(static::class)->dir($parent_dir)->directories());
Loading history...
154
155
        return in_array($this->path('url'), $parent_directories);
156
    }
157
158
    /**
159
     * Check a folder and its subfolders is empty or not.
160
     *
161
     * @param  string  $directory_path  Real path of a directory.
162
     * @return bool
163
     */
164
    public function directoryIsEmpty()
165
    {
166
        return count($this->storage->allFiles()) == 0;
0 ignored issues
show
Bug introduced by
The method allFiles() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
        return count($this->storage->/** @scrutinizer ignore-call */ allFiles()) == 0;
Loading history...
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
167
    }
168
169
    public function normalizeWorkingDir()
170
    {
171
        $path = $this->working_dir
172
            ?: $this->helper->input('working_dir')
173
            ?: $this->helper->getRootFolder();
174
175
        if ($this->is_thumb) {
176
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
177
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->helper->getThumbFolderName();
178
        }
179
180
        if ($this->getName()) {
181
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
182
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->getName();
183
        }
184
185
        return $path;
186
    }
187
188
    /**
189
     * Sort files and directories.
190
     *
191
     * @param  mixed  $arr_items  Array of files or folders or both.
192
     * @return array of object
193
     */
194
    public function sortByColumn($arr_items)
195
    {
196
        $sort_by = $this->helper->input('sort_type');
197
        if (in_array($sort_by, ['name', 'time'])) {
198
            $key_to_sort = $sort_by;
199
        } else {
200
            $key_to_sort = 'name';
201
        }
202
203
        uasort($arr_items, function ($a, $b) use ($key_to_sort) {
204
            return strcmp($a->{$key_to_sort}, $b->{$key_to_sort});
205
        });
206
207
        return $arr_items;
208
    }
209
210
    public function error($error_type, $variables = [])
211
    {
212
        throw new \Exception($this->helper->error($error_type, $variables));
213
    }
214
215
    // Upload section
216
    public function upload($file)
217
    {
218
        $this->uploadValidator($file);
219
        $new_file_name = $this->getNewName($file);
220
        $new_file_path = $this->setName($new_file_name)->path('absolute');
221
222
        event(new ImageIsUploading($new_file_path));
0 ignored issues
show
Bug introduced by
The function event was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

222
        /** @scrutinizer ignore-call */ 
223
        event(new ImageIsUploading($new_file_path));
Loading history...
223
        try {
224
            $new_file_name = $this->saveFile($file, $new_file_name);
225
        } catch (\Exception $e) {
226
            \Log::info($e);
227
            return $this->error('invalid');
228
        }
229
        // TODO should be "FileWasUploaded"
230
        event(new ImageWasUploaded($new_file_path));
231
232
        return $new_file_name;
233
    }
234
235
    private function uploadValidator($file)
236
    {
237
        if (empty($file)) {
238
            return $this->error('file-empty');
239
        } elseif (! $file instanceof UploadedFile) {
240
            return $this->error('instance');
241
        } elseif ($file->getError() == UPLOAD_ERR_INI_SIZE) {
242
            return $this->error('file-size', ['max' => ini_get('upload_max_filesize')]);
243
        } elseif ($file->getError() != UPLOAD_ERR_OK) {
244
            throw new \Exception('File failed to upload. Error code: ' . $file->getError());
245
        }
246
247
        $new_file_name = $this->getNewName($file);
248
249
        if ($this->setName($new_file_name)->exists() && !config('lfm.over_write_on_duplicate')) {
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

249
        if ($this->setName($new_file_name)->exists() && !/** @scrutinizer ignore-call */ config('lfm.over_write_on_duplicate')) {
Loading history...
Bug introduced by
The method exists() does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

249
        if ($this->setName($new_file_name)->/** @scrutinizer ignore-call */ exists() && !config('lfm.over_write_on_duplicate')) {
Loading history...
250
            return $this->error('file-exist');
251
        }
252
253
        $mimetype = $file->getMimeType();
254
255
        $excutable = ['text/x-php'];
256
257
        if (in_array($mimetype, $excutable)) {
258
            throw new \Exception('Invalid file detected');
259
        }
260
261
        if (config('lfm.should_validate_mime', false)) {
262
            if (false === in_array($mimetype, $this->helper->availableMimeTypes())) {
263
                return $this->error('mime') . $mimetype;
264
            }
265
        }
266
267
        if (config('lfm.should_validate_size', false)) {
268
            // size to kb unit is needed
269
            $file_size = $file->getSize() / 1000;
270
            if ($file_size > $this->helper->maxUploadSize()) {
271
                return $this->error('size') . $file_size;
272
            }
273
        }
274
275
        return 'pass';
276
    }
277
278
    private function getNewName($file)
279
    {
280
        $new_file_name = $this->helper
281
            ->translateFromUtf8(trim(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)));
282
283
        $extension = $file->getClientOriginalExtension();
284
285
        if (config('lfm.rename_file') === true) {
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

285
        if (/** @scrutinizer ignore-call */ config('lfm.rename_file') === true) {
Loading history...
286
            $new_file_name = uniqid();
287
        } elseif (config('lfm.alphanumeric_filename') === true) {
288
            $new_file_name = preg_replace('/[^A-Za-z0-9\-\']/', '_', $new_file_name);
289
        }
290
291
        if ($extension) {
292
            $new_file_name_with_extention = $new_file_name . '.' . $extension;
293
        }
294
295
        if (config('lfm.rename_duplicates') === true) {
296
            $counter = 1;
297
            $file_name_without_extentions = $new_file_name;
298
            while ($this->setName(($extension) ? $new_file_name_with_extention : $new_file_name)->exists()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $new_file_name_with_extention does not seem to be defined for all execution paths leading up to this point.
Loading history...
299
                if (config('lfm.alphanumeric_filename') === true) {
300
                    $suffix = '_'.$counter;
301
                } else {
302
                    $suffix = " ({$counter})";
303
                }
304
                $new_file_name = $file_name_without_extentions.$suffix;
305
306
                if ($extension) {
307
                    $new_file_name_with_extention = $new_file_name . '.' . $extension;
308
                }
309
                $counter++;
310
            }
311
        }
312
313
        return ($extension) ? $new_file_name_with_extention : $new_file_name;
314
    }
315
316
    private function saveFile($file, $new_file_name)
317
    {
318
        $this->setName($new_file_name)->storage->save($file);
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method save() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

318
        $this->setName($new_file_name)->storage->/** @scrutinizer ignore-call */ 
319
                                                 save($file);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
319
320
        $this->makeThumbnail($new_file_name);
321
322
        return $new_file_name;
323
    }
324
325
    public function makeThumbnail($file_name)
326
    {
327
        $original_image = $this->pretty($file_name);
328
329
        if (!$original_image->shouldCreateThumb()) {
330
            return;
331
        }
332
333
        // create folder for thumbnails
334
        $this->setName(null)->thumb(true)->createFolder();
335
336
        // generate cropped image content
337
        $this->setName($file_name)->thumb(true);
338
        $image = Image::make($original_image->get())
339
            ->fit(config('lfm.thumb_img_width', 200), config('lfm.thumb_img_height', 200));
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

339
            ->fit(/** @scrutinizer ignore-call */ config('lfm.thumb_img_width', 200), config('lfm.thumb_img_height', 200));
Loading history...
340
341
        $this->storage->put($image->stream()->detach(), 'public');
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on UniSharp\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method put() does not exist on UniSharp\LaravelFilemanager\LfmStorageRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

341
        $this->storage->/** @scrutinizer ignore-call */ 
342
                        put($image->stream()->detach(), 'public');
Loading history...
342
    }
343
}
344