friendship ended with social-app. php is my new best friend
1<?php
2/**
3 * Class Spotify
4 *
5 * @created 06.04.2018
6 * @author Smiley <smiley@chillerlan.net>
7 * @copyright 2018 Smiley
8 * @license MIT
9 *
10 * @noinspection PhpUnused
11 */
12declare(strict_types=1);
13
14namespace chillerlan\OAuth\Providers;
15
16use chillerlan\OAuth\Core\{
17 AuthenticatedUser, ClientCredentials, ClientCredentialsTrait, CSRFToken,
18 OAuth2Provider, PKCE, PKCETrait, TokenRefresh, UserInfo,
19};
20
21/**
22 * Spotify OAuth2
23 *
24 * @link https://developer.spotify.com/documentation/web-api
25 * @link https://developer.spotify.com/documentation/web-api/tutorials/code-flow
26 * @link https://developer.spotify.com/documentation/web-api/tutorials/client-credentials-flow
27 * @link https://developer.spotify.com/documentation/web-api/tutorials/code-pkce-flow
28 */
29class Spotify extends OAuth2Provider implements ClientCredentials, CSRFToken, PKCE, TokenRefresh, UserInfo{
30 use ClientCredentialsTrait, PKCETrait;
31
32 public const IDENTIFIER = 'SPOTIFY';
33
34 /**
35 * @link https://developer.spotify.com/documentation/web-api/concepts/scopes
36 */
37 // images
38 public const SCOPE_UGC_IMAGE_UPLOAD = 'ugc-image-upload';
39 // spotify connect
40 public const SCOPE_USER_READ_PLAYBACK_STATE = 'user-read-playback-state';
41 public const SCOPE_USER_MODIFY_PLAYBACK_STATE = 'user-modify-playback-state';
42 public const SCOPE_USER_READ_CURRENTLY_PLAYING = 'user-read-currently-playing';
43 // playback
44# public const SCOPE_APP_REMOTE_CONTROL = 'app-remote-control'; // currently only on ios and android
45 public const SCOPE_STREAMING = 'streaming'; // web playback SDK
46 // playlists
47 public const SCOPE_PLAYLIST_READ_PRIVATE = 'playlist-read-private';
48 public const SCOPE_PLAYLIST_READ_COLLABORATIVE = 'playlist-read-collaborative';
49 public const SCOPE_PLAYLIST_MODIFY_PRIVATE = 'playlist-modify-private';
50 public const SCOPE_PLAYLIST_MODIFY_PUBLIC = 'playlist-modify-public';
51 // follow
52 public const SCOPE_USER_FOLLOW_MODIFY = 'user-follow-modify';
53 public const SCOPE_USER_FOLLOW_READ = 'user-follow-read';
54 // listening history
55 public const SCOPE_USER_READ_PLAYBACK_POSITION = 'user-read-playback-position';
56 public const SCOPE_USER_TOP_READ = 'user-top-read';
57 public const SCOPE_USER_READ_RECENTLY_PLAYED = 'user-read-recently-played';
58 // library
59 public const SCOPE_USER_LIBRARY_MODIFY = 'user-library-modify';
60 public const SCOPE_USER_LIBRARY_READ = 'user-library-read';
61 // users
62 public const SCOPE_USER_READ_EMAIL = 'user-read-email';
63 public const SCOPE_USER_READ_PRIVATE = 'user-read-private';
64 // open access
65 public const SCOPE_USER_SOA_LINK = 'user-soa-link';
66 public const SCOPE_USER_SOA_UNLINK = 'user-soa-unlink';
67 public const SCOPE_USER_MANAGE_ENTITLEMENTS = 'user-manage-entitlements';
68 public const SCOPE_USER_MANAGE_PARTNER = 'user-manage-partner';
69 public const SCOPE_USER_CREATE_PARTNER = 'user-create-partner';
70
71 public const DEFAULT_SCOPES = [
72 self::SCOPE_PLAYLIST_READ_COLLABORATIVE,
73 self::SCOPE_PLAYLIST_MODIFY_PUBLIC,
74 self::SCOPE_USER_FOLLOW_MODIFY,
75 self::SCOPE_USER_FOLLOW_READ,
76 self::SCOPE_USER_LIBRARY_READ,
77 self::SCOPE_USER_LIBRARY_MODIFY,
78 self::SCOPE_USER_TOP_READ,
79 self::SCOPE_USER_READ_EMAIL,
80 self::SCOPE_STREAMING,
81 self::SCOPE_USER_READ_PLAYBACK_STATE,
82 self::SCOPE_USER_MODIFY_PLAYBACK_STATE,
83 self::SCOPE_USER_READ_CURRENTLY_PLAYING,
84 self::SCOPE_USER_READ_RECENTLY_PLAYED,
85 ];
86
87 protected string $authorizationURL = 'https://accounts.spotify.com/authorize';
88 protected string $accessTokenURL = 'https://accounts.spotify.com/api/token';
89 protected string $apiURL = 'https://api.spotify.com';
90 protected string|null $userRevokeURL = 'https://www.spotify.com/account/apps/';
91 protected string|null $apiDocs = 'https://developer.spotify.com/documentation/web-api/';
92 protected string|null $applicationURL = 'https://developer.spotify.com/dashboard';
93
94 /** @codeCoverageIgnore */
95 public function me():AuthenticatedUser{
96 $json = $this->getMeResponseData('/v1/me');
97
98 $userdata = [
99 'data' => $json,
100 'avatar' => ($json['images'][1]['url'] ?? $json['images'][0]['url'] ?? null),
101 'handle' => $json['uri'],
102 'displayName' => $json['display_name'],
103 'email' => $json['email'],
104 'id' => $json['id'],
105 'url' => $json['external_urls']['spotify'],
106 ];
107
108 return new AuthenticatedUser($userdata);
109 }
110
111}