Search code examples
symfonyeasyadmin

How to add a custom action in EasyAdmin 3?


I have a CrudController for my entity, Participant. I want to add a custom action, sendAcknowledgementEmail. The EasyAdmin docs doesn't mention anything about the custom function parameters or return values.

I have the following code

public function configureActions(Actions $actions): Actions
{
    $send_acknowledgement_email = Action::new('sendAcknowledgementEmail', 'Send Acknowledgement Email', 'fa fa-send')
        ->linkToCrudAction('sendAcknowledgementEmail');

    return $actions
        ->add(Crud::PAGE_INDEX, $send_acknowledgement_email)
        ->add(Crud::PAGE_EDIT, $send_acknowledgement_email)
    ;
}

public function sendAcknowledgementEmail() //Do I need parameters?
{
    //How do I get the Entity?

    //What should I return?
}

So far, EasyAdmin detects the custom function but I get an error "The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned null. Did you forget to add a return statement somewhere in your controller?"

How do I continue from here?


Solution

  • After browsing through the EasyAdmin AbstractCrudController I came up with the following working code.

    • In order to get the current object you need the parameter AdminContext
    • For my use case I want to return to the CrudController index action, so for that I can do a redirect.

    Note: you need to inject the CrudUrlGenerator service in your constructor controller.

    public function sendAcknowledgementEmail(AdminContext $context)
    {
        $participant = $context->getEntity()->getInstance();
    
        // Your logic
    
        $url = $this->crudUrlGenerator->build()
            ->setController(ParticipantCrudController::class)
            ->setAction(Action::INDEX)
            ->generateUrl();
    
        return $this->redirect($url);
    }
    

    My current function looks like this:

    public function sendAcknowledgementEmail(AdminContext $context)
    {
        $participant = $context->getEntity()->getInstance();
    
        $participant->sendAcknowledgementEmail();
    
        $this->addFlash('notice','<span style="color: green"><i class="fa fa-check"></i> Email sent</span>');
    
        $url = $this->crudUrlGenerator->build()
            ->setController(ParticipantCrudController::class)
            ->setAction(Action::INDEX)
            ->generateUrl();
    
        return $this->redirect($url);
    }
    

    My current working code

    <?php
    
    namespace App\Controller\Admin;
    
    use App\Service\WebinarService;
    use EasyCorp\Bundle\EasyAdminBundle\Router\CrudUrlGenerator;
    use Symfony\Contracts\Translation\TranslatorInterface;
    // ...
    
    class ParticipantCrudController extends AbstractCrudController
    {
    
        private CrudUrlGenerator $crudUrlGenerator;
        private WebinarService $webinar_service;
        private TranslatorInterface $translator;
    
        public function __construct(CrudUrlGenerator $crudUrlGenerator, WebinarService $webinar_service, TranslatorInterface $translator)
        {
            $this->crudUrlGenerator = $crudUrlGenerator;
            $this->webinar_service = $webinar_service;
            $this->translator = $translator;
        }
    
        // ...
    
        public function sendAcknowledgementEmail(AdminContext $context): Response
        {
            $participant = $context->getEntity()->getInstance();
    
            try {
                $this->webinar_service->sendAcknowledgementEmail($participant);
    
                $this->addFlash('notice', 'flash.email.sent');
            } catch (Exception $e) {
                $this->addFlash('error', $this->translator->trans('flash.error', ['message' => $e->getMessage()]));
            }
    
            $url = $this->crudUrlGenerator->build()
                ->setController(ParticipantCrudController::class)
                ->setAction(Action::INDEX)
                ->generateUrl()
            ;
    
            return $this->redirect($url);
        }
    }