This example will help you create custom Sonata Admin page and also explain how to make a statistics admin.
You can read more here
<div id="cms-block-{{ block.id }}" class="cms-block cms-block-element col-md-3"> | |
<div class="small-box {{ settings.css_class }}"> | |
<div class="inner"> | |
<h3>{{ count }}</h3> | |
<p>{{ settings.title }}</p> | |
</div> | |
<div class="icon"> | |
<i class="fa {{ settings.icon }}"></i> | |
</div> | |
</div> | |
</div> |
#app/config/config.yml | |
sonata_block: | |
default_contexts: [cms] | |
blocks: | |
# enable the SonataAdminBundle block | |
sonata.admin.block.admin_list: | |
contexts: [admin] | |
sonata.admin.block.search_result: | |
contexts: [admin] | |
admin.block.service.stats: ~ |
#app/config/services.yml | |
services: | |
bundle.admin.stats: | |
class: YourBundle\Admin\StatsAdmin | |
arguments: [~, ~, AdminBundle:StatsCRUD] | |
tags: | |
- { name: sonata.admin, manager_type: orm, label: Stats, group: Stats, on_top: true, icon: '<i class="fa fa-bar-chart"></i>' } | |
admin.block.service.stats: | |
class: YourBundle\Block\Service\StatsBlockService | |
arguments: ["admin.block.service.stats", "@templating", "@doctrine.orm.entity_manager"] | |
public: true | |
tags: | |
- {name: "sonata.block"} |
{% extends 'SonataAdminBundle::standard_layout.html.twig' %} | |
{% block content %} | |
<div class="row"> | |
{{ sonata_block_render({ 'type': 'admin.block.service.stats' }, { | |
'entity' : 'AppBundle:User', | |
'repository_method' : 'findNumberofAllUsers', | |
'title' : 'Users', | |
'css_class' : 'bg-gray-active', | |
'icon' : 'fa-users' | |
}) }} | |
{{ sonata_block_render({ 'type': 'admin.block.service.stats' }, { | |
'entity' : 'AppBundle:Delivery', | |
'repository_method' : 'findAllDeliversInProgress', | |
'title' : 'Deliveries in Progress', | |
'css_class' : 'bg-yellow', | |
'icon' : 'fa-truck' | |
}) }} | |
{{ sonata_block_render({ 'type': 'admin.block.service.stats' }, { | |
'entity' : 'AppBundle:Delivery', | |
'repository_method' : 'findAllFailedDelivers', | |
'title' : 'Failed Deliveries', | |
'css_class' : 'bg-red', | |
'icon' : 'fa-truck' | |
}) }} | |
</div> | |
{% endblock %} |
<?php | |
namespace YourBundle\Admin; | |
use Sonata\AdminBundle\Admin\AbstractAdmin; | |
use Sonata\AdminBundle\Route\RouteCollection; | |
class StatsAdmin extends AbstractAdmin | |
{ | |
protected $baseRoutePattern = 'stats'; | |
protected $baseRouteName = 'stats'; | |
protected function configureRoutes(RouteCollection $collection) | |
{ | |
$collection->clearExcept(['list']); | |
} | |
} |
<?php | |
namespace YourBundle\Block\Service; | |
use Doctrine\ORM\EntityManagerInterface; | |
use Sonata\AdminBundle\Form\FormMapper; | |
use Sonata\CoreBundle\Validator\ErrorElement; | |
use Sonata\BlockBundle\Block\Service\AbstractBlockService; | |
use Sonata\BlockBundle\Block\BlockContextInterface; | |
use Sonata\BlockBundle\Model\BlockInterface; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\OptionsResolver\OptionsResolver; | |
use Symfony\Bundle\TwigBundle\TwigEngine; | |
class StatsBlockService extends AbstractBlockService | |
{ | |
private $entityManager; | |
public function __construct(string $serviceId, TwigEngine $templating, EntityManagerInterface $entityManager) | |
{ | |
$this->entityManager = $entityManager; | |
parent::__construct($serviceId, $templating); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getName() | |
{ | |
return 'Stats Block'; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function configureSettings(OptionsResolver $resolver) | |
{ | |
$resolver->setDefaults(array( | |
'entity' => 'Add Entity', | |
'repository_method' => 'findAll', | |
'title' => 'Insert block Title', | |
'css_class' => 'bg-blue', | |
'icon' => 'fa-users', | |
'template' => 'YourBundle:Block:block_stats.html.twig', | |
)); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function buildEditForm(FormMapper $formMapper, BlockInterface $block) | |
{ | |
$formMapper->add('settings', 'sonata_type_immutable_array', array( | |
'keys' => array( | |
array('entity', 'text', array('required' => false)), | |
array('repository_method', 'text', array('required' => false)), | |
array('title', 'text', array('required' => false)), | |
array('css_class', 'text', array('required' => false)), | |
array('icon', 'text', array('required' => false)), | |
), | |
)); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function validateBlock(ErrorElement $errorElement, BlockInterface $block) | |
{ | |
$errorElement | |
->with('settings[entity]') | |
->assertNotNull(array()) | |
->assertNotBlank() | |
->end() | |
->with('settings[repository_method]') | |
->assertNotNull(array()) | |
->assertNotBlank() | |
->end() | |
->with('settings[title]') | |
->assertNotNull(array()) | |
->assertNotBlank() | |
->assertMaxLength(array('limit' => 50)) | |
->end() | |
->with('settings[css_class]') | |
->assertNotNull(array()) | |
->assertNotBlank() | |
->end() | |
->with('settings[icon]') | |
->assertNotNull(array()) | |
->assertNotBlank() | |
->end(); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function execute(BlockContextInterface $blockContext, Response $response = null) | |
{ | |
$settings = $blockContext->getSettings(); | |
$entity = $settings['entity']; | |
$method = $settings['repository_method']; | |
$rows = $this->entityManager->getRepository($entity)->$method(); | |
return $this->templating->renderResponse($blockContext->getTemplate(), array( | |
'count' => $rows, | |
'block' => $blockContext->getBlock(), | |
'settings' => $settings, | |
), $response); | |
} | |
} |
<?php | |
namespace YourBundle\Controller; | |
use Sonata\AdminBundle\Controller\CRUDController; | |
class StatsCRUDController extends CRUDController | |
{ | |
public function listAction() | |
{ | |
return $this->render('YourBundle::stats.html.twig'); | |
} | |
} |
Missing the closing curly bracket on StatsBlockService.php