I want to generate a small form inside a Sonata Admin show template. What I have done so far is creating the function in the custom CRUD for that specific entity (order) that extends from Sonata's default CRUD;
public function approveOrderAction($id = null)
{
$request = $this->getRequest();
$id = $request->get($this->admin->getIdParameter());
$order = $this->admin->getObject($id);
$approveForm = $this->createFormBuilder($order)
->add('reqSecondApprover', 'checkbox', array('label' => 'Require second Approval', 'required' => false))
->add('secondApprover', 'choice', array('choices' => Crud::getWhatever(array('Developer')), 'required' => false))
->getForm();
$approveForm->handleRequest($request);
if ($approveForm->isSubmitted() && $approveForm->isValid()) {
$secondApproval = $request->request->get('form');
$approval = $approveForm->getData();
if (isset($secondApproval['reqSecondApprover'])) {
$order->setStatus(PmodOrder::STATUS_PARTLY_APPROVED);
} else {
$order->setStatus(PmodOrder::STATUS_APPROVED);
$order->setSecondApprover(null);
}
$em->persist($approval);
$em->flush();
return new RedirectResponse($this->admin->generateUrl('show'));
}
return $this->render('AppBundle:PmodOrder:order_approve.html.twig', array(
'order' => $order,
'form' => $approveForm->createView(),
));
}
In my orderAdmin I have the configShowFields
method;
protected function configureShowFields(ShowMapper $showMapper)
{
$order = $this->getSubject();
$showMapper
->with('General')
->add('createdBy', null, array('label' => 'Requested By'))
->add('createdAt', null, array('label' => 'Date Requested'))
->with('Order Details')
->add('orderRows', NULL, array('template' => 'AppBundle:PmodOrderRow:orderrow_overview.html.twig'))
->end()
->with('Actions')
->add('actions', NULL, array('template' => 'AppBundle:PmodOrderAction:order_actions.html.twig', 'route' => 'approve'))
->end()
;
}
The order_actions
template looks like this and will show the relevant functionality according to the status of the order and who is logged in, thus how do work with so many diffent routes?;
<td>
{% if app.user.id == object.firstApprover and object.status == 1%}
{{ render(controller('AppBundle:PmodOrderCRUD:approveOrder', { 'id': object.id })) }}
{% elseif app.user.id == object.secondApprover and object.status == 2 %}
<a href="{{ path('order_second_approve', { 'id': object.id })}}" class="btn btn-primary"><i class="fa fa-check"></i> Approve</a>
<a href="{{ path('order_disapprove', { 'id': object.id })}}" class="btn btn-default"><i class="fa fa-times"></i> Disapprove</a>
{% elseif app.user == object.createdBy and object.status == 3 %}
<a href="{{ path('order_place', { 'id': object.id })}}" class="btn btn-primary">Place Order</a>
<a href="{{ path('order_place', { 'id': object.id })}}" class="btn btn-default">Cancel Order</a>
{% else %}
-
{% endif %}
</td>
When trying this I get an error;
An exception has been thrown during the rendering of a template ("There is no
_sonata_admin
defined for the controllerApBundle\Controller\PmodOrderCRUDController
and the current route ``") in AppBundle:PmodOrderAction:order_actions.html.twig at line 3.
I understand from the documentation that I need to make use of this configureRoutes
method;
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('clone', $this->getRouterIdParameter().'/clone');
}
But I can't get it to work and I am not sure about how to render forms instead of a simple link button.
Can somebody please help me fix my problem?
The _sonata_admin
(route) attribute is used by SonataAdminBundle
to get the required admin instance ($this->admin
) and be able to configure/process your requests:
After to add the right route definition:
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('approve_order', $this->getRouterIdParameter().'/approve');
}
You need to add also the _sonata_admin
code to generate the right request to approveOrderAction()
:
{{ render(controller('QiBssFrontendBundle:PmodOrderCRUD:approveOrder', { 'id': object.id, '_sonata_admin': '...' })) }}
Let's make a simple example:
You have an Order
entity and its admin class: OrderAdmin
into PurchaseBundle
, so this is the Sonata's service definition for OrderAdmin
class (Yaml):
services:
purchase_bundle.admin.order_admin:
class: PurchaseBundle\Admin\OrderAdmin
arguments:
- ~
- PurchaseBundle\Entity\Order
- ~
tags:
- { name: 'sonata.admin', manager_type: orm }
Now, based on your own approveOrderAction()
, you can render this action in the follows way:
{{ render(controller('PurchaseBundle:OrderAdmin:approveOrder', { 'id': object.id, '_sonata_admin': 'purchase_bundle.admin.order_admin' })) }}
Just you have to add the admin code: 'purchase_bundle.admin.order_admin'
and it should work!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With