Le interfacce tramite déle faut de Sonata sono dei CRUD. Il che è estremamente pratico (altrimenti non lo’non userei). Ma un'amministrazione n’non è composto soltantoée di CRUD.
Qui vedremo come si può fare una pagina di’esportazione di datiée di manière semplice, eliminando le viste per déservono delle interfacce, e in créprima la nostra per gépremere il nostro pulsante d’esportare.
1 –Aggiunta della libreria d’esportare
composer require sonata-project/exporter
Dobbiamo poi aggiungere un file di configurazione per il nostro esportatore.
#config/packages/sonata_exporter.yml
sonata_exporter:
writers:
csv:
delimiter: ";"
2 –Créazione del nostro controller
Noi andiamo a créper il nostro controller che conterrà la nostra configurazione di base.
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface as RoutingUrlGeneratorInterface;
use Sonata\FormatterBundle\Form\Type\SimpleFormatterType;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\RouteCollection;
class ExportModuleAdmin extends AbstractAdmin
{
public function __construct( $code, $class, $baseControllerName ) {
parent::__construct( $code, $class, $baseControllerName );
}
public function configure()
{
parent::configure();
}
}
Poi dobbiamo creareéper le nostre azioni:
Stiamo eliminando tutte le nostre strade, ci créabbiamo una route export-module per la nostra pagina.
protected function configureRoutes(RouteCollection $collection)
{
$collection->clearExcept(['export-module']);
$collection->remove('create');
$collection->add('export-module');
}
Dobbiamo quindi registrare la nostra interfaccia nei servizi
admin.export:
class: App\Admin\ExportModuleAdmin
arguments: [~, App\Entity\Export, App\Admin\CustomAction]
tags:
- { name: sonata.admin, manager_type: orm, label: "Export CSV" , label_translator_strategy: sonata.admin.label.strategy.underscore, label_catalogue: default}
public: true
Come potete notare il nostro terzoèIl mio argomento è un controller admin aggiuntivo, che andrà gérer le nostre azioni (src/Admin/CustomAction.php).
E c’è direttamente dentro l’azione che stiamo peréfinire la vista che useremo per aggiungere il nostro pulsante.
Noi crédunque una mémetodo exportModuleAction() che contiene il nostro référenceàil nostro modello.
<?php
namespace App\Admin;
use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\Query\ResultSetMapping;
class CustomAction extends CRUDController
{
public function exportDelefAction(){
return $this->renderWithExtraParams('Admin/export.html.twig', array(
'action' => 'export',
'elements' => $this->admin->getShow(),
), null);
}
}
E il nostro file twig che si trova in questa struttura templates/Admin/export.html.twig contiene il nostro codice, molto semplice, con un link per rétazzaérer l’esportare.
Il collegamento è solo la strada di’esporta d’un'interfaccia di’admin CRUD qui contient en argument le format souhaitéé (csv).
La funzione di’export è una funzione automatica delle interfacce CRUD.
{% extends '@SonataAdmin/standard_layout.html.twig' %}
{% block sonata_admin_content %}
{% include 'SonataCoreBundle:FlashMessage:render.html.twig' %}
<div>
<h2 class="title-border">Export CSV</h2>
<div class="box box-primary">
<div class="box-body">
<ul class="menu list-unstyled mb-0">
<li><a class="btn-link" href="{{ path('admin_app_wdeclar_export', {'format' : 'csv'}) }}">Cliquez ici pour télécharger le fichier csv</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
Affinché la nostra azione sia disponibile direttamente dalla dashboard, dobbiamo iscrivere l’azione nel file sonata_admin.yml
E per véverificare la strada che dobbiamo segnalare, ci basta’utilizzare il comando :
php bin/console debug:router
Una volta ripérée noi lo’usiamo come URL di’accès àil nostro pulsante d’esporta nel menu.
#config/packages/sonata_admin.yaml
sonata_admin:
title: 'Sonata Admin'
dashboard:
blocks:
- { type: sonata.admin.block.admin_list, position: left }
groups:
delef.admin.group.contrats:
label: Gestion des contrats
icon: '<i class="fa fa-cogs "></i>'
items:
- route: admin_app_export_export-module
label: "Export CSV"
Ma questo non’non è tutto. Dobbiamo poi configurare il nostro pulsante sulla dashboard. Aggiungeremo la méthode getDashboardActions().
Vi aggiungiamo la nostra azione e la classe CSS di l’icôche vogliamo usare. Qui si usa una icôin fontawsome 5 che abbiamo aggiuntoé àil nostro progetto.
public function getDashboardActions()
{
$actions = parent::getDashboardActions();
$actions['import'] = [
'label' => 'Export',
'url' => $this->generateUrl('export-delef'),
'icon' => ' fas fa-file-export',
'translation_domain' => 'SonataAdminBundle', // optional
'template' => '@SonataAdmin/CRUD/dashboard__action.html.twig', // optional
];
return $actions;
}
Questo ci dà il seguente file php :
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface as RoutingUrlGeneratorInterface;
use Sonata\FormatterBundle\Form\Type\SimpleFormatterType;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\RouteCollection;
class ExportModuleAdmin extends AbstractAdmin
{
public function __construct( $code, $class, $baseControllerName ) {
parent::__construct( $code, $class, $baseControllerName );
}
public function configure()
{
parent::configure();
}
protected function configureRoutes(RouteCollection $collection)
{
//$collection->clearExcept(['list']);
$collection->clearExcept(['export-delef']);
$collection->remove('create');
$collection->add('export-delef');
}
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
public function getDashboardActions()
{
$actions = parent::getDashboardActions();
$actions['import'] = [
'label' => 'Export',
'url' => $this->generateUrl('export-delef'),
'icon' => ' fas fa-file-export',
'translation_domain' => 'SonataAdminBundle', // optional
'template' => '@SonataAdmin/CRUD/dashboard__action.html.twig', // optional
];
return $actions;
}
}
A questo punto abbiamo il nostro accès dal cruscotto :
E la nostra pagina di télécaricamento :
3 –Configurazione di l’esporta
Ci manca solo la configurazione della nostra esportazione.
Abbiamo visto più sopra che facciamo référenceàun'azione per débisogna‘esportare’ d’un'interfaccia CRUD del nostro admin.
C’è quindi direttamente nella nostra entitàéche configureremo l’esportare.
Nel nostro CRUD aggiungiamo la référiferimento seguente :
use App\Source\DBALStatementSourceIterator;
E i due mémetodi seguenti :
public function getDataSourceIterator()
{
$container = $this->getConfigurationPool()->getContainer();
$em = $container->get('doctrine.orm.entity_manager');
$conn = $em->getConnection();
$fields = $this->getExportFields();
$field_str = implode(',', $fields);
$sql = "SELECT {$field_str} FROM myTable d where champs1 ='valeur' order by id asc";
$stmt = $conn->prepare($sql);
$stmt->execute();
return new DBALStatementSourceIterator($stmt);
}
public function getExportFields() {
return [
'd.champs1','d.champs2','d.champs3'
];
}
Ci restaàaggiungere il nostro iteratore di sorgente che si trova in src/Source/DBALStatementSourceIterator.php
<?php
namespace App\Source;
use Sonata\Exporter\Exception\InvalidMethodCallException;
use Sonata\Exporter\Source\SourceIteratorInterface;
class DBALStatementSourceIterator implements SourceIteratorInterface
{
/**
* @var \Doctrine\DBAL\Statement
*/
protected $statement;
/**
* @var mixed
*/
protected $current;
/**
* @var int
*/
protected $position;
/**
* @var bool
*/
protected $rewinded;
/**
* @param \Doctrine\DBAL\Statement $statement
*/
public function __construct(\Doctrine\DBAL\Statement $statement)
{
$this->statement = $statement;
$this->position = 0;
$this->rewinded = false;
}
/**
* {@inheritdoc}
*/
public function current()
{
return $this->current;
}
/**
* {@inheritdoc}
*/
public function next()
{
$this->current = $this->statement->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE);
++$this->position;
}
/**
* {@inheritdoc}
*/
public function key()
{
return $this->position;
}
/**
* {@inheritdoc}
*/
public function valid()
{
return \is_array($this->current);
}
/**
* {@inheritdoc}
*/
public function rewind()
{
if ($this->rewinded) {
throw new InvalidMethodCallException('Cannot rewind a PDOStatement');
}
$this->current = $this->statement->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE);
$this->rewinded = true;
}
}
E il giro è fattoé !
Adattare l’esempio alla versione installata
Gli esempi Symfony e Sonata rimangono legati alle versioni indicate nell’articolo. Symfony 4.x e Symfony 6.2 non sono più supportati: per un progetto attuale, utilizzate un ramo mantenuto e la documentazione corrispondente esattamente alle vostre dipendenze.
php bin/console about
composer show symfony/framework-bundle sonata-project/admin-bundle
Prima di riprendere il codice, controllate le firme, i servizi, le rotte e i template interessati. Aggiungete poi un test funzionale che copra le autorizzazioni, il codice HTTP e il risultato visibile.
Riferimento : versioni di Symfony supportate.