Using Spotify Web Api with Symfony4 Flex

Oct. 2018 (en) Symfony 4 Symfony Flex PHP

Albert Serra

1. Setup a Symfony Flex project

2. Setup Spotify app

3. Requirements

4. Templating

# templates/base.twig.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.css">

        {% block stylesheets %}{% endblock %}
    </head>
    <body>
        {% block body %}
        {% block header %}
        <header>
        </header>
        {% endblock %}
        <main>
            {% block content %}
            {% endblock %}
        </main>
        {% endblock %}
        {% block footer %}
        <footer>
        </footer>
        {% endblock %}
        <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.js"></script>
        {% block javascripts %}{% endblock %}
    </body>
</html>

5. Controller (and templates)

5.1. Constructor

  // src/Controller/AuthController
    private $spotifyParams;
    private $spotify; 

    public function __construct()
    {
        $this->spotifyParams = [
            'client_id' => 'e4e6d0a8791448eebxxxxxxxxxxxxx',
            'client_secret' => '14b342672e7447axxxxxxxxxxxxx',
            'scope' => ['user-read-email','user-read-private','playlist-read-private',
                         'playlist-read-collaborative','playlist-modify-public',
                         'playlist-modify-private','user-follow-read','user-follow-modify']
        ];

        $this->spotify = new SpotifyWebAPI\Session(
            $this->spotifyParams['client_id'],
            $this->spotifyParams['client_secret'],
            'http://127.0.0.1:8000/login/oauth'
        );

    }

5.2. Login

