getKey() && $this->getSecret(); } /** * Get information about an artist. * * @param $name string Name of the artist * * @return array|false */ public function getArtistInfo($name) { if (!$this->enabled()) { return false; } $name = urlencode($name); try { $cacheKey = md5("lastfm_artist_$name"); if ($response = cache($cacheKey)) { $response = simplexml_load_string($response); } else { if ($response = $this->get("?method=artist.getInfo&autocorrect=1&artist=$name")) { cache([$cacheKey => $response->asXML()], 24 * 60 * 7); } } $response = json_decode(json_encode($response), true); if (!$response || !$artist = array_get($response, 'artist')) { return false; } return [ 'url' => array_get($artist, 'url'), 'image' => count($artist['image']) > 3 ? $artist['image'][3] : $artist['image'][0], 'bio' => [ 'summary' => $this->formatText(array_get($artist, 'bio.summary')), 'full' => $this->formatText(array_get($artist, 'bio.content')), ], ]; } catch (Exception $e) { Log::error($e); return false; } } /** * Get information about an album. * * @param string $name Name of the album * @param string $artistName Name of the artist * * @return array|false */ public function getAlbumInfo($name, $artistName) { if (!$this->enabled()) { return false; } $name = urlencode($name); $artistName = urlencode($artistName); try { $cacheKey = md5("lastfm_album_{$name}_{$artistName}"); if ($response = cache($cacheKey)) { $response = simplexml_load_string($response); } else { if ($response = $this->get("?method=album.getInfo&autocorrect=1&album=$name&artist=$artistName")) { cache([$cacheKey => $response->asXML()], 24 * 60 * 7); } } $response = json_decode(json_encode($response), true); if (!$response || !$album = array_get($response, 'album')) { return false; } return [ 'url' => array_get($album, 'url'), 'image' => count($album['image']) > 3 ? $album['image'][3] : $album['image'][0], 'wiki' => [ 'summary' => $this->formatText(array_get($album, 'wiki.summary')), 'full' => $this->formatText(array_get($album, 'wiki.content')), ], 'tracks' => array_map(function ($track) { return [ 'title' => $track['name'], 'length' => (int) $track['duration'], 'url' => $track['url'], ]; }, array_get($album, 'tracks.track', [])), ]; } catch (Exception $e) { Log::error($e); return false; } } /** * Get Last.fm's session key for the authenticated user using a token. * * @param string $token The token after successfully connecting to Last.fm * * @link http://www.last.fm/api/webauth#4 * * @return string The token key */ public function getSessionKey($token) { $query = $this->buildAuthCallParams([ 'method' => 'auth.getSession', 'token' => $token, ], true); try { $response = $this->get("/?$query", [], false); return (string) $response->session->key; } catch (Exception $e) { Log::error($e); return false; } } /** * Scrobble a song. * * @param string $artist The artist name * @param string $track The track name * @param string|int $timestamp The UNIX timestamp * @param string $album The album name * @param string $sk The session key * * @return bool */ public function scrobble($artist, $track, $timestamp, $album, $sk) { $params = compact('artist', 'track', 'timestamp', 'sk'); if ($album) { $params['album'] = $album; } $params['method'] = 'track.scrobble'; try { return (bool) $this->post('/', $this->buildAuthCallParams($params), false); } catch (Exception $e) { Log::error($e); return false; } } /** * Love or unlove a track on Last.fm. * * @param string $track The track name * @param string $artist The artist's name * @param string $sk The session key * @param bool $love Whether to love or unlove. Such cheesy terms... urrgggh * * @return bool */ public function toggleLoveTrack($track, $artist, $sk, $love = true) { $params = compact('track', 'artist', 'sk'); $params['method'] = $love ? 'track.love' : 'track.unlove'; try { return (bool) $this->post('/', $this->buildAuthCallParams($params), false); } catch (Exception $e) { Log::error($e); return false; } } /** * Update a track's "now playing" on Last.fm. * * @param string $artist Name of the artist * @param string $track Name of the track * @param string $album Name of the album * @param int|float $duration Duration of the track, in seconds * @param string $sk The session key * * @return bool */ public function updateNowPlaying($artist, $track, $album, $duration, $sk) { $params = compact('artist', 'track', 'duration', 'sk'); $params['method'] = 'track.updateNowPlaying'; if ($album) { $params['album'] = $album; } try { return (bool) $this->post('/', $this->buildAuthCallParams($params), false); } catch (Exception $e) { Log::error($e); return false; } } /** * Build the parameters to use for _authenticated_ Last.fm API calls. * Such calls require: * - The API key (api_key) * - The API signature (api_sig). * * @link http://www.last.fm/api/webauth#5 * * @param array $params The array of parameters. * @param bool $toString Whether to turn the array into a query string * * @return array|string */ public function buildAuthCallParams(array $params, $toString = false) { $params['api_key'] = $this->getKey(); ksort($params); // Generate the API signature. // @link http://www.last.fm/api/webauth#6 $str = ''; foreach ($params as $name => $value) { $str .= $name.$value; } $str .= $this->getSecret(); $params['api_sig'] = md5($str); if (!$toString) { return $params; } $query = ''; foreach ($params as $key => $value) { $query .= "$key=$value&"; } return rtrim($query, '&'); } /** * Correctly format a string returned by Last.fm. * * @param string $str * * @return string */ protected function formatText($str) { if (!$str) { return ''; } return trim(str_replace('Read more on Last.fm', '', nl2br(strip_tags(html_entity_decode($str))))); } }