Passed
Branch 0.5 (404206)
by Philippe
05:17
created

Asset::removeFile()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 10
cts 10
cp 1
rs 9.3888
c 0
b 0
f 0
cc 5
nc 4
nop 1
crap 5
1
<?php
2
3
namespace Thinktomorrow\AssetLibrary\Models;
4
5
use Thinktomorrow\Locale\Locale;
6
use Illuminate\Support\Collection;
7
use Spatie\MediaLibrary\Models\Media;
8
use Illuminate\Database\Eloquent\Model;
9
use Spatie\MediaLibrary\HasMedia\HasMedia;
10
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
11
use Thinktomorrow\AssetLibrary\Exceptions\ConfigException;
12
use Thinktomorrow\AssetLibrary\Exceptions\AssetUploadException;
13
use Thinktomorrow\AssetLibrary\Exceptions\CorruptMediaException;
14
15
/**
16
 * @property mixed media
17
 */
18
class Asset extends Model implements HasMedia
19
{
20
    use HasMediaTrait;
21
22
    private $order;
23
24
    /**
25
     * Attaches this asset instance to the given model and
26
     * sets the type and locale to the given values and
27
     * returns the model with the asset relationship.
28
     *
29
     * @param Model $model
30
     * @param string $type
31
     * @param null|string $locale
32
     * @return Model
33
     * @throws \Thinktomorrow\AssetLibrary\Exceptions\AssetUploadException
34
     */
35 37
    public function attachToModel(Model $model, $type = '', $locale = null): Model
36
    {
37 37
        if ($model->assets()->get()->contains($this)) {
38 1
            throw AssetUploadException::create();
39
        }
40
41 37
        $model->assets->where('pivot.type', $type)->where('pivot.locale', $locale);
42
43 37
        $locale = $locale ?? config('app.locale');
44
45 37
        $model->assets()->attach($this, ['type' => $type, 'locale' => $locale, 'order' => $this->order]);
46
47 37
        return $model->load('assets');
48
    }
49
50
    /**
51
     * @return bool
52
     */
53 1
    public function hasFile(): bool
54
    {
55 1
        return (bool) $this->getFileUrl();
56
    }
57
58
    /**
59
     * @param string $size
60
     * @return string
61
     */
62 14
    public function getFilename($size = ''): string
63
    {
64 14
        return basename($this->getFileUrl($size));
65
    }
66
67
    /**
68
     * @param string $size
69
     * @return string
70
     */
71 45
    public function getFileUrl($size = ''): string
72
    {
73 45
        $media = $this->getMedia()->first();
74
75 45
        if ($media == null) {
76 1
            throw CorruptMediaException::corrupt($this->id);
77
        }
78
79 44
        return $media->getUrl($size);
80
    }
81
82
    /**
83
     * Returns the image url or a fallback specific per filetype.
84
     *
85
     * @param string $type
86
     * @return string
87
     */
88 9
    public function getImageUrl($type = ''): string
89
    {
90 9
        if ($this->getMedia()->isEmpty()) {
91 1
            return asset('assets/back/img/other.png');
92
        }
93 8
        $extension = $this->getExtensionType();
94 8
        if ($extension === 'image') {
95 7
            return $this->getFileUrl($type);
96 1
        } elseif ($extension) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extension of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
97 1
            return asset('assets/back/img/'.$extension.'.png');
98
        }
99
100 1
        return asset('assets/back/img/other.png');
101
    }
102
103
    /**
104
     * @return bool|string
105
     */
106 2
    public function getExtensionForFilter()
107
    {
108 2
        if ($extension = $this->getExtensionType()) {
109 2
            return $extension;
110
        }
111
112 1
        return '';
113
    }
114
115
    /**
116
     * @return string|null
117
     */
118 10
    public function getExtensionType(): ?string
