[ 'name' => 'Client ID', 'type' => 'text', 'required' => true ], 'clientsecret' => [ 'name' => 'Client secret', 'type' => 'text', 'required' => true ], 'spotifyuri' => [ 'name' => 'Spotify URIs', 'type' => 'text', 'required' => true, 'exampleValue' => 'spotify:artist:4lianjyuR1tqf6oUX8kjrZ [,spotify:artist:3JsMj0DEzyWc0VDlHuy9Bx]', ], 'albumtype' => [ 'name' => 'Album type', 'type' => 'text', 'required' => false, 'exampleValue' => 'album,single,appears_on,compilation', 'defaultValue' => 'album,single' ], 'country' => [ 'name' => 'Country', 'type' => 'text', 'required' => false, 'exampleValue' => 'US', 'defaultValue' => 'US' ] ]]; const TOKENURI = 'https://accounts.spotify.com/api/token'; const APIURI = 'https://api.spotify.com/v1/'; private $uri = ''; private $name = ''; private $token = ''; private $artists = []; private $albums = []; public function getURI() { if (empty($this->uri)) { $this->getArtist(); } return $this->uri; } public function getName() { if (empty($this->name)) { $this->getArtist(); } return $this->name; } public function getIcon() { return 'https://www.scdn.co/i/_global/favicon.png'; } private function getId($artist) { return explode(':', $artist)[2]; } private function getDate($album_date) { if (strlen($album_date) == 4) { $album_date .= '-01-01'; } elseif (strlen($album_date) == 7) { $album_date .= '-01'; } return DateTime::createFromFormat('Y-m-d', $album_date)->getTimestamp(); } private function getAlbumType() { return $this->getInput('albumtype'); } private function getCountry() { return $this->getInput('country'); } private function getToken() { $cacheFactory = new CacheFactory(); $cache = $cacheFactory->create(); $cache->setScope('SpotifyBridge'); $cache->setKey(['token']); if ($cache->getTime()) { $time = (new DateTime())->getTimestamp() - $cache->getTime(); Debug::log('Token time: ' . $time); } if ($cache->getTime() == false || $time >= 3600) { Debug::log('Fetching token from Spotify'); $this->fetchToken(); $cache->saveData($this->token); } else { Debug::log('Loading token from cache'); $this->token = $cache->loadData(); } Debug::log('Token: ' . $this->token); } private function getArtist() { if (!is_null($this->getInput('spotifyuri')) && strpos($this->getInput('spotifyuri'), ',') === false) { $artist = $this->fetchContent(self::APIURI . 'artists/' . $this->getId($this->artists[0])); $this->uri = $artist['external_urls']['spotify']; $this->name = $artist['name'] . ' - Spotify'; } else { $this->uri = parent::getURI(); $this->name = parent::getName(); } } private function getAllArtists() { Debug::log('Parsing all artists'); $this->artists = explode(',', $this->getInput('spotifyuri')); } private function getAllAlbums() { $this->albums = []; $this->getAllArtists(); Debug::log('Fetching all albums'); foreach ($this->artists as $artist) { $fetch = true; $offset = 0; while ($fetch) { $partial_albums = $this->fetchContent(self::APIURI . 'artists/' . $this->getId($artist) . '/albums?limit=50&include_groups=' . $this->getAlbumType() . '&country=' . $this->getCountry() . '&offset=' . $offset); if (!empty($partial_albums['items'])) { $this->albums = array_merge( $this->albums, $partial_albums['items'] ); } else { $fetch = false; } $offset += 50; } } } private function fetchToken() { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, self::TOKENURI); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, 'grant_type=client_credentials'); curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Basic ' . base64_encode($this->getInput('clientid') . ':' . $this->getInput('clientsecret'))]); $json = curl_exec($curl); $json = json_decode($json)->access_token; curl_close($curl); $this->token = $json; } private function fetchContent($url) { $this->getToken(); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $this->token]); Debug::log('Fetching content from ' . $url); $json = curl_exec($curl); $json = json_decode($json, true); curl_close($curl); return $json; } private function sortAlbums() { Debug::log('Sorting albums'); usort($this->albums, function ($album1, $album2) { if ($this->getDate($album1['release_date']) < $this->getDate($album2['release_date'])) { return 1; } else { return -1; } }); } public function collectData() { $offset = 0; $this->getAllAlbums(); $this->sortAlbums(); Debug::log('Building RSS feed'); foreach ($this->albums as $album) { $item = []; $item['title'] = $album['name']; $item['uri'] = $album['external_urls']['spotify']; $item['timestamp'] = $this->getDate($album['release_date']); $item['author'] = $album['artists'][0]['name']; $item['categories'] = [$album['album_type']]; $item['content'] = ''; if ($album['total_tracks'] > 1) { $item['content'] .= '

Total tracks: ' . $album['total_tracks'] . '

'; } $this->items[] = $item; if (count($this->items) >= 10) { break; } } } }