Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  type safe ternary
  fix attributes not always returned by the API
  fix psalm
  fix search test
  all results keys may not be defined depending on the search
  url encode the term to search
  • Loading branch information
Baptouuuu committed Apr 13, 2020
2 parents 0104da4 + 67a7646 commit 0010e49
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 81 deletions.
5 changes: 4 additions & 1 deletion fixtures/SDK/Catalog/Album.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ static function($id, $artwork, $name, $single, $url, $complete, $genres, $tracks
return new Model($id, $artwork, $name, $single, $url, $complete, $genres, $tracks, $masteredForItunes, $release, $recordLabel, $copyright, $editorialNotes, $artists);
},
Album\Id::any(),
Artwork::any(),
new Set\Either(
Artwork::any(),
Set\Elements::of(null),
),
Album\Name::any(),
Set\Elements::of(true, false),
Url::any(),
Expand Down
25 changes: 20 additions & 5 deletions fixtures/SDK/Catalog/Artwork.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,26 @@ static function($width, $height, $url, $background, $text1, $text2, $text3, $tex
Artwork\Width::any(),
Artwork\Height::any(),
Url::any(),
Colour::any(),
Colour::any(),
Colour::any(),
Colour::any(),
Colour::any(),
new Set\Either(
Colour::any(),
Set\Elements::of(null),
),
new Set\Either(
Colour::any(),
Set\Elements::of(null),
),
new Set\Either(
Colour::any(),
Set\Elements::of(null),
),
new Set\Either(
Colour::any(),
Set\Elements::of(null),
),
new Set\Either(
Colour::any(),
Set\Elements::of(null),
),
);
}
}
11 changes: 9 additions & 2 deletions src/SDK/Catalog/Album.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
final class Album
{
private Id $id;
private Artwork $artwork;
private ?Artwork $artwork;
private Name $name;
private bool $single;
private Url $url;
Expand All @@ -42,7 +42,7 @@ final class Album
*/
public function __construct(
Id $id,
Artwork $artwork,
?Artwork $artwork,
Name $name,
bool $single,
Url $url,
Expand Down Expand Up @@ -81,8 +81,15 @@ public function id(): Id
return $this->id;
}

public function hasArtwork(): bool
{
return $this->artwork instanceof Artwork;
}

/** @psalm-suppress InvalidNullableReturnType */
public function artwork(): Artwork
{
/** @psalm-suppress NullableReturnStatement */
return $this->artwork;
}

Expand Down
30 changes: 15 additions & 15 deletions src/SDK/Catalog/Artwork.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ final class Artwork
private Width $width;
private Height $height;
private Url $url;
private RGBA $backgroundColor;
private RGBA $textColor1;
private RGBA $textColor2;
private RGBA $textColor3;
private RGBA $textColor4;
private ?RGBA $backgroundColor;
private ?RGBA $textColor1;
private ?RGBA $textColor2;
private ?RGBA $textColor3;
private ?RGBA $textColor4;

public function __construct(
Width $width,
Height $height,
Url $url,
RGBA $backgroundColor,
RGBA $textColor1,
RGBA $textColor2,
RGBA $textColor3,
RGBA $textColor4
?RGBA $backgroundColor,
?RGBA $textColor1,
?RGBA $textColor2,
?RGBA $textColor3,
?RGBA $textColor4
) {
$this->width = $width;
$this->height = $height;
Expand All @@ -60,27 +60,27 @@ public function url(): Url
return $this->url;
}

public function backgroundColor(): RGBA
public function backgroundColor(): ?RGBA
{
return $this->backgroundColor;
}

public function textColor1(): RGBA
public function textColor1(): ?RGBA
{
return $this->textColor1;
}

public function textColor2(): RGBA
public function textColor2(): ?RGBA
{
return $this->textColor2;
}

public function textColor3(): RGBA
public function textColor3(): ?RGBA
{
return $this->textColor3;
}

public function textColor4(): RGBA
public function textColor4(): ?RGBA
{
return $this->textColor4;
}
Expand Down
123 changes: 71 additions & 52 deletions src/SDK/Catalog/Catalog.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,40 +68,46 @@ public function artist(Artist\Id $id): Artist

public function album(Album\Id $id): Album
{
/** @var array{data: array{0: array{attributes: array{artwork: array{width: int, height: int, url: string, bgColor: string, textColor1: string, textColor2: string, textColor3: string, textColor4: string}, name: string, isSingle: bool, url: string, isComplete: bool, genreNames: list<string>, isMasteredForItunes: bool, releaseDate: string, recordLabel: string, copyright: string, editorialNotes: array{standard: string, short: string}}, relationships: array{tracks: array{data: list<array{id: int}>}, artists: array{data: list<array{id: int}>}}}}} */
/** @var array{data: array{0: array{attributes: array{artwork?: array{width: int, height: int, url: string, bgColor?: string, textColor1?: string, textColor2?: string, textColor3?: string, textColor4?: string}, name: string, isSingle: bool, url: string, isComplete: bool, genreNames: list<string>, isMasteredForItunes: bool, releaseDate: string, recordLabel: string, copyright?: string, editorialNotes?: array{standard: string, short: string}}, relationships: array{tracks: array{data: list<array{id: int}>}, artists: array{data: list<array{id: int}>}}}}} */
$resource = $this->get($this->url("albums/{$id->toString()}"));
$attributes = $resource['data'][0]['attributes'];
$bgColor = $attributes['artwork']['bgColor'] ?? null;
$textColor1 = $attributes['artwork']['textColor1'] ?? null;
$textColor2 = $attributes['artwork']['textColor2'] ?? null;
$textColor3 = $attributes['artwork']['textColor3'] ?? null;
$textColor4 = $attributes['artwork']['textColor4'] ?? null;

return new Album(
$id,
new Artwork(
new Artwork\Width($resource['data'][0]['attributes']['artwork']['width']),
new Artwork\Height($resource['data'][0]['attributes']['artwork']['height']),
Url::of($resource['data'][0]['attributes']['artwork']['url']),
RGBA::of($resource['data'][0]['attributes']['artwork']['bgColor']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor1']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor2']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor3']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor4']),
),
new Album\Name($resource['data'][0]['attributes']['name']),
$resource['data'][0]['attributes']['isSingle'],
Url::of($resource['data'][0]['attributes']['url']),
$resource['data'][0]['attributes']['isComplete'],
\array_key_exists('artwork', $attributes) ? new Artwork(
new Artwork\Width($attributes['artwork']['width']),
new Artwork\Height($attributes['artwork']['height']),
Url::of($attributes['artwork']['url']),
\is_string($bgColor) ? RGBA::of($bgColor) : null,
\is_string($textColor1) ? RGBA::of($textColor1) : null,
\is_string($textColor2) ? RGBA::of($textColor2) : null,
\is_string($textColor3) ? RGBA::of($textColor3) : null,
\is_string($textColor4) ? RGBA::of($textColor4) : null,
) : null,
new Album\Name($attributes['name']),
$attributes['isSingle'],
Url::of($attributes['url']),
$attributes['isComplete'],
Set::of(Genre::class, ...\array_map(
static fn(string $genre): Genre => new Genre($genre),
$resource['data'][0]['attributes']['genreNames'],
$attributes['genreNames'],
)),
Set::of(Song\Id::class, ...\array_map(
static fn(array $song): Song\Id => new Song\Id((int) $song['id']),
$resource['data'][0]['relationships']['tracks']['data'],
)),
$resource['data'][0]['attributes']['isMasteredForItunes'],
$this->clock->at($resource['data'][0]['attributes']['releaseDate']),
new Album\RecordLabel($resource['data'][0]['attributes']['recordLabel']),
new Album\Copyright($resource['data'][0]['attributes']['copyright']),
$attributes['isMasteredForItunes'],
$this->clock->at($attributes['releaseDate']),
new Album\RecordLabel($attributes['recordLabel']),
new Album\Copyright($attributes['copyright'] ?? ''),
new Album\EditorialNotes(
$resource['data'][0]['attributes']['editorialNotes']['standard'],
$resource['data'][0]['attributes']['editorialNotes']['short'],
$attributes['editorialNotes']['standard'] ?? '',
$attributes['editorialNotes']['short'] ?? '',
),
Set::of(Artist\Id::class, ...\array_map(
static fn(array $artist): Artist\Id => new Artist\Id((int) $artist['id']),
Expand All @@ -112,37 +118,43 @@ public function album(Album\Id $id): Album

public function song(Song\Id $id): Song
{
/** @var array{data: array{0: array{attributes: array{previews: list<array{url: string}>, artwork: array{width: int, height: int, url: string, bgColor: string, textColor1: string, textColor2: string, textColor3: string, textColor4: string}, url: string, discNumber: int, genreNames: list<string>, durationInMillis: int, releaseDate: string, name: string, isrc: string, trackNumber: int, composerName: string}, relationships: array{artists: array{data: list<array{id: int}>}, albums: array{data: list<array{id: int}>}}}}} */
/** @var array{data: array{0: array{attributes: array{previews: list<array{url: string}>, artwork: array{width: int, height: int, url: string, bgColor?: string, textColor1?: string, textColor2?: string, textColor3?: string, textColor4?: string}, url: string, discNumber: int, genreNames: list<string>, durationInMillis?: int, releaseDate: string, name: string, isrc: string, trackNumber: int, composerName?: string}, relationships: array{artists: array{data: list<array{id: int}>}, albums: array{data: list<array{id: int}>}}}}} */
$resource = $this->get($this->url("songs/{$id->toString()}"));
$attributes = $resource['data'][0]['attributes'];
$bgColor = $attributes['artwork']['bgColor'] ?? null;
$textColor1 = $attributes['artwork']['textColor1'] ?? null;
$textColor2 = $attributes['artwork']['textColor2'] ?? null;
$textColor3 = $attributes['artwork']['textColor3'] ?? null;
$textColor4 = $attributes['artwork']['textColor4'] ?? null;

return new Song(
$id,
Set::of(Url::class, ...\array_map(
static fn(array $preview): Url => Url::of($preview['url']),
$resource['data'][0]['attributes']['previews'],
$attributes['previews'],
)),
new Artwork(
new Artwork\Width($resource['data'][0]['attributes']['artwork']['width']),
new Artwork\Height($resource['data'][0]['attributes']['artwork']['height']),
Url::of($resource['data'][0]['attributes']['artwork']['url']),
RGBA::of($resource['data'][0]['attributes']['artwork']['bgColor']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor1']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor2']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor3']),
RGBA::of($resource['data'][0]['attributes']['artwork']['textColor4']),
new Artwork\Width($attributes['artwork']['width']),
new Artwork\Height($attributes['artwork']['height']),
Url::of($attributes['artwork']['url']),
\is_string($bgColor) ? RGBA::of($bgColor) : null,
\is_string($textColor1) ? RGBA::of($textColor1) : null,
\is_string($textColor2) ? RGBA::of($textColor2) : null,
\is_string($textColor3) ? RGBA::of($textColor3) : null,
\is_string($textColor4) ? RGBA::of($textColor4) : null,
),
Url::of($resource['data'][0]['attributes']['url']),
new Song\DiscNumber($resource['data'][0]['attributes']['discNumber']),
Url::of($attributes['url']),
new Song\DiscNumber($attributes['discNumber']),
Set::of(Genre::class, ...\array_map(
static fn(string $genre): Genre => new Genre($genre),
$resource['data'][0]['attributes']['genreNames'],
$attributes['genreNames'],
)),
new Song\Duration($resource['data'][0]['attributes']['durationInMillis']),
$this->clock->at($resource['data'][0]['attributes']['releaseDate']),
new Song\Name($resource['data'][0]['attributes']['name']),
new Song\ISRC($resource['data'][0]['attributes']['isrc']),
new Song\TrackNumber($resource['data'][0]['attributes']['trackNumber']),
new Song\Composer($resource['data'][0]['attributes']['composerName']),
Song\Duration::of($attributes['durationInMillis'] ?? null),
$this->clock->at($attributes['releaseDate']),
new Song\Name($attributes['name']),
new Song\ISRC($attributes['isrc']),
new Song\TrackNumber($attributes['trackNumber']),
new Song\Composer($attributes['composerName'] ?? ''),
Set::of(Artist\Id::class, ...\array_map(
static fn(array $artist): Artist\Id => new Artist\Id((int) $artist['id']),
$resource['data'][0]['relationships']['artists']['data'],
Expand Down Expand Up @@ -184,25 +196,28 @@ public function genres(): Set

public function search(string $term): Search
{
$url = $this->url("search?term=$term&types=artists,albums,songs&limit=25");
/** @var array{results: array{artists: array{data: list<array{id: int}>, next?: string}, albums: array{data: list<array{id: int}>, next?: string}, songs: array{data: list<array{id: int}>, next?: string}}} */
$encodedTerm = \urlencode($term);
$url = $this->url("search?term=$encodedTerm&types=artists,albums,songs&limit=25");
/** @var array{results: array{artists?: array{data: list<array{id: int}>, next?: string}, albums?: array{data: list<array{id: int}>, next?: string}, songs?: array{data: list<array{id: int}>, next?: string}}} */
$resource = $this->get($url);

/** @var Sequence<Artist\Id> */
$artists = Sequence::lazy(
Artist\Id::class,
function() use ($resource): \Generator {
do {
foreach ($resource['results']['artists']['data'] as $artist) {
$artists = $resource['results']['artists'] ?? [];

foreach ($artists['data'] ?? [] as $artist) {
yield new Artist\Id((int) $artist['id']);
}

if (!\array_key_exists('next', $resource['results']['artists'])) {
if (!\array_key_exists('next', $artists)) {
return;
}

/** @var array{results: array{artists: array{data: list<array{id: int}>, next?: string}}} */
$resource = $this->get(Url::of($resource['results']['artists']['next']));
$resource = $this->get(Url::of($artists['next']));
} while (true);
},
);
Expand All @@ -212,16 +227,18 @@ function() use ($resource): \Generator {
Album\Id::class,
function() use ($resource): \Generator {
do {
foreach ($resource['results']['albums']['data'] as $album) {
$albums = $resource['results']['albums'] ?? [];

foreach ($albums['data'] ?? [] as $album) {
yield new Album\Id((int) $album['id']);
}

if (!\array_key_exists('next', $resource['results']['albums'])) {
if (!\array_key_exists('next', $albums)) {
return;
}

/** @var array{results: array{albums: array{data: list<array{id: int}>, next?: string}}} */
$resource = $this->get(Url::of($resource['results']['albums']['next']));
$resource = $this->get(Url::of($albums['next']));
} while (true);
},
);
Expand All @@ -231,16 +248,18 @@ function() use ($resource): \Generator {
Song\Id::class,
function() use ($resource): \Generator {
do {
foreach ($resource['results']['songs']['data'] as $song) {
$songs = $resource['results']['songs'] ?? [];

foreach ($songs['data'] ?? [] as $song) {
yield new Song\Id((int) $song['id']);
}

if (!\array_key_exists('next', $resource['results']['songs'])) {
if (!\array_key_exists('next', $songs)) {
return;
}

/** @var array{results: array{songs: array{data: list<array{id: int}>, next?: string}}} */
$resource = $this->get(Url::of($resource['results']['songs']['next']));
$resource = $this->get(Url::of($songs['next']));
} while (true);
},
);
Expand Down
11 changes: 9 additions & 2 deletions src/SDK/Catalog/Song.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class Song
private DiscNumber $discNumber;
/** @var Set<Genre> */
private Set $genres;
private Duration $duration;
private ?Duration $duration;
private PointInTime $release;
private Name $name;
private ISRC $isrc;
Expand All @@ -51,7 +51,7 @@ public function __construct(
Url $url,
DiscNumber $discNumber,
Set $genres,
Duration $duration,
?Duration $duration,
PointInTime $release,
Name $name,
ISRC $isrc,
Expand Down Expand Up @@ -117,8 +117,15 @@ public function genres(): Set
return $this->genres;
}

public function durationKnown(): bool
{
return $this->duration instanceof Duration;
}

/** @psalm-suppress InvalidNullableReturnType */
public function duration(): Duration
{
/** @psalm-suppress NullableReturnStatement */
return $this->duration;
}

Expand Down

0 comments on commit 0010e49

Please sign in to comment.