DownloadService   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 21.05%

Importance

Changes 0
Metric Value
wmc 14
eloc 33
c 0
b 0
f 0
dl 0
loc 83
ccs 8
cts 38
cp 0.2105
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A fromAlbum() 0 3 1
A fromMultipleSongs() 0 10 2
A fromArtist() 0 3 1
A from() 0 16 6
A __construct() 0 3 1
A fromSong() 0 20 2
A fromPlaylist() 0 3 1
1
<?php
2
3
namespace App\Services;
4
5
use App\Models\Album;
6
use App\Models\Artist;
7
use App\Models\Playlist;
8
use App\Models\Song;
9
use App\Models\SongZipArchive;
10
use Illuminate\Database\Eloquent\Collection;
11
use InvalidArgumentException;
12
13
class DownloadService
14
{
15
    private $s3Service;
16
17 2
    public function __construct(S3Service $s3Service)
18
    {
19 2
        $this->s3Service = $s3Service;
20 2
    }
21
22
    /**
23
     * Generic method to generate a download archive from various source types.
24
     *
25
     * @param Song|Collection|Album|Artist|Playlist $mixed
26
     *
27
     * @throws InvalidArgumentException
28
     *
29
     * @return string Full path to the generated archive
30
     */
31
    public function from($mixed): string
32
    {
33
        switch (get_class($mixed)) {
34
            case Song::class:
35
                return $this->fromSong($mixed);
0 ignored issues
show
Bug introduced by
It seems like $mixed can also be of type App\Models\Album and App\Models\Artist and App\Models\Playlist and Illuminate\Database\Eloquent\Collection; however, parameter $song of App\Services\DownloadService::fromSong() does only seem to accept App\Models\Song, 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

35
                return $this->fromSong(/** @scrutinizer ignore-type */ $mixed);
Loading history...
36
            case Collection::class:
37
                return $this->fromMultipleSongs($mixed);
0 ignored issues
show
Bug introduced by
It seems like $mixed can also be of type App\Models\Album and App\Models\Artist and App\Models\Playlist and App\Models\Song; however, parameter $songs of App\Services\DownloadService::fromMultipleSongs() does only seem to accept Illuminate\Database\Eloquent\Collection, 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

37
                return $this->fromMultipleSongs(/** @scrutinizer ignore-type */ $mixed);
Loading history...
38
            case Album::class:
39
                return $this->fromAlbum($mixed);
0 ignored issues
show
Bug introduced by
It seems like $mixed can also be of type App\Models\Artist and App\Models\Playlist and App\Models\Song and Illuminate\Database\Eloquent\Collection; however, parameter $album of App\Services\DownloadService::fromAlbum() does only seem to accept App\Models\Album, 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

39
                return $this->fromAlbum(/** @scrutinizer ignore-type */ $mixed);
Loading history...
40
            case Artist::class:
41
                return $this->fromArtist($mixed);
0 ignored issues
show
Bug introduced by
It seems like $mixed can also be of type App\Models\Album and App\Models\Playlist and App\Models\Song and Illuminate\Database\Eloquent\Collection; however, parameter $artist of App\Services\DownloadService::fromArtist() does only seem to accept App\Models\Artist, 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

41
                return $this->fromArtist(/** @scrutinizer ignore-type */ $mixed);
Loading history...
42
            case Playlist::class:
43
                return $this->fromPlaylist($mixed);
0 ignored issues
show
Bug introduced by
It seems like $mixed can also be of type App\Models\Album and App\Models\Artist and App\Models\Song and Illuminate\Database\Eloquent\Collection; however, parameter $playlist of App\Services\DownloadService::fromPlaylist() does only seem to accept App\Models\Playlist, 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

43
                return $this->fromPlaylist(/** @scrutinizer ignore-type */ $mixed);
Loading history...
44
        }
45
46
        throw new InvalidArgumentException('Unsupported download type.');
47
    }
48
49 2
    public function fromSong(Song $song): string
50
    {
51 2
        if ($s3Params = $song->s3_params) {
52
            // The song is hosted on Amazon S3.
53
            // We download it back to our local server first.
54
            $url = $this->s3Service->getSongPublicUrl($song);
55
            abort_unless($url, 404);
0 ignored issues
show
Bug introduced by
$url of type string is incompatible with the type boolean expected by parameter $boolean of abort_unless(). ( Ignorable by Annotation )

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

55
            abort_unless(/** @scrutinizer ignore-type */ $url, 404);
Loading history...
56
57
            $localPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.basename($s3Params['key']);
58
59
            // The following function requires allow_url_fopen to be ON.
60
            // We're just assuming that to be the case here.
61
            copy($url, $localPath);
62
        } else {
63
            // The song is hosted locally. Make sure the file exists.
64 2
            $localPath = $song->path;
65 2
            abort_unless(file_exists($localPath), 404);
66
        }
67
68 2
        return $localPath;
69
    }
70
71
    protected function fromMultipleSongs(Collection $songs): string
72
    {
73
        if ($songs->count() === 1) {
74
            return $this->fromSong($songs->first());
75
        }
76
77
        return (new SongZipArchive())
78
            ->addSongs($songs)
79
            ->finish()
80
            ->getPath();
81
    }
82
83
    protected function fromPlaylist(Playlist $playlist): string
84
    {
85
        return $this->fromMultipleSongs($playlist->songs);
86
    }
87
88
    protected function fromAlbum(Album $album): string
89
    {
90
        return $this->fromMultipleSongs($album->songs);
91
    }
92
93
    protected function fromArtist(Artist $artist): string
94
    {
95
        return $this->fromMultipleSongs($artist->songs);
0 ignored issues
show
Bug introduced by
$artist->songs of type App\Models\Song is incompatible with the type Illuminate\Database\Eloquent\Collection expected by parameter $songs of App\Services\DownloadService::fromMultipleSongs(). ( Ignorable by Annotation )

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

95
        return $this->fromMultipleSongs(/** @scrutinizer ignore-type */ $artist->songs);
Loading history...
96
    }
97
}
98