[GH-ISSUE #213] Search for Episodes and Shows - no data returned #145

Closed
opened 2026-02-27 19:26:18 +03:00 by kerem · 8 comments
Owner

Originally created by @ghost on GitHub (Dec 21, 2020).
Original GitHub issue: https://github.com/jwilsson/spotify-web-api-php/issues/213

Hi - thanks again for this excellent and very useful resource.

I'm using the search API as follows:

$options = ['offset' => 0,'limit' => 5];
$search = $api->search($str,'album,track,playlist,artist,show,episode', $options);

When I get the response back from Spotify I convert it into an array.

When I run a search for e.g. 'fugazi', the response from the API returns data for album, track, playlist and artist.

There are also headings in the array for shows and episodes, but they are always empty.

This demonstrates an example response after outputting to the page using php-ref:

Array screenshot

In the above example, there are 10 records showing in the 'total' value for 'shows' but the 'items' array is empty, so there are no details for the shows, in the same way that e.g. the 'items' array for 'playlists' is populated.

I have read the Spotify Search API docs but can't see anything that says e.g. that the user must be logged in before the search will work.

I wondered when I might be doing wrong?

Thanks

Originally created by @ghost on GitHub (Dec 21, 2020). Original GitHub issue: https://github.com/jwilsson/spotify-web-api-php/issues/213 Hi - thanks again for this excellent and very useful resource. I'm using the search API as follows: ``` $options = ['offset' => 0,'limit' => 5]; $search = $api->search($str,'album,track,playlist,artist,show,episode', $options); ``` When I get the response back from Spotify I convert it into an array. When I run a search for e.g. 'fugazi', the response from the API returns data for album, track, playlist and artist. There are also headings in the array for shows and episodes, but they are always empty. This demonstrates an example response after outputting to the page using [php-ref](https://github.com/digitalnature/php-ref): ![Array screenshot](https://i.imgur.com/Syx7R0C.png) In the above example, there are 10 records showing in the 'total' value for 'shows' but the 'items' array is empty, so there are no details for the shows, in the same way that e.g. the 'items' array for 'playlists' _is_ populated. I have read the [Spotify Search API docs](https://developer.spotify.com/documentation/web-api/reference-beta/#category-search) but can't see anything that says e.g. that the user must be logged in before the search will work. I wondered when I might be doing wrong? Thanks
kerem 2026-02-27 19:26:18 +03:00
  • closed this issue
  • added the
    question
    label
Author
Owner

@jwilsson commented on GitHub (Dec 22, 2020):

Hi again!
That's really strange, when I run the same query "fugazi" and the same options I'm getting results back for all types. I think the results can sometimes differ depending on the country your account belongs to as well, perhaps that can be one reason?

You're saying you're converting the result to an array, are you using the return_assoc option or doing it yourself after fetching the results? Could that be an issue?

<!-- gh-comment-id:749345026 --> @jwilsson commented on GitHub (Dec 22, 2020): Hi again! That's really strange, when I run the same query "fugazi" and the same options I'm getting results back for all types. I think the results can sometimes differ depending on the country your account belongs to as well, perhaps that can be one reason? You're saying you're converting the result to an array, are you using the [`return_assoc` option](https://github.com/jwilsson/spotify-web-api-php/blob/master/docs/examples/setting-options.md#return_assoc) or doing it yourself after fetching the results? Could that be an issue?
Author
Owner

@ghost commented on GitHub (Dec 22, 2020):

Hi Jonathan,

Thanks for your reply.

I was using this to convert the Object to an Array:

// https://stackoverflow.com/questions/4345554/convert-a-php-object-to-an-associative-array
function objectToArray($r)
{
  if (is_object($r)) {
	if (method_exists($r, 'toArray')) {
	  return $r->toArray(); // returns result directly
	} else {
	  $r = get_object_vars($r);
	}
  }

  if (is_array($r)) {
	$r = array_map(__FUNCTION__, $r); // recursive function call
  }

  return $r;
}

I didn't realise there was an option in your code to do that, that's great.

I have tested with:

$options = ['return_assoc' => true];
$api = new SpotifyWebAPI\SpotifyWebAPI($options);
$api->setAccessToken($accessToken);
$search = $api->search('fugazi','artist,album,track,playlist,show,episode');
var_export($search);

Again, for some reason, the items section in the array is empty for both episodes and shows.

I also tested searching just for episode or show, e.g.

$search = $api->search('fugazi','episode');

But the same result happens there too.

Maybe as you say, there's some issue with location - I'm in the UK. In my account settings my location is set to United Kingdom.

Thanks again for your help.

<!-- gh-comment-id:749403776 --> @ghost commented on GitHub (Dec 22, 2020): Hi Jonathan, Thanks for your reply. I was using this to convert the Object to an Array: ``` // https://stackoverflow.com/questions/4345554/convert-a-php-object-to-an-associative-array function objectToArray($r) { if (is_object($r)) { if (method_exists($r, 'toArray')) { return $r->toArray(); // returns result directly } else { $r = get_object_vars($r); } } if (is_array($r)) { $r = array_map(__FUNCTION__, $r); // recursive function call } return $r; } ``` I didn't realise there was an option in your code to do that, that's great. I have tested with: ``` $options = ['return_assoc' => true]; $api = new SpotifyWebAPI\SpotifyWebAPI($options); $api->setAccessToken($accessToken); $search = $api->search('fugazi','artist,album,track,playlist,show,episode'); var_export($search); ``` Again, for some reason, the `items` section in the array is empty for both episodes and shows. I also tested searching just for episode or show, e.g. `$search = $api->search('fugazi','episode');` But the same result happens there too. Maybe as you say, there's some issue with location - I'm in the UK. In my account settings my location is set to United Kingdom. Thanks again for your help.
Author
Owner

@jwilsson commented on GitHub (Dec 22, 2020):

Are you using Authorization Code or Client Credentials flow to authenticate? Previously I tried with the Authorization Code flow but now when I used the Client Credentials flow I'm also getting empty results for shows and episodes. Does your use case allow for the Authorization Code flow instead?

If not, I'd post a question on their developer forum and see if anyone from Spotify can shed any light on it.

<!-- gh-comment-id:749696866 --> @jwilsson commented on GitHub (Dec 22, 2020): Are you using Authorization Code or Client Credentials flow to authenticate? Previously I tried with the Authorization Code flow but now when I used the Client Credentials flow I'm also getting empty results for shows and episodes. Does your use case allow for the Authorization Code flow instead? If not, I'd post a question on [their developer forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer) and see if anyone from Spotify can shed any light on it.
Author
Owner

@ghost commented on GitHub (Dec 22, 2020):

Hi - thanks for your latest reply. Yes, I am using the Client Credentials flow. I have been avoiding using the Authorization Code flow because I quickly get out of my depth :-) as I'm not a "proper" programmer.

I realise this is a very big ask, but I wondered if there is any place you're aware of which provides example code for how to cover e.g. an implementation of the Authorization Code flow?

I found this example here: https://gist.github.com/matthijsotterloo/da9da7a90214cfbf9ab0.

However, it doesn't contain the code for the other files that are referenced in the 'required' sections.

Reading previous issues, I found this example of the refresh option: https://github.com/jwilsson/spotify-web-api-php/issues/181.

However, that's not a complete example as I realise the person for that issue was asking about one part of their code.

I am interested to learn how to become a better programmer, but I find it very useful to learn from unpicking existing code, but I'm struggling to find a good example that uses your repository as the basis.

Thanks again for your help and patience.

<!-- gh-comment-id:749764725 --> @ghost commented on GitHub (Dec 22, 2020): Hi - thanks for your latest reply. Yes, I am using the Client Credentials flow. I have been avoiding using the Authorization Code flow because I quickly get out of my depth :-) as I'm not a "proper" programmer. I realise this is a very big ask, but I wondered if there is any place you're aware of which provides example code for how to cover e.g. an implementation of the Authorization Code flow? I found this example here: [https://gist.github.com/matthijsotterloo/da9da7a90214cfbf9ab0](https://gist.github.com/matthijsotterloo/da9da7a90214cfbf9ab0). However, it doesn't contain the code for the other files that are referenced in the 'required' sections. Reading previous issues, I found this example of the refresh option: [https://github.com/jwilsson/spotify-web-api-php/issues/181](https://github.com/jwilsson/spotify-web-api-php/issues/181). However, that's not a complete example as I realise the person for that issue was asking about one part of their code. I am interested to learn how to become a better programmer, but I find it very useful to learn from unpicking existing code, but I'm struggling to find a good example that uses your repository as the basis. Thanks again for your help and patience.
Author
Owner

@jwilsson commented on GitHub (Dec 23, 2020):

No worries!

The docs for this library has lot of examples and a complete guide on the Authorization Code flow. If something's unclear or if you think I can improve it in any way, please let me know! I'm always looking for ways to make the docs better :)

