Completed
Pull Request — master (#831)
by
unknown
03:34
created

LfmPath::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Xuandung38\LaravelFilemanager;
4
5
use Illuminate\Container\Container;
6
use Intervention\Image\Facades\Image;
7
use Symfony\Component\HttpFoundation\File\UploadedFile;
8
use Xuandung38\LaravelFilemanager\Events\ImageIsUploading;
9
use Xuandung38\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 Xuandung38\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 $this->translateToOsPath($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 Xuandung38\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 translateToOsPath($path)
87
    {
88
        return str_replace(Lfm::DS, $this->helper->ds(), $path);
89
    }
90
91
    public function url()
92
    {
93
        return $this->storage->url($this->path('url'));
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
94
    }
95
96
    public function folders()
97
    {
98
        $all_folders = array_map(function ($directory_path) {
99
            return $this->pretty($directory_path);
100
        }, $this->storage->directories());
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method directories() does not exist on Xuandung38\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

100
        }, $this->storage->/** @scrutinizer ignore-call */ directories());
Loading history...
101
102
        $folders = array_filter($all_folders, function ($directory) {
103
            return $directory->name !== $this->helper->getThumbFolderName();
104
        });
105
106
        return $this->sortByColumn($folders);
107
    }
108
109
    public function files()
110
    {
111
        $files = array_map(function ($file_path) {
112
            return $this->pretty($file_path);
113
        }, $this->storage->files());
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method files() does not exist on Xuandung38\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

113
        }, $this->storage->/** @scrutinizer ignore-call */ files());
Loading history...
114
115
        return $this->sortByColumn($files);
116
    }
117
118
    public function pretty($item_path)
119
    {
120
        return Container::getInstance()->makeWith(LfmItem::class, [
121
            'lfm' => (clone $this)->setName($this->helper->getNameFromPath($item_path)),
122
            'helper' => $this->helper
123
        ]);
124
    }
125
126
    public function delete()
127
    {
128
        if ($this->isDirectory()) {
129
            return $this->storage->deleteDirectory();
0 ignored issues
show
Bug introduced by
The method deleteDirectory() does not exist on Xuandung38\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

129
            return $this->storage->/** @scrutinizer ignore-call */ deleteDirectory();
Loading history...
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
130
        } else {
131
            return $this->storage->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on Xuandung38\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

131
            return $this->storage->/** @scrutinizer ignore-call */ delete();
Loading history...
132
        }
133
    }
134
135
    /**
136
     * Create folder if not exist.
137
     *
138
     * @param  string  $path  Real path of a directory.
139
     * @return bool
140
     */
141
    public function createFolder()
142
    {
143
        if ($this->storage->exists($this)) {
0 ignored issues
show
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method exists() does not exist on Xuandung38\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

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

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

157
        }, /** @scrutinizer ignore-call */ app(static::class)->dir($parent_dir)->directories());
Loading history...
158
159
        return in_array($this->path('url'), $parent_directories);
160
    }
161
162
    /**
163
     * Check a folder and its subfolders is empty or not.
164
     *
165
     * @param  string  $directory_path  Real path of a directory.
166
     * @return bool
167
     */
168
    public function directoryIsEmpty()
169
    {
170
        return count($this->storage->allFiles()) == 0;
0 ignored issues
show
Bug introduced by
The method allFiles() does not exist on Xuandung38\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

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

226
        /** @scrutinizer ignore-call */ 
227
        event(new ImageIsUploading($new_file_path));
Loading history...
227
        try {
228
            $new_file_name = $this->saveFile($file, $new_file_name);
229
        } catch (\Exception $e) {
230
            \Log::info($e);
231
            return $this->error('invalid');
232
        }
233
        // TODO should be "FileWasUploaded"
234
        event(new ImageWasUploaded($new_file_path));
235
236
        return $new_file_name;
237
    }
238
239
    private function uploadValidator($file)
240
    {
241
        if (empty($file)) {
242
            return $this->error('file-empty');
243
        } elseif (! $file instanceof UploadedFile) {
244
            return $this->error('instance');
245
        } elseif ($file->getError() == UPLOAD_ERR_INI_SIZE) {
246
            return $this->error('file-size', ['max' => ini_get('upload_max_filesize')]);
247
        } elseif ($file->getError() != UPLOAD_ERR_OK) {
248
            throw new \Exception('File failed to upload. Error code: ' . $file->getError());
249
        }
250
251
        $new_file_name = $this->getNewName($file);
252
253
        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

253
        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 Xuandung38\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

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

280
        if (/** @scrutinizer ignore-call */ config('lfm.rename_file') === true) {
Loading history...
281
            $new_file_name = uniqid();
282
        } elseif (config('lfm.alphanumeric_filename') === true) {
283
            $new_file_name = preg_replace('/[^A-Za-z0-9\-\']/', '_', $new_file_name);
284
        }
285
286
        $extension = $file->getClientOriginalExtension();
287
288
        if ($extension) {
289
            $new_file_name .= '.' . $extension;
290
        }
291
292
        return $new_file_name;
293
    }
294
295
    private function saveFile($file, $new_file_name)
296
    {
297
        $this->setName($new_file_name)->storage->save($file);
0 ignored issues
show
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

297
        $this->setName($new_file_name)->storage->/** @scrutinizer ignore-call */ 
298
                                                 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...
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
298
299
        $this->makeThumbnail($new_file_name);
300
301
        return $new_file_name;
302
    }
303
304
    public function makeThumbnail($file_name)
305
    {
306
        $original_image = $this->pretty($file_name);
307
308
        if (!$original_image->shouldCreateThumb()) {
309
            return;
310
        }
311
312
        // create folder for thumbnails
313
        $this->setName(null)->thumb(true)->createFolder();
314
315
        // generate cropped image content
316
        $this->setName($file_name)->thumb(true);
317
        $image = Image::make($original_image->get())
318
            ->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

318
            ->fit(/** @scrutinizer ignore-call */ config('lfm.thumb_img_width', 200), config('lfm.thumb_img_height', 200));
Loading history...
319
320
        $this->storage->put($image->stream()->detach());
0 ignored issues
show
Bug introduced by
The method put() does not exist on Xuandung38\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

320
        $this->storage->/** @scrutinizer ignore-call */ 
321
                        put($image->stream()->detach());
Loading history...
Bug Best Practice introduced by
The property storage does not exist on Xuandung38\LaravelFilemanager\LfmPath. Since you implemented __get, consider adding a @property annotation.
Loading history...
321
    }
322
}
323