// src/Controller/AuthController
    /**
     * @Route("/login", name="login")
     */
    public function login( SessionInterface $session )
    {

        $options = [
            'scope' => $this->spotifyParams['scope']
        ];

        $spotify_auth_url = $this->spotify->getAuthorizeUrl($options);

        return $this->render('auth/login.html.twig', array(
            'spotify_auth_url' => $spotify_auth_url

        ));
    }
    # templates/auth/login.twig.html

    {% extends "base.html.twig" %}

    {% block body %}
    <style type="text/css">
        body { background-color: #DADADA; }
        body > .grid { height: 100%; }
        .column { max-width: 450px; }
      </style>

    <div class="ui middle aligned center aligned grid">
      <div class="column">
        <h2 class="ui teal image header">
          <div class="content">
            Log-in to your account
          </div>
        </h2>
        <form class="ui large form">
          <div class="ui stacked segment">
            <a href="{{ spotify_auth_url }}" class="ui fluid large teal submit button"><i class="spotify icon"></i> Login by Spotify</a>
          </div>

          {% for flashMessage in app.session.flashbag.get('error') %}
          <div class="ui error message">{{ flashMessage }}</div>
          {% endfor %}

          {% for flashMessage in app.session.flashbag.get('success') %}
          <div class="ui error message">{{ flashMessage }}</div>
          {% endfor %}

        </form> 
      </div>
    </div>
    {% endblock %}

Capture Spotify Login

5.3. OAuth

// src/Controller/AuthController

    /**
     * @Route("/login/oauth", name="oauth")
     */
    public function oauth(Request $request, SessionInterface $session) 
    {

        $accessCode = $request->get('code');
        $session->set('accessCode', $accessCode); // symfony session

        $this->spotify->requestAccessToken($accessCode);
        $accessToken = $this->spotify->getAccessToken();
        $session->set('accessToken', $accessToken); // symfony session

        return $this->redirectToRoute('profile');
    }

5.4. Profile

// src/Controller/AuthController

    /**
     * @Route("/profile", name="profile")
     */
    public function profile(Request $request, SessionInterface $session )
    {
        $accessToken = $session->get('accessToken');
        if( ! $accessToken ) {
            $session->getFlashBag()->add('error', 'Invalid authorization');
            $this->redirectToRoute('login');
        }

        $api = new SpotifyWebAPI\SpotifyWebAPI();
        $api->setAccessToken($accessToken);

        $me = $api->me();

        return $this->render('auth/profile.html.twig', array(
            'me' => $me
        ));
    }
# templates/auth/profile.html.twig

{% extends "base.html.twig" %}

{% block content %}

<div class="ui container">
  <h1>Profile</h1>
  <div class="ui cards">
    <div class="ui raised card">
      <div class="content">
        <div class="header">{{ me.display_name }}</div>
        <div class="meta">
          <span class="right floated time">
            <a href="{{ me.external_urls.spotify }}" target="_blank"><i class="linkify icon"></i></a>
          </span>
          <span class="category">{{ me.id }}</span>
        </div>
        <div class="description">
          {{ me.product }}
        </div>
      </div>
      <div class="extra content">
        <i class="check icon"></i>
        {{ me.followers.total }} Followers
      </div>
    </div>
  </div>

  <a href="{{ path('logout') }}" class="ui red button right floated"><i class="power icon"></i> Logout</a>

  <pre><code>
    {{ dump(me) }}
  </code></pre>
</div>

{% endblock %}

Capture Spotify Login

5.5. Logout

// src/Controller/AuthController

    /**
     * @Route("/logout", name="logout")
     */
    public function logout( SessionInterface $session )
    {
        $session->clear();
        $session->getFlashBag()->add('success', 'You have successfully logged out');

        return $this->redirectToRoute('login');
    }

6. Entire Controller

// src/Controller/AuthController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

use SpotifyWebAPI;

class AuthController extends AbstractController
{

    private $spotifyParams;
    private $spotify; 

    public function __construct()
    {
        $this->spotifyParams = [
            'client_id' => 'e4e6d0a8791448eebb643e4ec22d0e89',
            'client_secret' => '14b342672e7447a19b03f03c79a11bb8',
            'scope' => ['user-read-email','user-read-private','playlist-read-private',
                         'playlist-read-collaborative','playlist-modify-public',
                         'playlist-modify-private','user-follow-read','user-follow-modify']
        ];

        $this->spotify = new SpotifyWebAPI\Session(
            $this->spotifyParams['client_id'],
            $this->spotifyParams['client_secret'],
            'http://127.0.0.1:8000/login/oauth'
        );

    }

    /**
     * @Route("/login", name="login")
     */
    public function login( SessionInterface $session )
    {

        $options = [
            'scope' => $this->spotifyParams['scope']
        ];

        $spotify_auth_url = $this->spotify->getAuthorizeUrl($options);

        return $this->render('auth/login.html.twig', array(
            'spotify_auth_url' => $spotify_auth_url

        ));
    }

    /**
     * @Route("/login/oauth", name="oauth")
     */
    public function oauth(Request $request, SessionInterface $session) 
    {

        $accessCode = $request->get('code');
        $session->set('accessCode', $accessCode); // symfony session

        $this->spotify->requestAccessToken($accessCode);
        $accessToken = $this->spotify->getAccessToken();
        $session->set('accessToken', $accessToken); // symfony session

        return $this->redirectToRoute('profile');
    }

    /**
     * @Route("/profile", name="profile")
     */
    public function profile(Request $request, SessionInterface $session )
    {
        $accessToken = $session->get('accessToken');
        if( ! $accessToken ) {
            $session->getFlashBag()->add('error', 'Invalid authorization');
            $this->redirectToRoute('login');
        }

        $api = new SpotifyWebAPI\SpotifyWebAPI();
        $api->setAccessToken($accessToken);

        $me = $api->me();

        return $this->render('auth/profile.html.twig', array(
            'me' => $me
        ));
    }

    /**
     * @Route("/logout", name="logout")
     */
    public function logout( SessionInterface $session )
    {
        $session->clear();
        $session->getFlashBag()->add('success', 'You have successfully logged out');

        return $this->redirectToRoute('login');
    }

}

?>

7. Thanks to

EOF