<!-- gh-comment-id:749941289 --> @jwilsson commented on GitHub (Dec 23, 2020): No worries! The [docs](https://github.com/jwilsson/spotify-web-api-php/tree/master/docs) for this library has lot of examples and a [complete guide on the Authorization Code flow](https://github.com/jwilsson/spotify-web-api-php/blob/master/docs/examples/access-token-with-authorization-code-flow.md). If something's unclear or if you think I can improve it in any way, please let me know! I'm always looking for ways to make the docs better :)
Author
Owner

@ghost commented on GitHub (Dec 23, 2020):

Hi Jonathan,

Thank you again for your reply. Your docs are excellent and very informative.

The thing I am struggling to understand is the refresh route.

I have the basic Auth page here from your example:

auth.php

<?php
require '../../vendor/autoload.php';
require '../../config/spotify.php';

$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET',
    'http://localhost/spotify/callback.php'
);

$options = [
    'scope' => [
        'playlist-read-private',
        'user-read-private',
    ],
];

header('Location: ' . $session->getAuthorizeUrl($options));
die();
?>

Then moving on to the callback... I'm cheating by passing accessToken and refreshToken by the QueryString for local development, I wouldn't do this later on. One question is - if I stored them in a database, how would they be tied to a unique user record - maybe by storing them against the id value for the user's record, returned from $api-me()?