119
    {
120 10
        $extension = explode('.', $this->getMedia()[0]->file_name);
121 10
        $extension = end($extension);
122
123 10
        if (in_array(strtolower($extension), ['xls', 'xlsx', 'numbers', 'sheets'])) {
124 1
            return 'xls';
125
        }
126 10
        if (in_array(strtolower($extension), ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'])) {
127 9
            return 'image';
128
        }
129 3
        if (strtolower($extension) === 'pdf') {
130 2
            return 'pdf';
131
        }
132
133 2
        return null;
134
    }
135
136
    /**
137
     * @return string
138
     */
139 2
    public function getMimeType(): string
140
    {
141 2
        return $this->isMediaEmpty() ? '' : $this->getMedia()[0]->mime_type;
142
    }
143
144
    /**
145
     * @return bool
146
     */
147 5
    public function isMediaEmpty(): bool
148
    {
149 5
        return $this->getMedia()->isEmpty();
150
    }
151
152
    /**
153
     * @return string
154
     */
155 2
    public function getSize(): string
156
    {
157 2
        return $this->isMediaEmpty() ? '' : $this->getMedia()[0]->human_readable_size;
158
    }
159
160
    /**
161
     * @param null $size
162
     * @return string
163
     */
164 3
    public function getDimensions($size = null): string
165
    {
166 3
        if ($this->isMediaEmpty()) {
167 1
            return '';
168
        }
169
170
        //TODO Check the other sizes as well
171 2
        if ($size === 'cropped') {
172 1
            $dimensions = explode(',', $this->getMedia()[0]->manipulations['cropped']['manualCrop']);
173
174 1
            return $dimensions[0].' x'.$dimensions[1];
175
        }
176
177 1
        return $this->getMedia()[0]->getCustomProperty('dimensions');
178
    }
179
180
    /**
181
     * Removes one or more assets by their ids.
182
     * @param $imageIds
183
     */
184 5
    public static function remove($imageIds)
185
    {
186 5
        if (is_array($imageIds)) {
187 2
            foreach ($imageIds as $id) {
188 2
                self::removeFile($id);
189
            }
190
        } else {
191 4
            self::removeFile($imageIds);
192
        }
193 5
    }
194
195 5
    private static function removeFile($id)
196
    {
197 5
        if (! $id) {
198 1
            return;
199
        }
200
201 4
        $asset = self::find($id)->first();
202
203 4
        $media = $asset->media;
204
205 4
        foreach ($media as $file) {
206 4
            if (! is_file(public_path($file->getUrl())) || ! is_writable(public_path($file->getUrl()))) {
207 4
                return false;
208
            }
209
        }
210 4
        $asset->delete();
211 4
    }
212
213
    /**
214
     * Returns a collection of all the assets in the library.
215
     * @return \Illuminate\Support\Collection
216
     */
217 6
    public static function getAllAssets(): Collection
218
    {
219 6
        return self::all()->sortByDesc('created_at');
220
    }
221
222
    /**
223
     * @param $width
224
     * @param $height
225
     * @param $x
226
     * @param $y
227
     * @return $this
228
     * @throws ConfigException
229
     */
230 2
    public function crop($width, $height, $x, $y)
231
    {
232 2
        if (! config('assetlibrary.allowCropping')) {
233 1
            throw ConfigException::create();
234
        }
235 1
        $this->media[0]->manipulations = [
236
            'cropped'   => [
237 1
                'manualCrop' => $width.', '.$height.', '.$x.', '.$y,
238
            ],
239
        ];
240
241 1
        $this->media[0]->save();
242
243 1
        return $this;
244
    }
245
246
    /**
247
     * Register the conversions that should be performed.
248
     *
249
     * @param Media|null $media
250
     * @throws \Spatie\Image\Exceptions\InvalidManipulation
251
     */
252 60
    public function registerMediaConversions(Media $media = null): void
253
    {
254 60
        $conversions        = config('assetlibrary.conversions');
255
256 60
        foreach ($conversions as $key => $value) {
257 60
            $this->addMediaConversion($key)
258 60
                ->width($value['width'])
259 60
                ->height($value['height'])
260 60
                ->sharpen(15)
261 60
                ->keepOriginalImageFormat()
262 60
                ->optimize();
263
        }
264
265 60
        if (config('assetlibrary.allowCropping')) {
266 1
            $this->addMediaConversion('cropped')
267 1
                ->sharpen(15)
268 1
                ->keepOriginalImageFormat()
269 1
                ->optimize();
270
        }
271 60
    }
272
273 4
    public function setOrder($order)
274
    {
275 4
        $this->order = $order;
276
277 4
        return $this;
278
    }
279
}
280