Passed
Push — master ( cb0d0b...539a19 )
by Stream
05:33
created

src/LfmPath.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace UniSharp\LaravelFilemanager;
4
5
use Illuminate\Container\Container;
6
use Intervention\Image\Facades\Image as InterventionImageV2;
7
use Intervention\Image\Laravel\Facades\Image as InterventionImageV3;
0 ignored issues
show
The type Intervention\Image\Laravel\Facades\Image was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Symfony\Component\HttpFoundation\File\UploadedFile;
9
use UniSharp\LaravelFilemanager\Events\FileIsUploading;
10
use UniSharp\LaravelFilemanager\Events\FileWasUploaded;
11
use UniSharp\LaravelFilemanager\Events\ImageIsUploading;
12
use UniSharp\LaravelFilemanager\Events\ImageWasUploaded;
13
use UniSharp\LaravelFilemanager\LfmUploadValidator;
14
15
class LfmPath
16
{
17
    private $working_dir;
18
    private $item_name;
19
    private $is_thumb = false;
20
21
    private $helper;
22
23
    public function __construct(Lfm $lfm = null)
24
    {
25
        $this->helper = $lfm;
26
    }
27
28
    public function __get($var_name)
29
    {
30
        if ($var_name == 'storage') {
31
            return $this->helper->getStorage($this->path('url'));
32
        }
33
    }
34
35
    public function __call($function_name, $arguments)
36
    {
37
        return $this->storage->$function_name(...$arguments);
38
    }
39
40
    public function dir($working_dir)
41
    {
42
        $this->working_dir = $working_dir;
43
44
        return $this;
45
    }
46
47
    public function thumb($is_thumb = true)
48
    {
49
        $this->is_thumb = $is_thumb;
50
51
        return $this;
52
    }
53
54
    public function setName($item_name)
55
    {
56
        $this->item_name = $item_name;
57
58
        return $this;
59
    }
60
61
    public function getName()
62
    {
63
        return $this->item_name;
64
    }
65
66
    public function path($type = 'storage')
67
    {
68
        if ($type == 'working_dir') {
69
            // working directory: /{user_slug}
70
            return $this->translateToLfmPath($this->normalizeWorkingDir());
71
        } elseif ($type == 'url') {
72
            // storage: files/{user_slug}
73
            // storage without folder: {user_slug}
74
            return $this->helper->getCategoryName() === '.'
75
                ? ltrim($this->path('working_dir'), '/')
76
                : $this->helper->getCategoryName() . $this->path('working_dir');
77
        } elseif ($type == 'storage') {
78
            // storage: files/{user_slug}
79
            // storage on windows: files\{user_slug}
80
            return str_replace(Lfm::DS, $this->helper->ds(), $this->path('url'));
81
        } else {
82
            // absolute: /var/www/html/project/storage/app/files/{user_slug}
83
            // absolute on windows: C:\project\storage\app\files\{user_slug}
84
            return $this->storage->rootPath() . $this->path('storage');
85
        }
86
    }
87
88
    public function translateToLfmPath($path)
89
    {
90
        return str_replace($this->helper->ds(), Lfm::DS, $path);
91
    }
92
93
    public function url()
94
    {
95
        return $this->storage->url($this->path('url'));
96
    }
97
98
    public function folders()
99
    {
100
        $all_folders = array_map(function ($directory_path) {
101
            return $this->pretty($directory_path, true);
102
        }, $this->storage->directories());
103
104
        $folders = array_filter($all_folders, function ($directory) {
105
            return $directory->name !== $this->helper->getThumbFolderName();
106
        });
107
108
        return $this->sortByColumn($folders);
109
    }
110
111
    public function files()
112
    {
113
        $files = array_map(function ($file_path) {
114
            return $this->pretty($file_path);
115
        }, $this->storage->files());
116
117
        return $this->sortByColumn($files);
118
    }
119
120
    public function pretty($item_path, $isDirectory = false)
121
    {
122
        return Container::getInstance()->makeWith(LfmItem::class, [
123
            'lfm' => (clone $this)->setName($this->helper->getNameFromPath($item_path)),
124
            'helper' => $this->helper,
125
            'isDirectory' => $isDirectory
126
        ]);
127
    }
128
129
    public function delete()
130
    {
131
        if ($this->isDirectory()) {
132
            return $this->storage->deleteDirectory();
133
        } else {
134
            return $this->storage->delete();
135
        }
136
    }
137
138
    /**
139
     * Create folder if not exist.
140
     *
141
     * @param  string  $path  Real path of a directory.
142
     * @return bool
143
     */
144
    public function createFolder()
145
    {
146
        if ($this->storage->exists($this)) {
147
            return false;
148
        }
149
150
        $this->storage->makeDirectory(0777, true, true);
151
    }
152
153
    public function isDirectory()
154
    {
155
        $working_dir = $this->path('working_dir');
156
        $parent_dir = substr($working_dir, 0, strrpos($working_dir, '/'));
157
158
        $parent_directories = array_map(function ($directory_path) {
159
            return app(static::class)->translateToLfmPath($directory_path);
160
        }, app(static::class)->dir($parent_dir)->directories());
161
162
        return in_array($this->path('url'), $parent_directories);
163
    }
164
165
    /**
166
     * Check a folder and its subfolders is empty or not.
167
     *
168
     * @param  string  $directory_path  Real path of a directory.
169
     * @return bool
170
     */
171
    public function directoryIsEmpty()
172
    {
173
        return count($this->storage->allFiles()) == 0;
174
    }
175
176
    public function normalizeWorkingDir()
177
    {
178
        $path = $this->working_dir
179
            ?: $this->helper->input('working_dir')
180
            ?: $this->helper->getRootFolder();
181
182
        if ($this->is_thumb) {
183
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
184
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->helper->getThumbFolderName();
185
        }
186
187
        if ($this->getName()) {
188
            // Prevent if working dir is "/" normalizeWorkingDir will add double "//" that breaks S3 functionality
189
            $path = rtrim($path, Lfm::DS) . Lfm::DS . $this->getName();
190
        }
191
192
        return $path;
193
    }
194
195
    /**
196
     * Sort files and directories.
197
     *
198
     * @param  mixed  $arr_items  Array of files or folders or both.
199
     * @return array of object
200
     */
201
    public function sortByColumn($arr_items)
202
    {
203
        $sort_by = $this->helper->input('sort_type');
204
        if (in_array($sort_by, ['name', 'time'])) {
205
            $key_to_sort = $sort_by;
206
        } else {
207
            $key_to_sort = 'name';
208
        }
209
210
        uasort($arr_items, function ($a, $b) use ($key_to_sort) {
211
            return strcasecmp($a->{$key_to_sort}, $b->{$key_to_sort});
212
        });
213
214
        return $arr_items;
215
    }
216
217
    public function error($error_type, $variables = [])
218
    {
219
        throw new \Exception($this->helper->error($error_type, $variables));
220
    }
221
222
    // Upload section
223
    public function upload($file)
224
    {
225
        $new_file_name = $this->getNewName($file);
226
        $new_file_path = $this->setName($new_file_name)->path('absolute');
227
228
        event(new FileIsUploading($new_file_path));
229
        event(new ImageIsUploading($new_file_path));
230
        try {
231
            $this->setName($new_file_name)->storage->save($file);
232
233
            $this->generateThumbnail($new_file_name);
234
        } catch (\Exception $e) {
235
            \Log::info($e);
236
            return $this->error('invalid');
237
        }
238
        event(new FileWasUploaded($new_file_path));
239
        event(new ImageWasUploaded($new_file_path));
240
241
        return $new_file_name;
242
    }
243
244
    public function validateUploadedFile($file)
245
    {
246
        $validator = new LfmUploadValidator($file);
247
248
        $validator->sizeLowerThanIniMaximum();
249
250
        $validator->uploadWasSuccessful();
251
252
        if (!config('lfm.over_write_on_duplicate')) {
253
            $validator->nameIsNotDuplicate($this->getNewName($file), $this);
254
        }
255
256
        $validator->mimetypeIsNotExcutable(config('lfm.disallowed_mimetypes', ['text/x-php', 'text/html', 'text/plain']));
257
258
        $validator->extensionIsNotExcutable(config('lfm.disallowed_extensions', ['php', 'html']));
259
260
        if (config('lfm.should_validate_mime', false)) {
261
            $validator->mimeTypeIsValid($this->helper->availableMimeTypes());
262
        }
263
264
        if (config('lfm.should_validate_size', false)) {
265
            $validator->sizeIsLowerThanConfiguredMaximum($this->helper->maxUploadSize());
266
        }
267
268
        return true;
269
    }
270
271
    private function getNewName($file)
272
    {
273
        $new_file_name = $this->helper->translateFromUtf8(
274
            trim($this->helper->utf8Pathinfo($file->getClientOriginalName(), "filename"))
275
        );
276
277
        $extension = $file->getClientOriginalExtension();
278
279
        if (config('lfm.rename_file') === true) {
280
            $new_file_name = uniqid();
281
        } elseif (config('lfm.alphanumeric_filename') === true) {
282
            $new_file_name = preg_replace('/[^A-Za-z0-9\-\']/', '_', $new_file_name);
283
        }
284
285
        if ($extension) {
286
            $new_file_name_with_extention = $new_file_name . '.' . $extension;
287
        }
288
289
        if (config('lfm.rename_duplicates') === true) {
290
            $counter = 1;
291
            $file_name_without_extentions = $new_file_name;
292
            while ($this->setName(($extension) ? $new_file_name_with_extention : $new_file_name)->exists()) {
293
                if (config('lfm.alphanumeric_filename') === true) {
294
                    $suffix = '_'.$counter;
295
                } else {
296
                    $suffix = " ({$counter})";
297
                }
298
                $new_file_name = $file_name_without_extentions.$suffix;
299
300
                if ($extension) {
301
                    $new_file_name_with_extention = $new_file_name . '.' . $extension;
302
                }
303
                $counter++;
304
            }
305
        }
306
307
        return ($extension) ? $new_file_name_with_extention : $new_file_name;
308
    }
309
310
    public function generateThumbnail($file_name)
311
    {
312
        $original_image = $this->pretty($file_name);
313
314
        if (!$original_image->shouldCreateThumb()) {
315
            return;
316
        }
317
318
        // create folder for thumbnails
319
        $this->setName(null)->thumb(true)->createFolder();
320
321
        // generate cropped image content
322
        $this->setName($file_name)->thumb(true);
323
        $thumbWidth = $this->helper->shouldCreateCategoryThumb() && $this->helper->categoryThumbWidth() ? $this->helper->categoryThumbWidth() : config('lfm.thumb_img_width', 200);
324
        $thumbHeight = $this->helper->shouldCreateCategoryThumb() && $this->helper->categoryThumbHeight() ? $this->helper->categoryThumbHeight() : config('lfm.thumb_img_height', 200);
325
326
        if (class_exists(InterventionImageV2::class)) {
327
            $encoded_image = InterventionImageV2::make($original_image->get())
328
                ->fit($thumbWidth, $thumbHeight)
329
                ->stream()
330
                ->detach();
331
        } else {
332
            $encoded_image = InterventionImageV3::read($original_image->get())
333
                ->cover($thumbWidth, $thumbHeight)
334
                ->encodeByMediaType();
335
        }
336
337
338
        $this->storage->put($encoded_image, 'public');
339
    }
340
}
341