phanan /
koel
| 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
Loading history...
|
|||||
| 36 | case Collection::class: |
||||
| 37 | return $this->fromMultipleSongs($mixed); |
||||
|
0 ignored issues
–
show
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
Loading history...
|
|||||
| 38 | case Album::class: |
||||
| 39 | return $this->fromAlbum($mixed); |
||||
|
0 ignored issues
–
show
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
Loading history...
|
|||||
| 40 | case Artist::class: |
||||
| 41 | return $this->fromArtist($mixed); |
||||
|
0 ignored issues
–
show
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
Loading history...
|
|||||
| 42 | case Playlist::class: |
||||
| 43 | return $this->fromPlaylist($mixed); |
||||
|
0 ignored issues
–
show
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
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
$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
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
$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
Loading history...
|
|||||
| 96 | } |
||||
| 97 | } |
||||
| 98 |