Passed
Pull Request — master (#1103)
by
unknown
03:41
created

LfmPath   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 308
Duplicated Lines 0 %

Importance

Changes 13
Bugs 5 Features 2
Metric Value
eloc 125
c 13
b 5
f 2
dl 0
loc 308
rs 6.96
wmc 53

24 Methods

Rating   Name   Duplication   Size   Complexity  
A dir() 0 5 1
A files() 0 7 1
A getName() 0 3 1
A delete() 0 6 2
A directoryIsEmpty() 0 3 1
A error() 0 3 1
A __call() 0 3 1
A setName() 0 5 1
A isDirectory() 0 10 1
A path() 0 16 4
A url() 0 3 1
A folders() 0 11 1
A translateToLfmPath() 0 3 1
A __get() 0 4 2
A pretty() 0 6 1
A createFolder() 0 7 2
A __construct() 0 3 1
A normalizeWorkingDir() 0 17 5
A sortByColumn() 0 14 2
A thumb() 0 5 1
A upload() 0 18 2
A validateUploadedFile() 0 23 4
B getNewName() 0 37 10
A generateThumbnail() 0 19 6

How to fix   Complexity   

Complex Class

Complex classes like LfmPath often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LfmPath, and based on these observations, apply Extract Interface, too.

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
use UniSharp\LaravelFilemanager\LfmUploadValidator;
11
12
class LfmPath
13
{
14
    private $working_dir;
15
    private $item_name;
16
    private $is_thumb = false;
17
18
    private $helper;
19
20
    public function __construct(Lfm $lfm = null)
21
    {
22
        $this->helper = $lfm;
23
    }
24
25
    public function __get($var_name)
26
    {
27
        if ($var_name == 'storage') {
28
            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

28
            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...
29
        }
30
    }
31
32
    public function __call($function_name, $arguments)
33
    {
34
        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...
35
    }
36
37
    public function dir($working_dir)
38
    {
39
        $this->working_dir = $working_dir;
40
41
        return $this;
42
    }
43
44
    public function thumb($is_thumb = true)
45
    {
46
        $this->is_thumb = $is_thumb;
47
48
        return $this;
49
    }
50
51
    public function setName($item_name)
52
    {
53
        $this->item_name = $item_name;
54
55
        return $this;
56
    }
57
58
    public function getName()
59
    {
60
        return $this->item_name;
61
    }
62
63
    public function path($type = 'storage')
64
    {
65
        if ($type == 'working_dir') {
66
            // working directory: /{user_slug}
67
            return $this->translateToLfmPath($this->normalizeWorkingDir());
68
        } elseif ($type == 'url') {
69
            // storage: files/{user_slug}
70
            return $this->helper->getCategoryName() . $this->path('working_dir');
71
        } elseif ($type == 'storage') {
72
            // storage: files/{user_slug}
73
            // storage on windows: files\{user_slug}
74
            return str_replace(Lfm::DS, $this->helper->ds(), $this->path('url'));
75
        } else {
76
            // absolute: /var/www/html/project/storage/app/files/{user_slug}
77
            // absolute on windows: C:\project\storage\app\files\{user_slug}
78
            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

78
            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...
79
        }
80
    }
81
82
    public function translateToLfmPath($path)
83
    {
84
        return str_replace($this->helper->ds(), Lfm::DS, $path);
85
    }
86
87
    public function url()
88
    {
89
        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...
90
    }
91
92
    public function folders()
93
    {
94
        $all_folders = array_map(function ($directory_path) {
95
            return $this->pretty($directory_path, true);
96
        }, $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

96
        }, $this->storage->/** @scrutinizer ignore-call */ directories());
Loading history...
97
98
        $folders = array_filter($all_folders, function ($directory) {
99
            return $directory->name !== $this->helper->getThumbFolderName();
100
        });
101
102
        return $this->sortByColumn($folders);
103
    }
104
105
    public function files()
106
    {
107
        $files = array_map(function ($file_path) {
108
            return $this->pretty($file_path);
109
        }, $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

109
        }, $this->storage->/** @scrutinizer ignore-call */ files());
Loading history...
110
111
        return $this->sortByColumn($files);
112
    }
