Passed
Push — master ( ca7d80...7a0d15 )
by Philippe
03:38
created

Asset   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 44
c 4
b 1
f 1
lcom 3
cbo 4
dl 0
loc 283
ccs 104
cts 104
cp 1
rs 8.3396

16 Methods

Rating   Name   Duplication   Size   Complexity  
A attachToModel() 0 14 2
A hasFile() 0 4 1
A getFilename() 0 4 1
A getFileUrl() 0 12 3
A getImageUrl() 0 14 4
A getExtensionForFilter() 0 8 2
A getExtensionType() 0 17 4
A getMimeType() 0 4 2
A isMediaEmpty() 0 4 1
A getSize() 0 4 2
A getDimensions() 0 15 3
C remove() 0 40 11
A getAllAssets() 0 4 1
A crop() 0 15 2
B registerMediaConversions() 0 27 4
A setOrder() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like Asset 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Asset, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Thinktomorrow\AssetLibrary\Models;
4
5
use Spatie\MediaLibrary\Media;
6
use Thinktomorrow\Locale\Locale;
7
use Illuminate\Support\Collection;
8
use Illuminate\Database\Eloquent\Model;
9
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
10
use Thinktomorrow\AssetLibrary\Exceptions\ConfigException;
11
use Thinktomorrow\AssetLibrary\Exceptions\AssetUploadException;
12
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMediaConversions;
13
14
/**
15
 * @property mixed media
16
 */