callback.php

<?php
require '../../vendor/autoload.php';
require '../../config/spotify.php';

$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET',
    'http://localhost/spotify/callback.php'
);

// Request a access token using the code from Spotify
$session->requestAccessToken($_GET['code']);

$accessToken = $session->getAccessToken();
$refreshToken = $session->getRefreshToken();

// Store the access and refresh tokens somewhere. In a database for example.

// Send the user along and fetch some data!
header('Location: app.php?accessToken=' . $accessToken . '&refreshToken=' . $refreshToken . '');
die();

?>

And then on to app.php

app.php

<?php
require '../../vendor/autoload.php';
require '../../config/spotify.php';

$accessToken = $_GET['accessToken'];
$refreshToken = $_GET['refreshToken'];

$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET'
);

// Use previously requested tokens fetched from somewhere. A database for example.
if ($accessToken) {
    $session->setAccessToken($accessToken);
    $session->setRefreshToken($refreshToken);
} else {
    // Or request a new access token
    $session->refreshAccessToken($refreshToken);
}

$options = [
    'auto_refresh' => true,
];

$api = new SpotifyWebAPI\SpotifyWebAPI($options, $session);

// You can also call setSession on an existing SpotifyWebAPI instance
$api->setSession($session);

// Call the API as usual
$api->me();

// Remember to grab the tokens afterwards, they might have been updated
$newAccessToken = $session->getAccessToken();
$newRefreshToken = $session->getRefreshToken();

// It's now possible to request data about the currently authenticated user
r($api->me());

// Getting Spotify catalog data is of course also possible
r($api->getTrack('7EjyzZcbLxW7PaaLua9Ksb'));

?>

This is what I don't understand:

  1. The accessToken can expire any time - is that right?
  2. If so - then on every single page on my application, do I have to re-run all of this code each time the page runs:
$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET'
);

// Use previously requested tokens fetched from somewhere. A database for example.
if ($accessToken) {
    $session->setAccessToken($accessToken);
    $session->setRefreshToken($refreshToken);
} else {
    // Or request a new access token
    $session->refreshAccessToken($refreshToken);
}

$options = [
    'auto_refresh' => true,
];

$api = new SpotifyWebAPI\SpotifyWebAPI($options, $session);

// You can also call setSession on an existing SpotifyWebAPI instance
$api->setSession($session);

// Call the API as usual
$api->me();

