Integrate SyliusSettingsBundle with SonataAdminBundle

Написана 13 Августа, 2015 в 19:45. Автор: borN_free   |   Теги: settings, sonata, bundle, admin Комментарии 0

Sonata is a great project that allows to build a rich Admin Dashboard. However, there is no integrated settings functionality in SonataAdminBundle.

Let's integrate an awesome SyliusSettingsBundle with Sonata's Admin Dashboard.

I assuming that you already have SonataAdminBundle installed. Let's install SyliusSettingsBundle.

Please see detailed installation procces in bundle's documentation (5 minutes to install):

SonataAdmin and SyliusSettingsBundle

Here is a structure of our AdminBundle where we will implement settings:

SonataAdmin and SyliusSettingsBundle - structure

Lets create our settings class. This file is used to generate settings form (see SyliusSettingsBundle's documentation):

namespace App\CoreBundle\Settings;

use Sylius\Bundle\SettingsBundle\Schema\SchemaInterface;
use Sylius\Bundle\SettingsBundle\Schema\SettingsBuilderInterface;
use Symfony\Component\Form\FormBuilderInterface;

class AdminSettingsSchema implements SchemaInterface
{
    /**
     * @param SettingsBuilderInterface $builder
     */
    public function buildSettings(SettingsBuilderInterface $builder)
    {
        $builder
            ->setDefaults(
                [
                    'questions_per_quiz' => '80',
                    'questions_duration' => '8',
                    'question_time_limit' => '30',
                    'product_id' => '',
                    'contact_email' => '',
                ]
            )
            ->setAllowedTypes(
                [
                    'questions_per_quiz' => ['string'],
                    'questions_duration' => ['string'],
                    'question_time_limit' => ['string'],
                    'product_id' => ['string'],
                    'contact_email' => ['string'],
                ]
            );
    }

    /**
     * @param FormBuilderInterface $builder
     */
    public function buildForm(FormBuilderInterface $builder)
    {
        $builder
            ->add('questions_per_quiz')
            ->add('questions_duration')
            ->add('question_time_limit')
            ->add('product_id')
            ->add('contact_email', 'email')
        ;
    }
}

and service for it:

# src/CoreBundle/Resources/config/services.yml
services:
    app_core.settings_schema.meta:
        class: App\CoreBundle\Settings\AdminSettingsSchema
        tags:
            - { name: "sylius.settings_schema", namespace: "default" }

Then we create our Sonata's admin class:

namespace Application\Sonata\AdminBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Route\RouteCollection;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AdminInterface;

class SettingsAdmin extends Admin
{
    /**
     * @var string
     */
    protected $baseRouteName = 'sonata_setting';

    /**
     * @var string
     */
    protected $baseRoutePattern = '/';

    /**
     * @var string
     */
    protected $translationDomain = 'SettingsAdmin';

    /**
     * @param RouteCollection $collection
     */
    protected function configureRoutes(RouteCollection $collection)
    {
        $collection->clear();
        $collection->add('update', '/settings');
        $collection->add(
            'list',
            '/settings',
            [
                '_controller' => 'Sylius\Bundle\SettingsBundle\Controller\SettingsController::updateAction',
                'namespace' => 'default'
            ]
        );
    }
}

Here we create only two routes:

  • update route: /settings URL will be used to open and update our settings form. Full URL will be: http://test.com/admin/settings
  • list route: this route is used to display Settings menu item on the sidebar. Without this route it will not be displayed. We just override controller and path here to use the same action as in the 'update' route.

We should also create a service for our admin class:

# src/Application/Sonata/AdminBundle/Resources/config/services.yml
quizzle_core.admin.settings:
        class: Application\Sonata\AdminBundle\Admin\SettingsAdmin
        arguments: [~, Sylius\Bundle\SettingsBundle\Model\Parameter, ApplicationSonataAdminBundle:SettingsAdmin]
        tags:
            - { name: sonata.admin, manager_type: orm, group: Settings, show_in_dashboard: true, label: Settings, label_translator_strategy: sonata.admin.label.strategy.underscore }
        calls:
            - [setFormTheme, [[SonataPageBundle:Form:form_admin_fields.html.twig, SonataDoctrineORMAdminBundle:Form:form_admin_fields.html.twig]]]

Create an admin controller:

namespace Application\Sonata\AdminBundle\Controller;

use Sonata\AdminBundle\Controller\CRUDController;
use Sylius\Bundle\SettingsBundle\Controller\SettingsController;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Internal\Hydration\IterableResult;

/**
 * Class SettingsAdminController
 * @package Application\Sonata\AdminBundle\Controller
 */
class SettingsAdminController extends SettingsController
{
    /**
     * @param Request $request
     * @param string $namespace
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function updateAction(Request $request, $namespace = 'default')
    {
        $manager = $this->getSettingsManager();
        $settings = $manager->loadSettings($namespace);

        $form = $this
            ->getSettingsFormFactory()
            ->create($namespace)
        ;

        $form->setData($settings);

        if ($request->isMethod('POST') && $form->bind($request)->isValid()) {
            $manager->saveSettings($namespace, $form->getData());

            $message = $this->getTranslator()->trans('updated_successful', array(), 'SettingsAdmin');
            $this->get('session')->getFlashBag()->add('sonata_flash_success', $message);

            return $this->redirect($request->headers->get('referer'));
        }

        $admin_pool = $this->get('sonata.admin.pool');

        return $this->render('ApplicationSonataAdminBundle:Admin:settings.html.twig', array(
                'settings' => $settings,
                'form'     => $form->createView(),
                'admin_pool' => $admin_pool,
            ));
    }
}

Pretty straightforward code - load settings, create form and if form is submitted and is valid - add a flash message. The last file is a template to display our settings form:

{% extends 'SonataAdminBundle::standard_layout.html.twig' %}

{% form_theme form 'SonataAdminBundle:Form:form_admin_fields.html.twig' %}

{% block content %}
    

{{ 'dashboard.settings'|trans({}, 'SettingsAdmin') }}

{{ form_widget(form) }}
{% endblock %}

Enjoy!

Оставьте свой комментарий:

Поля с * обязательны.