Test Setup Failed
Push — 0.9 ( fcbced...e11516 )
by Ben
04:32 queued 01:19
created

Asset::getBaseName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Thinktomorrow\AssetLibrary;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
use Illuminate\Support\Facades\DB;
8
use Spatie\MediaLibrary\InteractsWithMedia;
9
use Spatie\MediaLibrary\MediaCollections\Models\Media;
10
use Illuminate\Database\Eloquent\Model;
11
use Spatie\MediaLibrary\HasMedia;
12
13
class Asset extends Model implements HasMedia
14
{
15
    use InteractsWithMedia;
0 ignored issues
show
introduced by
The trait Spatie\MediaLibrary\InteractsWithMedia requires some properties which are not provided by Thinktomorrow\AssetLibrary\Asset: $fallbackPath, $mediaConversionRegistrations, $forceDeleting, $fallbackUrl, $media, $collection_name
Loading history...
16
17
    /**
18
     * The asset model always has one collection type. Different collection types for
19
     * the owning model are set on the asset model instead of the media model.
20
     */
21
    const MEDIA_COLLECTION = 'default';
22
23
    /**
24
     * Proxy for the data values on the associated pivot. This is the context data
25
     * relevant and unique for each owner - asset relation.
26
     */
27
    public function hasData(string $key): bool
28
    {
29
        if(!$this->pivot) return false;
0 ignored issues
show
Bug introduced by
The property pivot does not seem to exist on Thinktomorrow\AssetLibrary\Asset. 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...
30
31
        return $this->pivot->hasData($key);
32
    }
33
34
    /**
35
     * Proxy for the data values on the associated pivot. This is the context data
36
     * relevant and unique for each owner - asset relation.
37
     */
38
    public function getData(string $key, $default = null)
39
    {
40
        if(!$this->pivot) return $default;
0 ignored issues
show
Bug introduced by
The property pivot does not seem to exist on Thinktomorrow\AssetLibrary\Asset. 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...
41
42
        return $this->pivot->getData($key, $default);
43
    }
44
45
    /**
46
     * Return path of the media file. In case the passed conversion
47
     * does not exist, the path to the original is returned.
48
     */
49
    public function getPath($conversionName = ''): ?string
50
    {
51
        return $this->getFirstMediaPath(self::MEDIA_COLLECTION, $conversionName) ?: null;
52
    }
53
54
    /**
55
     * Return url of the media file. In case the passed conversion
56
     * does not exist, the url to the original is returned.
57
     */
58
    public function getUrl(string $conversionName = ''): ?string
59
    {
60
        return $this->getFirstMediaUrl(self::MEDIA_COLLECTION, $conversionName) ?: null;
61
    }
62
63
    /**
64
     * Return filename of the media file. In case the passed conversion
65
     * does not exist, the name to the original is returned.
66
     */
67
    public function getFileName(string $conversionName = ''): ?string
68
    {
69
        if (!$path = $this->getFirstMediaPath(self::MEDIA_COLLECTION, $conversionName)) return null;
70
71
        return basename($path);
72
    }
73
74
    public function getBaseName(string $conversionName = ''): string
75
    {
76
        return basename($this->getFileName($conversionName), '.'.$this->getExtension());
0 ignored issues
show
Bug introduced by
It seems like $this->getFileName($conversionName) can also be of type null; however, parameter $path of basename() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
        return basename(/** @scrutinizer ignore-type */ $this->getFileName($conversionName), '.'.$this->getExtension());
Loading history...
77
    }
78
79
    /**
80
     * Checks if the conversion exists. It checks if file
81
     * exists as media record and on the server
82
     */
83
    public function exists(string $conversionName = ''): bool
84
    {
85
        // In case there is no media model attached to our Asset.
86
        if (!$path = $this->getFirstMediaPath(self::MEDIA_COLLECTION, $conversionName)) {
87
            return false;
88
        }
89
90
        // When we specifically check if a conversion exists, we need to explicitly check if the provided path is that of the conversion.
91
        // This is because Media Library falls back to returning the original path if the converted file does not exist.
92
        if ($conversionName) {
93
            $originalPath = $this->getFirstMediaPath(self::MEDIA_COLLECTION, '');
94
            if ($originalPath == $path) return false;
95
        }
96
97
        return file_exists($path);
98
    }
99
100
    public function getSize(): int
101
    {
102
        return $this->getMediaPropertyValue('size', 0);
103
    }
104
105
    public function getHumanReadableSize(): string
106
    {
107
        return $this->getMediaPropertyValue('human_readable_size', '');
108
    }
109
110
    public function getMimeType(): ?string
111
    {
112
        return $this->getMediaPropertyValue('mime_type');
113
    }
114
115
    public function getExtension(): string
116
    {
117
        return $this->getMediaPropertyValue('extension', '');
118
    }
119
120
    public function getExtensionType(): string
121
    {
122
        return match (strtolower($this->getExtension())) {
123
            'xls', 'xlsx', 'numbers', 'sheets' => 'spreadsheet',
124
            'png', 'jpg', 'jpeg', 'gif', 'svg', 'webp' => 'image',
125
            'pdf' => 'pdf',
126
            'mp4', 'webm', 'mpeg', 'mov' => 'video',
127
            default => 'file'
128
        };
129
    }
130
131
    public function isImage(): bool
132
    {
133
        return $this->getExtensionType() == 'image';
134
    }
135
136
    public function getImageWidth(string $conversionName = ''): ?int
137
    {
138
        return $this->getImageDimensions($conversionName)['width'];
139
    }
140
141
    public function getImageHeight(string $conversionName = ''): ?int
142
    {
143
        return $this->getImageDimensions($conversionName)['height'];
144
    }
145
146
    private function getImageDimensions(string $conversionName = ''): array
147
    {
148
        $result = [
149
            'width' => null,
150
            'height' => null,
151
        ];
152
153
        if(!$this->isImage() || !$this->exists($conversionName)) {
154
            return $result;
155
        }
156
157
        if($dimensions = getimagesize($this->getPath($conversionName))) {
158
            $result['width'] = $dimensions[0];
159
            $result['height'] = $dimensions[1];
160
        }
161
162
        return $result;
163
    }
164
165
    private function getMediaPropertyValue(string $property, $default = null)
166
    {
167
        if (!$mediaModel = $this->getFirstMedia(self::MEDIA_COLLECTION)) {
168
            return $default;
169
        }
170
171
        return $mediaModel->{$property};
172
    }
173
174
    /**
175
     * @deprecated Use getFileName instead
176
     */
177
    public function filename($size = ''): string
178
    {
179
        return $this->getFileName($size);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getFileName($size) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
180
    }
181
182
    /**
183
     * @deprecated use getUrl() instead
184
     */
185
    public function url($size = ''): string
186
    {
187
        return $this->getUrl($size);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getUrl($size) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
188
    }
189
190
    /**
191
     * @deprecated use exists() instead
192
     */
193
    public function hasFile(): bool
194
    {
195
        return $this->exists();
196
    }
197
198
    /**
199
     * Register the conversions that should be performed.
200
     *
201
     * @param Media|null $media
202
     * @throws \Spatie\Image\Exceptions\InvalidManipulation
203
     */
204
    public function registerMediaConversions(Media $media = null): void
205
    {
206
        $conversions = config('thinktomorrow.assetlibrary.conversions');
207
208
        foreach ($conversions as $key => $value) {
209
            $this->addMediaConversion($key)
210
                ->width($value['width'])
211
                ->height($value['height'])
212
                ->keepOriginalImageFormat();
213
//                ->optimize();
214
        }
215
216
        if (config('thinktomorrow.assetlibrary.allowCropping')) {
217
            $this->addMediaConversion('cropped')
218
                ->keepOriginalImageFormat();
219
//                ->optimize();
220
        }
221
    }
222
}
223