How to install Polr Admin in Symfony with the Sonata Admin bundle

The news aggregator Africa News Hub uses two instances of URL shortener, one for outgoing links to referenced sites, and another for incoming links included in messages posted on social networks. Polr, which defines itself as a modern and robust URL shortener, is used on both instances.

By default, having two Polr instances means there are two backends to manage, one for each intance. The Polr Admin package was created to make it simple to deal with multiple Polr instances.

Polr Admin is a package that allows you to manage multiple Polr instances from a single location. It is not a standalone application, but an extension to be installed on a running PHP application. The authentication and authorization functions are left to the application, and thus will not be discussed in this article.

The Polr Admin interface is displayed in a single web page, and uses Ajax to update its content. The Ajax function is implemented with the Jaxon library, which converts PHP classes into Javascript classes, so that they can be called directly from the browser.

This article describes the installation of Polr Admin with the Sonata Admin bundle, a package that allows you to create backends for the Symfony framework. For Africa News Hub, Polr Admin is integrated into a Laravel backend. Symfony was chosen for this article to show how, thanks to the Jaxon library, Polr Admin can be installed on other PHP frameworks.

The Polr Restful API

The Polr Admin package interacts with the Polr instances that it manages using the Polr API package, which wraps the Polr functions into a Restful API. It is therefore required to install Polr API on each instance of Polr to manage.

The Polr API package installs with Composer.

composer require lagdo/polr-api ~0.1

Then, you have to declare the package in the `bootstrap/app.php` file.


Once the Polr API package is installed, you must create an API key for a user on each instance of Polr. From here, it is possible to get access to Polr with an API testing tool like Postman.

We will now install Polr Admin on a different host. The next two sections describe how to install Symfony and the Sonata Admin bundle.

Symfony installation

We will begin by installing Symfony version 3.3, following the instructions given at

curl -LsS -o ~/bin/symfony
chmod a+x ~/bin/symfony
symfony new polr-admin 3.3

When the installation is complete, move into the Symfony directory and start the embedded web server.

cd polr-admin
php bin/console server:run

By browsing the address at http://localhost:8000/, you can see the above page, showing that the installation was successful.

Symfony Home
Symfony Home

The Sonata Admin bundle installation

The Sonata Admin bundle installs with Composer.

composer require sonata-project/admin-bundle

When the installation is complete, edit the app/AppKernel.php file to declare the Sonata bundles.

