I am following this tutorial here. I would like to create a custom action that saves a csv file. I want to save my user class, but for now I just want to understand why the function saveUsersToCsv
is not being called. Here is my UserCrudController:
UserCrudController.php
<?php
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField;
class UserCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return User::class;
}
// configurable fields
// see: https://symfony.com/bundles/EasyAdminBundle/current/fields.html
public function configureFields(string $pageName): iterable
{
return [
TextField::new("username"),
EmailField::new('email'),
ArrayField::new('roles'),
];
}
public function configureActions(Actions $actions): Actions
{
$saveCsv = Action::new('saveCsv','Save as Csv', 'fa fa-save-as-csv')
->displayAsButton()
->linkToCrudAction('saveUsersToCsv');
return $actions
->add(Crud::PAGE_DETAIL,$saveCsv);
}
// https://stackoverflow.com/questions/27888374/create-csv-and-force-download-of-file
public function saveUsersToCsv(AdminContext $context){
// $instance = $context->getEntity()->getInstance();
$fileName = "test";
$filePath = $_SERVER["DOCUMENT_ROOT"] . $fileName . '.csv';
$output = fopen($filePath,'w+');
fputcsv($output,array("Number","Description","test"));
fputcsv($output,array("100","TestDescription","10"));
// set the headers
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename ="'.$fileName.".csv'");
header('Content-Length: ' .filesize($filePath));
echo readfile($filePath);
}
}
The button for saving a user does correctly show up, but when clicked nothing happens:
How can I get the button click to call the function to save the csv file?
I have found a solution. Here is the code in UserCrudController.php
.
<?php
namespace App\Controller\Admin;
namespace App\Controller\Admin;
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\MoneyField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use App\Entity\User;
class UserCrudController extends AbstractCrudController
{
public const ACTION_SAVE_CSV = "SAVE_CSV";
// entity manager
private $em;
public function __construct(EntityManagerInterface $em){
$this->em = $em;
}
public static function getEntityFqcn(): string
{
return User::class;
}
// configurable fields
// see: https://symfony.com/bundles/EasyAdminBundle/current/fields.html
public function configureFields(string $pageName): iterable
{
return [
TextField::new("username"),
EmailField::new('email'),
ArrayField::new('roles'),
];
}
public function configureActions(Actions $actions): Actions
{
$duplicate = Action::new(self::ACTION_SAVE_CSV)
->linkToCrudAction('saveUsersToCsv')
->setCssClass('btn btn-info')
->createAsGlobalAction();
return $actions
->add(Crud::PAGE_INDEX,$duplicate);
}
public function saveUsersToCsv(
AdminContext $context,
AdminUrlGenerator $adminUrlGenerator,
EntityManagerInterface $em
): Response {
$userRepo = $this->em->getRepository(User::class);
$users= $userRepo->findAll(); // Doctrine query
$rows = array();
$columns = array(
'id',
'email',
);
$rows[] = implode(',',$columns);
foreach($users as $user){
$data = array(
$user->getId(),
$user->getEmail(),
);
$rows[] = implode(',',$data);
}
$content = implode("\n",$rows);
$response = new Response($content);
$response->headers->set("Content-Type",'text/csv');
$response->headers->set("Content-Disposition",'attachment; filename="users.csv"');
return $response;
}
}
The main problem was that I was not passing in the right arguments into the action function, and that I did not know at the time how to create a correct response.