// Remember to grab the tokens afterwards, they might have been updated
$newAccessToken = $session->getAccessToken();
$newRefreshToken = $session->getRefreshToken();
  • If I do that - do I need to do some checking so that if $newAccessToken <> $accessToken, then I set $accessToken to be the value of $newAccessToken, and the same for the refreshToken? And I need to do that at the top of every page on my application?

Again, thank you very much for your help, I realise I am asking a lot of questions which probably are very basic.

Jim

<!-- gh-comment-id:750473890 --> @ghost commented on GitHub (Dec 23, 2020): Hi Jonathan, Thank you again for your reply. Your docs are excellent and very informative. The thing I am struggling to understand is the refresh route. I have the basic Auth page here from your example: ## auth.php ``` <?php require '../../vendor/autoload.php'; require '../../config/spotify.php'; $session = new SpotifyWebAPI\Session( 'CLIENT_ID', 'CLIENT_SECRET', 'http://localhost/spotify/callback.php' ); $options = [ 'scope' => [ 'playlist-read-private', 'user-read-private', ], ]; header('Location: ' . $session->getAuthorizeUrl($options)); die(); ?> ``` Then moving on to the callback... I'm cheating by passing accessToken and refreshToken by the QueryString for local development, I wouldn't do this later on. One question is - if I stored them in a database, how would they be tied to a unique user record - maybe by storing them against the id value for the user's record, returned from $api-me()? ## callback.php ``` <?php require '../../vendor/autoload.php'; require '../../config/spotify.php'; $session = new SpotifyWebAPI\Session( 'CLIENT_ID', 'CLIENT_SECRET', 'http://localhost/spotify/callback.php' ); // Request a access token using the code from Spotify $session->requestAccessToken($_GET['code']); $accessToken = $session->getAccessToken(); $refreshToken = $session->getRefreshToken(); // Store the access and refresh tokens somewhere. In a database for example. // Send the user along and fetch some data! header('Location: app.php?accessToken=' . $accessToken . '&refreshToken=' . $refreshToken . ''); die(); ?> ``` And then on to app.php ## app.php ``` <?php require '../../vendor/autoload.php'; require '../../config/spotify.php'; $accessToken = $_GET['accessToken']; $refreshToken = $_GET['refreshToken']; $session = new SpotifyWebAPI\Session( 'CLIENT_ID', 'CLIENT_SECRET' ); // Use previously requested tokens fetched from somewhere. A database for example. if ($accessToken) { $session->setAccessToken($accessToken); $session->setRefreshToken($refreshToken); } else { // Or request a new access token $session->refreshAccessToken($refreshToken); } $options = [ 'auto_refresh' => true, ]; $api = new SpotifyWebAPI\SpotifyWebAPI($options, $session); // You can also call setSession on an existing SpotifyWebAPI instance $api->setSession($session); // Call the API as usual $api->me(); // Remember to grab the tokens afterwards, they might have been updated $newAccessToken = $session->getAccessToken(); $newRefreshToken = $session->getRefreshToken(); // It's now possible to request data about the currently authenticated user r($api->me()); // Getting Spotify catalog data is of course also possible r($api->getTrack('7EjyzZcbLxW7PaaLua9Ksb')); ?> ``` This is what I don't understand: 1. The accessToken can expire any time - is that right? 2. If so - then on every single page on my application, do I have to re-run all of this code each time the page runs: ``` $session = new SpotifyWebAPI\Session( 'CLIENT_ID', 'CLIENT_SECRET' ); // Use previously requested tokens fetched from somewhere. A database for example. if ($accessToken) { $session->setAccessToken($accessToken); $session->setRefreshToken($refreshToken); } else { // Or request a new access token $session->refreshAccessToken($refreshToken); } $options = [ 'auto_refresh' => true, ]; $api = new SpotifyWebAPI\SpotifyWebAPI($options, $session); // You can also call setSession on an existing SpotifyWebAPI instance $api->setSession($session); // Call the API as usual $api->me(); // Remember to grab the tokens afterwards, they might have been updated $newAccessToken = $session->getAccessToken(); $newRefreshToken = $session->getRefreshToken(); ``` - If I do that - do I need to do some checking so that if $newAccessToken <> $accessToken, then I set $accessToken to be the value of $newAccessToken, and the same for the refreshToken? And I need to do that at the top of every page on my application? Again, thank you very much for your help, I realise I am asking a lot of questions which probably are very basic. Jim
Author
Owner