113
114
    public function pretty($item_path, $isDirectory = false)
115
    {
116
        return Container::getInstance()->makeWith(LfmItem::class, [
117
            'lfm' => (clone $this)->setName($this->helper->getNameFromPath($item_path)),
118
            'helper' => $this->helper,
119
            'isDirectory' => $isDirectory
120
        ]);
121
    }
122
123
    public function delete()
124
    {
125
        if ($this->isDirectory()) {
126
            return $this->storage->deleteDirectory();
0 ignored issues
show
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

126
            return $this->storage->/** @scrutinizer ignore-call */ deleteDirectory();
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...
127
        } else {
128
            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

128
            return $this->storage->/** @scrutinizer ignore-call */ delete();
Loading history...
129
        }
130
    }
131
132
    /**
133
     * Create folder if not exist.
134
     *
135
     * @param  string  $path  Real path of a directory.
136
     * @return bool
137
     */
138
    public function createFolder()
139
    {
140
        if ($this->storage->exists($this)) {
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 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

140
        if ($this->storage->/** @scrutinizer ignore-call */ exists($this)) {
Loading history...
141
            return false;
142
        }
143
144
        $this->storage->makeDirectory(0777, true, true);
145
    }
146
147
    public function isDirectory()
148
    {
149
        $working_dir = $this->path('working_dir');
150
        $parent_dir = substr($working_dir, 0, strrpos($working_dir, '/'));
151
152
        $parent_directories = array_map(function ($directory_path) {
153
            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

153
            return /** @scrutinizer ignore-call */ app(static::class)->translateToLfmPath($directory_path);
Loading history...
154
        }, 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

154
        }, /** @scrutinizer ignore-call */ app(static::class)->dir($parent_dir)->directories());
Loading history...
155
156
        return in_array($this->path('url'), $parent_directories);
157
    }
158
159
    /**
160
     * Check a folder and its subfolders is empty or not.
161
     *
162
     * @param  string  $directory_path  Real path of a directory.
163
     * @return bool
164
     */
165
    public function directoryIsEmpty()
166
    {
167
        return count($this->storage->allFiles()) == 0;
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 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

167
        return count($this->storage->/** @scrutinizer ignore-call */ allFiles()) == 0;
Loading history...
168
    }
169
170
    public function normalizeWorkingDir()
171
    {
172
        $path = $this->working_dir
173
            ?: $this->helper->input('working_dir')
174
            ?: $this->helper->getRootFolder();
175
176
        if ($this->is_thumb) {
177
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
178
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->helper->getThumbFolderName();
179
        }
180
181
        if ($this->getName()) {
182
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
183
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->getName();
184
        }
185
186
        return $path;
187
    }
188
189
    /**
190
     * Sort files and directories.
191
     *
192
     * @param  mixed  $arr_items  Array of files or folders or both.
193
     * @return array of object
194
     */
195
    public function sortByColumn($arr_items)
196
    {
197
        $sort_by = $this->helper->input('sort_type');
198
        if (in_array($sort_by, ['name', 'time'])) {
199
            $key_to_sort = $sort_by;
200
        } else {
201
            $key_to_sort = 'name';
202
        }
203
204
        uasort($arr_items, function ($a, $b) use ($key_to_sort) {
205
            return strcasecmp($a->{$key_to_sort}, $b->{$key_to_sort});
206
        });
207
208
        return $arr_items;
209
    }
210
211
    public function error($error_type, $variables = [])
212
    {
213
        throw new \Exception($this->helper->error($error_type, $variables));
214
    }
215
216
    // Upload section
217
    public function upload($file)
218
    {
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
            $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

224
            $this->setName($new_file_name)->storage->/** @scrutinizer ignore-call */ 
225
                                                     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...
225
226
            $this->generateThumbnail($new_file_name);
227
        } catch (\Exception $e) {
228
            \Log::info($e);
229
            return $this->error('invalid');
230
        }
231
        // TODO should be "FileWasUploaded"
