Test Setup Failed
Push — master ( 7f1ec0...39e837 )
by Phan
04:24
created

Artist::generateRandomImagePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace App\Models;
4
5
use App\Facades\Lastfm;
6
use App\Facades\Util;
7
use App\Traits\SupportsDeleteWhereIDsNotIn;
8
use Exception;
9
use Illuminate\Database\Eloquent\Collection;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Eloquent\Relations\HasMany;
12
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
13
use Log;
14
15
/**
16
 * @property int    id      The model ID
17
 * @property string name    The artist name
18
 * @property string image
19
 * @property bool   is_unknown
20
 * @property bool   is_various
21
 * @property Collection songs
22
 */
23
class Artist extends Model
24
{
25
    use SupportsDeleteWhereIDsNotIn;
26
27
    const UNKNOWN_ID = 1;
28
    const UNKNOWN_NAME = 'Unknown Artist';
29
    const VARIOUS_ID = 2;
30
    const VARIOUS_NAME = 'Various Artists';
31
32
    protected $guarded = ['id'];
33
34
    protected $hidden = ['created_at', 'updated_at'];
35
36
    /**
37
     * An artist can have many albums.
38
     *
39
     * @return HasMany
40
     */
41
    public function albums()
42
    {
43
        return $this->hasMany(Album::class);
44
    }
45
46
    /**
47
     * An artist can have many songs.
48
     * Unless he is Rick Astley.
49
     *
50
     * @return HasManyThrough
51
     */
52
    public function songs()
53
    {
54
        return $this->hasManyThrough(Song::class, Album::class);
55
    }
56
57
    /**
58
     * Indicate if the artist is unknown.
59
     *
60
     * @return bool
61
     */
62
    public function getIsUnknownAttribute()
63
    {
64
        return $this->id === self::UNKNOWN_ID;
65
    }
66
67
    /**
68
     * Indicate if the artist is the special "Various Artists"
69
     *
70
     * @return bool
71
     */
72
    public function getIsVariousAttribute()
73
    {
74
        return $this->id === self::VARIOUS_ID;
75
    }
76
77
    /**
78
     * Get the "Various Artists" object.
79
     *
80
     * @return Artist
81
     */
82
    public static function getVariousArtist()
83
    {
84
        return self::find(self::VARIOUS_ID);
85
    }
86
87
    /**
88
     * Sometimes the tags extracted from getID3 are HTML entity encoded.
89
     * This makes sure they are always sane.
90
     *
91
     * @param $value
92
     *
93
     * @return string
94
     */
95
    public function getNameAttribute($value)
96
    {
97
        return html_entity_decode($value ?: self::UNKNOWN_NAME);
98
    }
99
100
    /**
101
     * Get an Artist object from their name.
102
     * If such is not found, a new artist will be created.
103
     *
104
     * @param string $name
105
     *
106
     * @return Artist
107
     */
108
    public static function get($name)
109
    {
110
        // Remove the BOM from UTF-8/16/32, as it will mess up the database constraints.
111
        if ($encoding = Util::detectUTFEncoding($name)) {
112
            $name = mb_convert_encoding($name, 'UTF-8', $encoding);
113
        }
114
115
        $name = trim($name) ?: self::UNKNOWN_NAME;
116
117
        return self::firstOrCreate(compact('name'), compact('name'));
118
    }
119
120
    /**
121
     * Get extra information about the artist from Last.fm.
122
     *
123
     * @return array|false
124
     */
125 View Code Duplication
    public function getInfo()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        if ($this->is_unknown) {
128
            return false;
129
        }
130
131
        $info = Lastfm::getArtistInfo($this->name);
132
        $image = array_get($info, 'image');
133
134
        // If our current artist has no image, and Last.fm has one, copy the image for our local use.
135
        if (!$this->image && is_string($image) && ini_get('allow_url_fopen')) {
136
            try {
137
                $extension = explode('.', $image);
138
                $this->writeImageFile(file_get_contents($image), last($extension));
139
                $info['image'] = $this->image;
140
            } catch (Exception $e) {
141
                Log::error($e);
142
            }
143
        }
144
145
        return $info;
146
    }
147
148
    /**
149
     * Write an artist image file with binary data and update the Artist with the new cover file.
150
     *
151
     * @param string $binaryData
152
     * @param string $extension     The file extension
153
     * @param string $destination   The destination path. Automatically generated if empty.
154
     */
155 View Code Duplication
    public function writeImageFile($binaryData, $extension, $destination = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
    {
157
        $extension = trim(strtolower($extension), '. ');
158
        $destination = $destination ?: $this->generateRandomImagePath($extension);
159
        file_put_contents($destination, $binaryData);
160
161
        $this->update(['image' => basename($destination)]);
162
    }
163
164
    /**
165
     * Generate a random path for the artist's image.
166
     *
167
     * @param string $extension The extension of the cover (without dot)
168
     *
169
     * @return string
170
     */
171
    private function generateRandomImagePath($extension)
172
    {
173
        return app()->publicPath().'/public/img/artists/'.uniqid('', true).".$extension";
174
    }
175
176
    /**
177
     * Turn the image name into its absolute URL.
178
     *
179
     * @param mixed $value
180
     *
181
     * @return string|null
182
     */
183
    public function getImageAttribute($value)
184
    {
185
        return  $value ? app()->staticUrl("public/img/artists/$value") : null;
186
    }
187
}
188