Issues (9)

src/Medium.php (8 issues)

1
<?php
2
3
namespace Khaleghi\Media;
4
5
use Exception;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Facades\Storage;
8
use Illuminate\Support\Facades\File;
9
use Illuminate\Support\Facades\URL;
10
use Intervention\Image\Facades\Image;
11
use Illuminate\Support\Facades\Response;
12
13
class Medium extends Model
14
{
15
    //use Favorite;
16
    protected $guarded = ['id', 'file'];
17
    public $file_object;
18
19
    public $file_object_attributes = ['stored_name', 'file_name', 'extension', 'size', 'mime', 'width', 'height'];
20
21
    public function mediumable() {
22
        return $this->morphTo();
23
    }
24
25
    public function __construct(array $attributes = [])
26
    {
27
        parent::__construct($attributes);
28
        if (isset($attributes['file'])) {
29
            $this->attach_file($attributes['file']);
30
        }
31
    }
32
33
    protected function set_up_upload_folders() {
34
35
        if (!$this->is('image')) {
36
            $path = storage_path('app/' . $this->main_upload_folder . "/{$this->type}s/");
37
            File::isDirectory($path) or File::makeDirectory($path, 0777, true, true);
38
            return null;
39
        }
40
        $large_image_folder = storage_path('app/' . $this->full_path_lg);
41
        $medium_image_folder = storage_path('app/' . $this->full_path_md);
42
        $small_image_folder = storage_path('app/' . $this->full_path_sm);
43
        $extra_small_image_folder = storage_path('app/' . $this->full_path_xs);
44
45
        File::isDirectory($large_image_folder) or File::makeDirectory($large_image_folder, 0777, true, true);
46
        File::isDirectory($medium_image_folder) or File::makeDirectory($medium_image_folder, 0777, true, true);
47
        File::isDirectory($small_image_folder) or File::makeDirectory($small_image_folder, 0777, true, true);
48
        File::isDirectory($extra_small_image_folder) or File::makeDirectory($extra_small_image_folder, 0777, true, true);
49
    }
50
51
    public function attach_file($file)
52
    {
53
        if ($this->id) { // if the file already stored
54
            return false;
55
        }
56
57
        $this->file_object = $file;
58
        $full_name = $file->getClientOriginalName();
59
60
        $this->stored_name = $this->store_file_name_hashed() ? $file->hashName() : $full_name;
0 ignored issues
show
The property stored_name does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
61
        $this->file_name = pathinfo($full_name, PATHINFO_FILENAME);
0 ignored issues
show
The property file_name does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
62
        $this->extension = strtolower($file->getClientOriginalExtension());
0 ignored issues
show
The property extension does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
63
        $this->size = $file->getSize();
0 ignored issues
show
The property size does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
64
        $this->mime = $file->getMimeType();
0 ignored issues
show
The property mime does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
65
        $dimensions = @is_array(getimagesize($file)) ? getimagesize($file) : [null, null];
66
        $this->width = $dimensions[0];
0 ignored issues
show
The property width does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
67
        $this->height = $dimensions[1];
0 ignored issues
show
The property height does not seem to exist on Khaleghi\Media\Medium. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
68
69
        return true;
70
    }
71
72
    public function detach()
73
    {
74
        // It the file saved into database
75
        if ($this->id) {
76
            return false;
77
        }
78
        foreach($this->file_object_attributes as $attribute){
79
            unset($this->$attribute);
80
        }
81
        unset($this->file_object);
82
        return true;
83
    }
84
85
    public function save(array $options = [])
86
    {
87
        $this->store();
88
        return parent::save($options);
89
    }
90
91
    public function store() {
92
        if (!$this->file_object) {
93
            throw new Exception('No File Attached');
94
        }
95
        // Create upload folder if not exists
96
        $this->set_up_upload_folders();
97
        $stored_name = $this->store_file_name_hashed() ? $this->file_object->hashName() : $this->full_name;
98
99
        if ($this->is('image')) {
100
            if (config('media.LARGE_IMAGE_SIZE')) {
101
                Image::make($this->file_object)
102
                    ->widen(config('media.LARGE_IMAGE_SIZE'))
103
                    ->save(storage_path('app/'.$this->full_path_lg.'/'.$stored_name));
104
            } else {
105
                $this->file_object->storeAs($this->full_path_lg, $stored_name);
106
            }
107
108
            if (config('media.CREATE_RESPONSIVE_SIZES')) {
109
110
                Image::make($this->file_object)
111
                    ->widen(config('media.MEDIUM_IMAGE_SIZE'))
112
                    ->save(storage_path('app/'.$this->full_path_md.'/'.$this->stored_name));
113
114
                Image::make($this->file_object)
115
                    ->widen(config('media.SMALL_IMAGE_SIZE'))
116
                    ->save(storage_path('app/'.$this->full_path_sm.'/'.$this->stored_name));
117
118
                Image::make($this->file_object)
119
                    ->widen(config('media.EXTRA_SMALL_IMAGE_SIZE'))
120
                    ->save(storage_path('app/'.$this->full_path_xs.'/'.$this->stored_name));
121
            }
122
        } elseif ($this->is($this->type)) {
123
            $this->file_object->storeAs(config('media.MAIN_UPLOAD_FOLDER').'/'.$this->type.'s', $stored_name);
124
        }
125
    }
126
127
    public function remove() {
128
        if (!$this->delete()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->delete() of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
129
            return false;
130
        }
131
        if (!$this->is('image')) {
132
            Storage::delete($this->full_path . '/' . $this->stored_name);
133
            return true;
134
        }
135
        Storage::delete($this->full_path_lg . '/' . $this->stored_name);
136
        Storage::delete($this->full_path_md . '/' . $this->stored_name);
137
        Storage::delete($this->full_path_sm . '/' . $this->stored_name);
138
        Storage::delete($this->full_path_xs . '/' . $this->stored_name);
139
        return true;
140
    }
141
142
    public function url($image_size = 'lg') {
143
        if ($this->is('image')) {
144
            return Url::to(Storage::url($this->main_upload_folder."/images/{$image_size}/".$this->stored_name));
145
        } else {
146
            return Url::to(Storage::url($this->main_upload_folder."/{$this->type}s/".$this->stored_name));
147
        }
148
    }
149
150
    public function get_image_info(array $sizes = ['lg','md','sm','xs'])
151
    {
152
        if(!$this->is('image')){return null;}
153
154
        $info = [];
155
        foreach ($sizes as $size){
156
            $info[$size] = [
157
                'src' => url('/').$this->url($size),
158
                'width' => $this->width,
159
                'height' => $this->height
160
            ];
161
        }
162
        return $info;
163
    }
164
165
    /********************** ACCESSORS *********************/
166
167
    public function getFullNameAttribute() {
168
        return $this->file_name.'.'.$this->extension;
169
    }
170
171
    public function getMainUploadFolderAttribute() {
172
        return config('media.MAIN_UPLOAD_FOLDER');
173
    }
174
175
    public function getFullPathLgAttribute() {
176
        return $this->main_upload_folder.'/images/'.config('media.LARGE_IMAGE_FOLDER_PATH');
177
    }
178
179
    public function getFullPathMdAttribute() {
180
        return $this->main_upload_folder.'/images/'.config('media.MEDIUM_IMAGE_FOLDER_PATH');
181
    }
182
183
    public function getFullPathSmAttribute() {
184
        return $this->main_upload_folder.'/images/'.config('media.SMALL_IMAGE_FOLDER_PATH');
185
    }
186
187
    public function getFullPathXsAttribute() {
188
        return $this->main_upload_folder.'/images/'.config('media.EXTRA_SMALL_IMAGE_FOLDER_PATH');
189
    }
190
191
    public function getFullPathAttribute()
192
    {
193
        return $this->main_upload_folder."/{$this->type}s/";
194
    }
195
196
    public function getTypeAttribute() {
197
        return explode('/', $this->mime)[0];
198
    }
199
200
    /********************** DETERMINERS *********************/
201
202
    public function is($type) {
203
        return preg_match("/{$type}\/*/", $this->mime);
204
    }
205
206
    public function store_file_name_hashed() {
207
        return config('media.STORE_FILE_NAME_HASHED');
208
    }
209
210
    public function is_file_attached()
211
    {
212
        return !!$this->file_object;
213
    }
214
215
    /********************** SCOPES *********************/
216
217
    public function scopeByType($query, $type)
218
    {
219
        return $query->where('mime', 'LIKE', $type.'/%');
220
    }
221
222
    public function scopeImages($query)
223
    {
224
        return $query->where('mime', 'LIKE', 'image/%');
225
    }
226
227
    public function scopeVideos($query)
228
    {
229
        return $query->where('mime', 'LIKE', 'video/%');
230
    }
231
232
    public function scopeOf($query, $value) {
233
        return $query->where('mediumable_type', $value);
234
    }
235
236
}
237