232
        event(new ImageWasUploaded($new_file_path));
233
234
        return $new_file_name;
235
    }
236
237
    public function validateUploadedFile($file)
238
    {
239
        $validator = new LfmUploadValidator($file);
240
241
        $validator->sizeLowerThanIniMaximum();
242
243
        $validator->uploadWasSuccessful();
244
245
        if (!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

245
        if (!/** @scrutinizer ignore-call */ config('lfm.over_write_on_duplicate')) {
Loading history...
246
            $validator->nameIsNotDuplicate($this->getNewName($file), $this);
247
        }
248
249
        $validator->isNotExcutable();
250
251
        if (config('lfm.should_validate_mime', false)) {
252
            $validator->mimeTypeIsValid($this->helper->availableMimeTypes());
253
        }
254
255
        if (config('lfm.should_validate_size', false)) {
256
            $validator->sizeIsLowerThanConfiguredMaximum($this->helper->maxUploadSize());
257
        }
258
259
        return true;
260
    }
261
262
    private function getNewName($file)
263
    {
264
        $new_file_name = $this->helper->translateFromUtf8(
265
            trim($this->helper->utf8Pathinfo($file->getClientOriginalName(), "filename"))
266
        );
267
268
        $extension = $file->getClientOriginalExtension();
269
270
        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

270
        if (/** @scrutinizer ignore-call */ config('lfm.rename_file') === true) {
Loading history...
271
            $new_file_name = uniqid();
272
        } elseif (config('lfm.alphanumeric_filename') === true) {
273
            $new_file_name = preg_replace('/[^A-Za-z0-9\-\']/', '_', $new_file_name);
274
        }
275
276
        if ($extension) {
277
            $new_file_name_with_extention = $new_file_name . '.' . $extension;
278
        }
279
280
        if (config('lfm.rename_duplicates') === true) {
281
            $counter = 1;
282
            $file_name_without_extentions = $new_file_name;
283
            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...
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

283
            while ($this->setName(($extension) ? $new_file_name_with_extention : $new_file_name)->/** @scrutinizer ignore-call */ exists()) {
Loading history...
284
                if (config('lfm.alphanumeric_filename') === true) {
285
                    $suffix = '_'.$counter;
286
                } else {
287
                    $suffix = " ({$counter})";
288
                }
289
                $new_file_name = $file_name_without_extentions.$suffix;
290
291
                if ($extension) {
292
                    $new_file_name_with_extention = $new_file_name . '.' . $extension;
293
                }
294
                $counter++;
295
            }
296
        }
297
298
        return ($extension) ? $new_file_name_with_extention : $new_file_name;
299
    }
300
301
    public function generateThumbnail($file_name)
302
    {
303
        $original_image = $this->pretty($file_name);
304
305
        if (!$original_image->shouldCreateThumb()) {
306
            return;
307
        }
308
309
        // create folder for thumbnails
310
        $this->setName(null)->thumb(true)->createFolder();
311
312
        // generate cropped image content
313
        $this->setName($file_name)->thumb(true);
314
        $thumbWidth = $this->helper->shouldCreateCategoryThumb() && $this->helper->categoryThumbWidth() ? $this->helper->categoryThumbWidth() : config('lfm.thumb_img_width', 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

314
        $thumbWidth = $this->helper->shouldCreateCategoryThumb() && $this->helper->categoryThumbWidth() ? $this->helper->categoryThumbWidth() : /** @scrutinizer ignore-call */ config('lfm.thumb_img_width', 200);
Loading history...
315
        $thumbHeight = $this->helper->shouldCreateCategoryThumb() && $this->helper->categoryThumbHeight() ? $this->helper->categoryThumbHeight() : config('lfm.thumb_img_height', 200);
316
        $image = Image::make($original_image->get())
317
            ->fit($thumbWidth, $thumbHeight);
318
319
        $this->storage->put($image->stream()->detach(), 'public');
0 ignored issues
show
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

319
        $this->storage->/** @scrutinizer ignore-call */ 
320
                        put($image->stream()->detach(), 'public');
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...
320
    }
321
}
322