SonataAdminBundle : display non crud (statistics)

sonata-admin, symfony, symfony-2.2

Solution

Since pulzarraider explained us one way to do this I'll explain the other.

The block bundle's way allow to custom the dashboard in a pretty powerful way. You can follow Block bundle doc at the same time

1. Create StatisticsBlockService.php in Copndz\MyBundle\Block\Service

I want to display stats by doing maths with data stored : I need to

- import the EntityManager

- add attribute $em to the service

- add constructor __construct which will call its parent constructor and set $em with EntityManager passed in argument

namespace Copndz\MyBundle\Block\Service;
use Symfony\Component\HttpFoundation\Response;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\BlockBundle\Model\BlockInterface;
use Sonata\BlockBundle\Block\BaseBlockService;
use Doctrine\ORM\EntityManager;

class StatisticsBlockService extends BaseBlockService
{
    private $em;
    
    /**
     * {@inheritdoc}
     */
    public function execute(BlockInterface $block, Response $response = null)
    {
        $settings = array_merge($this->getDefaultSettings(), $block->getSettings());
        
        $myentityrepository = $this->em->getRepository('CopndzMyBundle:MyEntity');
        $myentity = $myentityrepository->find('5');
        
        return $this->renderResponse('CopndzMyBundle:Block:block_statistics.html.twig', array(
            'block'     => $block,
            'settings'  => $settings,
            'myentity' => $myentity,   
        ), $response);
    }

    /**
     * {@inheritdoc}
     */
    public function validateBlock(ErrorElement $errorElement, BlockInterface $block)
    {
        // TODO: Implement validateBlock() method.
    }

    /**
     * {@inheritdoc}
     */
    public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
    {
        $formMapper->add('settings', 'sonata_type_immutable_array', array(
            'keys' => array(
                array('content', 'textarea', array()),
            )
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'Text (core)';
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultSettings()
    {
        return array(
            'content' => 'Insert your custom content here',
        );
    }
    
    public function __construct($name, $templating, EntityManager $entityManager)
    {
            parent::__construct($name, $templating);
            $this->em = $entityManager;
    }
}

2. Create the service in MyBundle\Ressources\config\services.yml

 sonata.block.service.statistics:
      class: Copndz\MyBundle\Block\Service\StatisticsBlockService
      tags:
        - { name: sonata.block }
      arguments:
        - "sonata.block.service.statistics"
        - @templating
        - @doctrine.orm.entity_manager

3. Add this service to sonata_block in my config.yml

sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts:   [admin]

        sonata.block.service.text:
        sonata.block.service.rss:
        sonata.block.service.statistics:

4. Create the template block_statistics.html.twig in Copndz\MyBundle\Ressources\views\Block

{% extends sonata_block.templates.block_base %}

{% block block %}
    {{ myentity.name }}
{% endblock %}

5. And finally call the service in the admin bundle configuration in config.yml

sonata_admin:
    dashboard:
        blocks:
            # display a dashboard block
            - { position: left, type: sonata.admin.block.admin_list }
            - { position: right, type: sonata.block.service.statistics }

Problem

I'm using sonata admin bundle to generate my backend, I'm so happy with it that I would like to use my backend to display statistics as well. I guess I can do that by tweaking bundle's views, "standard_layout.html.twig" maybe. Problem is, I can't find examples or even people speaking about it, so I'm wondering, is that possible ? Aren't people speaking about it because it's too simple ? Did you do it ? I really would like to have a single backend, so pls enlighten me ! Thank you, copndz

Original source