17
class Asset extends Model implements HasMediaConversions
18
{
19
    use HasMediaTrait;
20
21
    private $order;
22
23
    /**
24
     * Attaches this asset instance to the given model and
25
     * sets the type and locale to the given values and
26
     * returns the model with the asset relationship.
27
     *
28
     * @param Model $model
29
     * @param string $type
30
     * @param null|string $locale
31
     * @return Model
32
     * @throws \Thinktomorrow\AssetLibrary\Exceptions\AssetUploadException
33
     */
34 35
    public function attachToModel(Model $model, $type = '', $locale = null): Model
35
    {
36 35
        if ($model->assets()->get()->contains($this)) {
37 1
            throw AssetUploadException::create();
38
        }
39
40 35
        $model->assets->where('pivot.type', $type)->where('pivot.locale', $locale);
41
42 35
        $locale = $locale ?? Locale::getDefault();
43
44 35
        $model->assets()->attach($this, ['type' => $type, 'locale' => $locale, 'order' => $this->order]);
45
46 35
        return $model->load('assets');
47
    }
48
49
    /**
50
     * @return bool
51
     */
52 1
    public function hasFile(): bool
53
    {
54 1
        return (bool) $this->getFileUrl();
55
    }
56
57
    /**
58
     * @param string $size
59
     * @return string
60
     */
61 13
    public function getFilename($size = ''): string
62
    {
63 13
        return basename($this->getFileUrl($size));
64
    }
65
66
    /**
67
     * @param string $size
68
     * @return string
69
     */
70 44
    public function getFileUrl($size = ''): string
71
    {
72 44
        $media = $this->getMedia()->first();
73
74 44
        if (config('assetlibrary.conversionPrefix') && $size != '') {
75 1
            $conversionName = $media->name.'_'.$size;
76
        } else {
77 43
            $conversionName = $size;
78
        }
79
80 44
        return $media->getUrl($conversionName);
81
    }
82
83
    /**
84
     * Returns the image url or a fallback specific per filetype.
85
     *
86
     * @param string $type
87
     * @return string
88
     */
89 9
    public function getImageUrl($type = ''): string
90
    {
91 9
        if ($this->getMedia()->isEmpty()) {
92 1
            return asset('assets/back/img/other.png');
93
        }
94 8
        $extension = $this->getExtensionType();
95 8
        if ($extension === 'image') {
96 7
            return $this->getFileUrl($type);
97 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...
98 1
            return asset('assets/back/img/'.$extension.'.png');
99
        }
100
101 1
        return asset('assets/back/img/other.png');
102
    }
103
104
    /**
105
     * @return bool|string
106
     */
107 2
    public function getExtensionForFilter()
108
    {
109 2
        if ($extension = $this->getExtensionType()) {
110 2
            return $extension;
111
        }
112
113 1
        return '';
114
    }
115
116
    /**
117
     * @return string|null
118
     */
119 10
    public function getExtensionType(): ?string
120
    {
121 10
        $extension = explode('.', $this->getMedia()[0]->file_name);
122 10
        $extension = end($extension);
123
124 10
        if (in_array(strtolower($extension), ['xls', 'xlsx', 'numbers', 'sheets'])) {
125 1
            return 'xls';
126
        }
127 10
        if (in_array(strtolower($extension), ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'])) {
128 9
            return 'image';
129
        }
130 3
        if (strtolower($extension) === 'pdf') {
131 2
            return 'pdf';
132
        }
133
134 2
        return null;
135
    }
136
137
    /**
138
     * @return string
139
     */
140 2
    public function getMimeType(): string
141
    {
142 2
        return $this->isMediaEmpty() ? '' : $this->getMedia()[0]->mime_type;
143
    }
144
145
    /**
146
     * @return bool
147
     */
148 5
    public function isMediaEmpty(): bool
149
    {
150 5
        return $this->getMedia()->isEmpty();
151
    }
152
153
    /**
154
     * @return string
155
     */
156 2
    public function getSize(): string
157
    {
158 2
        return $this->isMediaEmpty() ? '' : $this->getMedia()[0]->human_readable_size;
159
    }
160
161
    /**
162
     * @param null $size
163
     * @return string
164
     */
165 3
    public function getDimensions($size = null): string
166
    {
167 3
        if ($this->isMediaEmpty()) {
168 1
            return '';
169
        }
170
171
        //TODO Check the other sizes as well
172 2
        if ($size === 'cropped') {
173 1
            $dimensions = explode(',', $this->getMedia()[0]->manipulations['cropped']['manualCrop']);
174
175 1
            return $dimensions[0].' x'.$dimensions[1];
176
        }
177
178 1
        return $this->getMedia()[0]->getCustomProperty('dimensions');
179
    }
180
181
    /**
182
     * Removes one or more assets by their ids.
183
     * @param $imageIds
184
     */
185 6
    public static function remove($imageIds)
186
    {
187 6
        if (is_array($imageIds)) {
188 2
            foreach ($imageIds as $id) {
189 2
                if (! $id) {
190 1
                    continue;
191
                }
192
193 1
                $asset = self::where('id', $id)->first();
194 1
                $media = $asset->media;
195
196 1
                foreach($media as $file){
197 1
                    if(is_file(public_path($file->getUrl())) && is_writable(public_path($file->getUrl()))){
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
198
199
                    }else{
200 1
                        return;
201
                    }
202
                }
203
204 2
                $asset->delete();
205
            }
206
        } else {
207 5
            if (! $imageIds) {
208 1
                return;
209
            }
210
211 4
            $asset = self::find($imageIds)->first();
212 4
            $media = $asset->media;
213
214 4
            foreach($media as $file){
215 4
                if(is_file(public_path($file->getUrl())) && is_writable(public_path($file->getUrl()))){
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
216
217
                }else{
218 4
                    return;
219
                }
220
            }
221
222 4
            self::find($imageIds)->first()->delete();
223
        }
224 6
    }
225
226
    /**
227
     * Returns a collection of all the assets in the library.
228
     * @return \Illuminate\Support\Collection
229
     */
230 6
    public static function getAllAssets(): Collection
231
    {
232 6
        return self::all()->sortByDesc('created_at');
233
    }
234
235
    /**
236
     * @param $width
237
     * @param $height
238
     * @param $x
239
     * @param $y
240
     * @return $this
241
     * @throws ConfigException
242
     */
243 2
    public function crop($width, $height, $x, $y)
244
    {
245 2
        if (! config('assetlibrary.allowCropping')) {
246 1
            throw ConfigException::create();
247
        }
248 1
        $this->media[0]->manipulations = [
249
            'cropped'   => [
250 1
                'manualCrop' => $width.', '.$height.', '.$x.', '.$y,
251
            ],
252
        ];
253
254 1
        $this->media[0]->save();
255
256 1
        return $this;
257
    }
258
259
    /**
260
     * Register the conversions that should be performed.
261
     *
262
     * @param Media|null $media
263
     * @throws \Spatie\Image\Exceptions\InvalidManipulation
264
     */
265 58
    public function registerMediaConversions(Media $media = null): void
266
    {
267 58
        $conversions        = config('assetlibrary.conversions');
268 58
        $conversionPrefix   = config('assetlibrary.conversionPrefix');
269
270 58
        foreach ($conversions as $key => $value) {
271 58
            if ($conversionPrefix) {
272 1
                $conversionName = $media->name.'_'.$key;
273
            } else {
274 58
                $conversionName = $key;
275
            }
276
277 58
            $this->addMediaConversion($conversionName)
278 58
                ->width($value['width'])
279 58
                ->height($value['height'])
280 58
                ->sharpen(15)
281 58
                ->keepOriginalImageFormat()
282 58
                ->optimize();
283
        }
284
285 58
        if (config('assetlibrary.allowCropping')) {
286 1
            $this->addMediaConversion('cropped')
287 1
                ->sharpen(15)
288 1
                ->keepOriginalImageFormat()
289 1
                ->optimize();
290
        }
291 58
    }
292
293 4
    public function setOrder($order)
294
    {
295 4
        $this->order = $order;
296
297 4
        return $this;
298
    }
299
}
300