Search code examples
phpsymfonysonata-admin

Getting instance of container in custom sonata block


I am creating a custom block for dashboard and where I want to display information persisted into the DB. How do I get an instance of the container or doctrine entity manager in the block service?

Tried googling alot but nothing substantial has come out so far


Solution

  • When you create a new block in sonata, you have to declare it like a service, so you can inject doctrine.orm.entity_manager. I can show you an example of a block where I injected the entity manager:

    //My\Bundle\Block\MyBlockService
    
    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 Sonata\BlockBundle\Block\BlockContextInterface;
    
    class MyBlockService extends BaseBlockService
    {
        protected $em;
    
        public function __construct($type, $templating, $em)
        {
            $this->type = $type;
            $this->templating = $templating;
            $this->em = $em;
        }
    
        public function getName()
        {
            return 'MyBlock';
        }
    
        public function getDefaultSettings()
        {
            return array();
        }
    
        public function validateBlock(ErrorElement $errorElement, BlockInterface $block)
        {
        }
    
        public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
        {
        }
    
        public function execute(BlockContextInterface $blockContext, Response $response = null)
        {
            $settings = array_merge($this->getDefaultSettings(), $blockContext->getBlock()->getSettings());
    
            $data = count($this->em->getRepository("MyBundle:Entity")->findAll());
    
            return $this->renderResponse('MyBundle::myblock.html.twig', array(
                'block' => $blockContext->getBlock(),
                'settings' => $settings,
                'data' => $data,
            ), $response);
        }
    }
    

    Declare you block in services.yml and inject whatever you need:

    //services.yml
    sonata.block.service.myblock:
            class: My\Bundle\Block\MyBlockService
            arguments: [ "sonata.block.service.myblock", @templating, @doctrine.orm.entity_manager ]
            tags:
                - { name: sonata.block }
    

    Declare you block in config.yml: //config.yml

    sonata_block:
        default_contexts: [cms]
        blocks:
        # Enable the SonataAdminBundle block
        sonata.admin.block.admin_list:
            contexts:   [admin]
        sonata.block.service.myblock: ~
    

    And then, of course, you have to create the template for block:

    {# myblock.html.twig #}
    {% extends 'SonataBlockBundle:Block:block_base.html.twig' %}
    
    
    {% block block %}
       <p>{{ data }}</p>
    {% endblock %}