// ...
class AppKernel extends Kernel
    public function registerBundles()
        $bundles = [
            // ...

            // These are the bundles the SonataAdminBundle relies on
            new Sonata\CoreBundle\SonataCoreBundle(),
            new Sonata\BlockBundle\SonataBlockBundle(),
            new Knp\Bundle\MenuBundle\KnpMenuBundle(),

            // And finally, the storage and SonataAdminBundle
            new Sonata\AdminBundle\SonataAdminBundle(),

        // ...

    // ...

Then, configure the translations and the Sonata bundle in the app/config/config.yml file.

    translator: { fallbacks: [en] }

# ...

    default_contexts: [cms]
        # enable the SonataAdminBundle block
            contexts: [admin]

Now add the Sonata bundle routes in the app/config/routing.yml file.

    resource: "@SonataAdminBundle/Resources/config/routing/sonata_admin.xml"
    prefix: /admin

Finally, run the following commands.

$ php bin/console cache:clear
$ php bin/console assets:install

The Sonata Admin bundle is now installed. The link http://localhost:8000/admin shows its homepage, which is empty for now.

Sonata Admin Home
Sonata Admin Home

Jaxon and Polr Admin installation

The jaxon-php/jaxon-symfony package that provides the Jaxon functions in a Symfony application can now be installed.
The views of the Polr Admin package use the Blade template engine, which requires the jaxon-php/jaxon-blade package to be installed.

$ composer require jaxon-php/jaxon-symfony ~2.0
$ composer require jaxon-php/jaxon-blade
$ composer require lagdo/polr-admin

When the installation is complete, declare the Jaxon bundle in the app/AppKernel.php file.

$bundles = array(
    new Jaxon\AjaxBundle\JaxonAjaxBundle(),

Configure the Jaxon bundle in the app/config/config.yml file.

    - { resource: jaxon.yml }
    - { resource: "@JaxonAjaxBundle/Resources/config/services.yml" }

Create the app/config/jaxon.yml file with the following content. It’s the Jaxon configuration.

                uri:     "ajax"
                class:   ""
                extern:  false
                minify: false
                    modal: bootbox
                    alert: noty
                    confirm: noty

In this configuration, the jaxon.lib.core.request.uri parameter indicates that Ajax requests will be sent to the URL /ajax. The parameters in the jaxon.lib.core.js section indicate that Jaxon’s Javascript code will be inserted directly into the web page, and the parameters in the jaxon.lib.dialogs section indicate that the modal windows will use the Bootbox library, while Alert and confirmation messages will use the Noty library. The corresponding files will be automatically loaded into the page by Jaxon.

Then define the following two routes in the app/config/routing.yml file.

    path: /polr
    defaults: { _controller: AppBundle:Polr:index }

    path: /ajax
    defaults: { _controller: AppBundle:Polr:jaxon }
    methods: [POST]

The first route is linked to the PolrController::indexAction() function, which prints the dashboard home page. The second one is linked to the PolrController::jaxonAction() function, which will process Jaxon’s Ajax requests.

This is the controller code, to be saved in the src/AppBundle/Controller/PolrController.php file.


namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class PolrController extends Controller
    private $jaxon;
    private $polr;

    protected function getJaxon()
        $this->jaxon = $this->get('jaxon.ajax');
        $this->polr = $this->jaxon->package('polr.admin');
        $this->polr->config($this->get('kernel')->getProjectDir() . '/app/config/polradmin.yml');

     * Show the Polr Admin page.
     * @return void
    public function indexAction()
        return $this->render('polr.html.twig', [
            'jaxon' => $this->jaxon,
            'polr' => $this->polr,
            'pageTitle' => "Symfony Framework",

     * Process a Jaxon request.
     * @return void
    public function jaxonAction()
        // Process the Jaxon request

The PolrController::indexAction() function prints the app/Resources/views/polr.html.twig template, whose content follows.

{% extends '@SonataAdmin/standard_layout.html.twig' %}

{% block stylesheets %}
{{ parent() }}

{{ jaxon.css()|raw }}
{{ polr.css()|raw }}
{% endblock %}

{% block javascripts %}
{{ parent() }}

{{ jaxon.js()|raw }}
{{ jaxon.script()|raw }}
{{ polr.js()|raw }}

$(document).ready(function() {
    {{ polr.ready()|raw }}

{% endblock %}

{% block page_title 'Welcome to the PolrAdmin Demo application' %}

{% block content_title 'Polr Admin Dashboard' %}

{% block body_id 'polr-admin' %}

{% block body_class 'list' %}

{% block sonata_admin_content %}
{{ parent() }}

{{ polr.html()|raw }}

{% endblock %}

The Jaxon and Polr Admin packages are now installed.
The last step is to declare the instances of Polr to manage. This is done in the app/config/polradmin.yml file, as in the following example.

default: first
        name: First Polr Instance
        url: http://first.domain.tld
        api: api/v2
        key: 012365478978965412300321456987
        name: Second Polr Instance
        url: http://second.domain.tld
        api: api/v2
        key: 987456321003214569879874563210

In this configuration, the default parameter indicates the instance on which Polr Admin will connect by default, and the endpoints section contains the list of instances.

The Polr Admin is now installed and configured, and can be accessed at http://localhost:8000/polr. Here’s the homepage.

The Settings tab displays a drop-down list where the user can choose the current Polr instance.

The other tabs display the data of the current instance: the user’s list of links, the list of all links, the list of users, and the link access statistics.

The user links
All the llinks
All the llinks
The users list
The users list

The code for this article is online at this address: