Passed
Push — master ( 4f3f84...6162ee )
by Stream
10:13 queued 06:39
created

LfmPath   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 324
Duplicated Lines 0 %

Importance

Changes 10
Bugs 3 Features 1
Metric Value
eloc 135
c 10
b 3
f 1
dl 0
loc 324
rs 5.04
wmc 57

25 Methods

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

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
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
        return $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
        if (config('lfm.should_validate_mime', false)) {
254
            $mimetype = $file->getMimeType();
255
            if (false === in_array($mimetype, $this->helper->availableMimeTypes())) {
256
                return $this->error('mime') . $mimetype;
257
            }
258
        }
259
260
        if (config('lfm.should_validate_size', false)) {
261
            // size to kb unit is needed
262
            $file_size = $file->getSize() / 1000;
263
            if ($file_size > $this->helper->maxUploadSize()) {
264
                return $this->error('size') . $file_size;
265
            }
266
        }
267
268
        return 'pass';
269
    }
270
271
    private function getNewName($file)
272
    {
273
        $new_file_name = $this->helper
274
            ->translateFromUtf8(trim(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)));
275
276
        $extension = $file->getClientOriginalExtension();
277
278
        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

278
        if (/** @scrutinizer ignore-call */ config('lfm.rename_file') === true) {
Loading history...
279
            $new_file_name = uniqid();
280
        } elseif (config('lfm.alphanumeric_filename') === true) {
281
            $new_file_name = preg_replace('/[^A-Za-z0-9\-\']/', '_', $new_file_name);
282
        }
283
284
        if ($extension) {
285
            $new_file_name_with_extention = $new_file_name . '.' . $extension;
286
        }
287
288
        if (config('lfm.rename_duplicates') === true) {
289
            $counter = 1;
290
            $file_name_without_extentions = $new_file_name;
291
            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...
292
                if (config('lfm.alphanumeric_filename') === true) {
293
                    $suffix = '_'.$counter;
294
                } else {
295
                    $suffix = " ({$counter})";
296
                }
297
                $new_file_name = $file_name_without_extentions.$suffix;
298
299
                if ($extension) {
300
                    $new_file_name_with_extention = $new_file_name . '.' . $extension;
301
                }
302
                $counter++;
303
            }
304
        }
305
306
        return ($extension) ? $new_file_name_with_extention : $new_file_name;
307
    }
308
309
    private function saveFile($file, $new_file_name)
310
    {
311
        $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

311
        $this->setName($new_file_name)->storage->/** @scrutinizer ignore-call */ 
312
                                                 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...
312
313
        $this->makeThumbnail($new_file_name);
314
315
        return $new_file_name;
316
    }
317
318
    public function makeThumbnail($file_name)
319
    {
320
        $original_image = $this->pretty($file_name);
321
322
        if (!$original_image->shouldCreateThumb()) {
323
            return;
324
        }
325
326
        // create folder for thumbnails
327
        $this->setName(null)->thumb(true)->createFolder();
328
329
        // generate cropped image content
330
        $this->setName($file_name)->thumb(true);
331
        $image = Image::make($original_image->get())
332
            ->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

332
            ->fit(/** @scrutinizer ignore-call */ config('lfm.thumb_img_width', 200), config('lfm.thumb_img_height', 200));
Loading history...
333
334
        $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

334
        $this->storage->/** @scrutinizer ignore-call */ 
335
                        put($image->stream()->detach(), 'public');
Loading history...
335
    }
336
}
337