@ghost commented on GitHub (Dec 26, 2020):

Hi Jonathan - I think I worked out how to do the refresh thing, putting this at the top of every page of my Spotify application (I was storing the access and refresh tokens as session variables, which seems to work okay for what I need):

if(!isset($_SESSION)) { session_start(); }
if (isset($_SESSION["accessToken"])) { $accessToken = $_SESSION["accessToken"]; }
if (isset($_SESSION["refreshToken"])) { $refreshToken = $_SESSION["refreshToken"]; }

if (!isset($accessToken) || empty($refreshToken)) {
    header('Location: auth.php');
    die();
}

$api = new SpotifyWebAPI\SpotifyWebAPI();

try {
	$user_array = get_object_vars($api->me());
} catch(Exception $e) {
    if ($e->getCode() == 401) {
		
        $session = new SpotifyWebAPI\Session(
			'CLIENT_ID',
			'CLIENT_SECRET'
			'http://localhost/spotify/callback.php'
        );
		
        $session->refreshAccessToken($refreshToken);
		
        $accessToken = $session->getAccessToken();
        $refreshToken = $session->getRefreshToken();
		
        $api->setAccessToken($accessToken);
		
        $_SESSION["accessToken"] = $accessToken;
        $_SESSION["refreshToken"] = $refreshToken;
		
    } else {
        $eMessage = 'Spotify Web API error (code '.$e->getCode().'): '.$e->getMessage()."\n";
        $logFile = fopen("_eee.txt", "a") or die("Log error: unable to open log file.");
        fwrite($logFile, $eMessage);
        fclose($logFile);
        die($eMessage); 
    }
}

I don't think it's probably very pretty but it seems to work okay, I left some sessions in place for a couple of hours and went back and the tokens were refreshed, so I must be doing something sort of right.

Thanks.

<!-- gh-comment-id:751406257 --> @ghost commented on GitHub (Dec 26, 2020): Hi Jonathan - I think I worked out how to do the refresh thing, putting this at the top of every page of my Spotify application (I was storing the access and refresh tokens as session variables, which seems to work okay for what I need): ``` if(!isset($_SESSION)) { session_start(); } if (isset($_SESSION["accessToken"])) { $accessToken = $_SESSION["accessToken"]; } if (isset($_SESSION["refreshToken"])) { $refreshToken = $_SESSION["refreshToken"]; } if (!isset($accessToken) || empty($refreshToken)) { header('Location: auth.php'); die(); } $api = new SpotifyWebAPI\SpotifyWebAPI(); try { $user_array = get_object_vars($api->me()); } catch(Exception $e) { if ($e->getCode() == 401) { $session = new SpotifyWebAPI\Session( 'CLIENT_ID', 'CLIENT_SECRET' 'http://localhost/spotify/callback.php' ); $session->refreshAccessToken($refreshToken); $accessToken = $session->getAccessToken(); $refreshToken = $session->getRefreshToken(); $api->setAccessToken($accessToken); $_SESSION["accessToken"] = $accessToken; $_SESSION["refreshToken"] = $refreshToken; } else { $eMessage = 'Spotify Web API error (code '.$e->getCode().'): '.$e->getMessage()."\n"; $logFile = fopen("_eee.txt", "a") or die("Log error: unable to open log file."); fwrite($logFile, $eMessage); fclose($logFile); die($eMessage); } } ``` I don't think it's probably very pretty but it seems to work okay, I left some sessions in place for a couple of hours and went back and the tokens were refreshed, so I must be doing something sort of right. Thanks.
Author
Owner

@jwilsson commented on GitHub (Dec 28, 2020):

Hey Jim!
Sorry for not getting back to you, I was off for a few days over Christmas.

I'm really glad you got it working! If you have any other questions or issues, don't hesitate to give me a shout.

Cheers,
Jonathan

<!-- gh-comment-id:751737676 --> @jwilsson commented on GitHub (Dec 28, 2020): Hey Jim! Sorry for not getting back to you, I was off for a few days over Christmas. I'm really glad you got it working! If you have any other questions or issues, don't hesitate to give me a shout. Cheers, Jonathan
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/spotify-web-api-php#145
No description provided.