Passed
Push — main ( 464f55...4d72a0 )
by Daniel
14:54 queued 11:08
created

GetRandomSongsDataProvider   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 6
eloc 32
c 1
b 0
f 1
dl 0
loc 93
ccs 36
cts 36
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A retrieveSongs() 0 19 2
A getRandomSongs() 0 28 3
A __construct() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Uxmp\Core\Component\SubSonic;
6
7
use Generator;
8
use Traversable;
9
use Usox\HyperSonic\FeatureSet\V1161\Contract\GetRandomSongsDataProviderInterface;
10
use Uxmp\Core\Component\Song\RandomSongsRetrieverInterface;
11
use Uxmp\Core\Orm\Model\SongInterface;
12
use Uxmp\Core\Orm\Repository\CatalogRepositoryInterface;
13
use Uxmp\Core\Orm\Repository\GenreRepositoryInterface;
14
15
/**
16
 * Retrieves songs in random order, optionally filtered by the given config
17
 */
18
final class GetRandomSongsDataProvider implements GetRandomSongsDataProviderInterface
19
{
20
    /** @var int */
21
    private const DEFAULT_SONG_LIMIT = 10;
22
23 2
    public function __construct(
24
        private readonly RandomSongsRetrieverInterface $randomSongsRetriever,
25
        private readonly CatalogRepositoryInterface $catalogRepository,
26
        private readonly GenreRepositoryInterface $genreRepository,
27
    ) {
28 2
    }
29
30
    /**
31
     * @return Traversable<array{
32
     *  id: int|string,
33
     *  name: string,
34
     *  albumId: int|string,
35
     *  artistName: string,
36
     *  albumName: string,
37
     *  trackNumber: int,
38
     *  year: int,
39
     *  genre: string,
40
     *  coverArtId: string,
41
     *  length: int,
42
     *  filesize: int
43
     *  }>
44
     */
45 2
    public function getRandomSongs(
46
        ?string $musicFolderId,
47
        ?int $limit = self::DEFAULT_SONG_LIMIT,
48
        ?string $genreName = null,
49
        ?int $fromYear = null,
50
        ?int $toYear = null
51
    ): Traversable {
52 2
        $catalog = null;
53 2
        $genre = null;
54 2
        if ($musicFolderId !== null) {
55 1
            $catalog = $this->catalogRepository->find((int) $musicFolderId);
56
        }
57
58 2
        if ($genreName !== null) {
59 1
            $genre = $this->genreRepository->findOneBy([
60 1
                'title' => $genreName,
61 1
            ]);
62
        }
63
64 2
        $songs = $this->randomSongsRetriever->retrieve(
65 2
            $limit ?? self::DEFAULT_SONG_LIMIT,
66 2
            $catalog,
67 2
            $genre,
68 2
            $fromYear,
69 2
            $toYear
70 2
        );
71
72 2
        return $this->retrieveSongs($songs);
73
    }
74
75
    /**
76
     * @param iterable<SongInterface> $songs
77
     *
78
     * @return Generator<array{
79
     *  id: int|string,
80
     *  name: string,
81
     *  albumId: int|string,
82
     *  artistName: string,
83
     *  albumName: string,
84
     *  trackNumber: int,
85
     *  year: int,
86
     *  genre: string,
87
     *  coverArtId: string,
88
     *  length: int,
89
     *  filesize: int
90
     * }>
91
     */
92 2
    private function retrieveSongs(iterable $songs): Generator
93
    {
94 2
        foreach ($songs as $song) {
95 2
            $artist = $song->getArtist();
96 2
            $album = $song->getAlbum();
97 2
            $songId = $song->getId();
98
99 2
            yield [
100 2
                'id' => $songId,
101 2
                'albumId' => $album->getId(),
102 2
                'name' => $song->getTitle(),
103 2
                'albumName' => (string) $album->getTitle(),
104 2
                'artistName' => (string) $artist->getTitle(),
105 2
                'trackNumber' => $song->getTrackNumber(),
106 2
                'year' => (int) $album->getYear(),
107 2
                'genre' => 'Aggi', // @todo add genre
108 2
                'coverArtId' => sprintf('song-%d', $songId),
109 2
                'length' => $song->getLength(),
110 2
                'filesize' => $song->getFileSize(),
111 2
            ];
112
        }
113
    }
114
}
115