向Sonata Admin添加自定义操作

时间:2016-07-15 09:50:44

标签: php symfony sonata-admin sonata

我创建了一个自定义操作,在我的show模板底部呈现一个小表单以获取订单。表单是一个基本复选框和一个带有拖动按钮的选择字段。它工作得很好但渲染不正确。

我知道我渲染节目模板的方式不是100%正确,因为当它呈现时,左侧菜单不再起作用。

这是我的自定义控制器,带有操作;

namespace Qi\Bss\FrontendBundle\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Qi\Bss\FrontendBundle\Crud\Crud;
use Qi\Bss\BaseBundle\Entity\Business\PmodOrder;
use Symfony\Component\HttpFoundation\RedirectResponse;

class PmodOrderController extends Controller
{   
    /**
     * @Route("/{id}/approve", name = "order_approve")
     * @Security("is_granted('IS_AUTHENTICATED_FULLY')")
     * @Method({"GET", "POST"})
     */
    public function approveAction(Request $request, $id){
        $em = $this->getDoctrine()->getManager();
        $order = $em->getRepository('QiBssBaseBundle:PmodOrder')->find($id);
        $approveForm = $this->createFormBuilder($order)
            ->add('requireApproval', 'checkbox', array('label' => 'Require second Approval', 'required' => false, 'mapped' => false))
            ->add('secondApprover', 'choice', array('choices' => Crud::enumStatus(), 'label' => 'User', 'required' => false))
            ->getForm();

        $approveForm->handleRequest($request);

        if ($approveForm->isSubmitted() && $approveForm->isValid()) {
            $secondApproval = $request->request->get('form');
            $approval = $approveForm->getData();

            if (isset($secondApproval['requireApproval'])) {
                $approval->setStatus(PmodOrder::STATUS_PARTLY_APPROVED);

                $em->persist($approval);
                $em->flush();

                return new RedirectResponse($this->container->get('router')->generate('admin_bss_base_business_pmodorder_show', array('id' => $order->getId())));
            } else {
                $approval->setSecondApprover(NULL);
                $approval->setStatus(PmodOrder::STATUS_APPROVED);

                $em->persist($approval);
                $em->flush();

                return new RedirectResponse($this->container->get('router')->generate('admin_bss_base_business_pmodorder_show', array('id' => $order->getId())));
            }            

        }

        return $this->render('QiBssFrontendBundle:PmodOrder:order_approve.html.twig', array(
            'order' => $order,
            'form' => $approveForm->createView(),
        ));
    }
}

令我困扰的是,我实际上是想从Sonata的CRUDController扩展。当我这样做时,我得到一个错误;

  

在渲染模板期间抛出了异常   (“没有为控制器定义_sonata_admin   Path\To\Controller\PmodOrderController和当前   路线``“)

而且我也知道我实际上假设使用像return new RedirectResponse($this->admin->generateUrl('show'));

这样的回报

此时我不知道该怎么做了。如果有人可以指导我如何在我的场景中正确地从CRUDController扩展,那将非常感激

1 个答案:

答案 0 :(得分:1)

这是一个例子,我不知道它是否是最好的解决方案,但我希望能帮到你:

1-创建自定义CRUDcontroller:

# CustomCRUDcontroller.php :
class CustomCRUDDController extends Controller
{   
    /**
     * Show action.
     *
     * @param int|string|null $id
     * @param Request         $request
     *
     * @return Response
     *
     * @throws NotFoundHttpException If the object does not exist
     * @throws AccessDeniedException If access is not granted
     */
    public function showAction($id = null)
    {
        $request = $this->getRequest();
        // DO YOUR LOGIC IN THE METHOD, for example :
        if(isset($request->get('yourFormParam'))){
            $this->doTheJob();
        }

        $id = $request->get($this->admin->getIdParameter());

        $object = $this->admin->getObject($id);

        if (!$object) {
            throw $this->createNotFoundException(sprintf('unable to find the object with id : %s', $id));
        }

        $this->admin->checkAccess('show', $object);

        $preResponse = $this->preShow($request, $object);
        if ($preResponse !== null) {
            return $preResponse;
        }

        $this->admin->setSubject($object);

        return $this->render($this->admin->getTemplate('show'), array(
            'action' => 'show',
            'object' => $object,
            'elements' => $this->admin->getShow(),
        ), null);
    }
}

2-在admin.yml中注册:

# admin.yml :
x.admin.x:
        class: Namespace\YourAdminClass
        arguments: [~, Namespace\Entity, Namespace:CustomCRUD]
        tags:
            - {name: sonata.admin, manager_type: orm, group: X, label: X}

3-创建您自己的custom_show.html.twig(只是复制并粘贴位于sonata-admin文件夹中的原始模板base_show.html.twig),在这里您可以向视图显示额外的元素:

# custom_show.html.twig :

{% extends base_template %}

{% import 'SonataAdminBundle:CRUD:base_show_macro.html.twig' as show_helper %}

{% block actions %}
    {% include 'SonataAdminBundle:CRUD:action_buttons.html.twig' %}
{% endblock %}

{% block tab_menu %}
    {{ knp_menu_render(admin.sidemenu(action), {
        'currentClass' : 'active',
        'template': sonata_admin.adminPool.getTemplate('tab_menu_template')
    }, 'twig') }}
{% endblock %}

{% block show %}
    <div class="sonata-ba-view">

        {{ sonata_block_render_event('sonata.admin.show.top', { 'admin': admin, 'object': object }) }}

        {% set has_tab = (admin.showtabs|length == 1 and admin.showtabs|keys[0] != 'default') or admin.showtabs|length > 1 %}

        {% if has_tab %}
            <div class="nav-tabs-custom">
                <ul class="nav nav-tabs" role="tablist">
                    {% for name, show_tab in admin.showtabs %}
                        <li{% if loop.first %} class="active"{% endif %}>
                            <a href="#tab_{{ admin.uniqid }}_{{ loop.index }}" data-toggle="tab">
                                <i class="fa fa-exclamation-circle has-errors hide"></i>
                                {{ admin.trans(name, {}, show_tab.translation_domain) }}
                            </a>
                        </li>
                    {% endfor %}
                </ul>

                <div class="tab-content">
                    {% for code, show_tab in admin.showtabs %}
                        <div
                                class="tab-pane fade{% if loop.first %} in active{% endif %}"
                                id="tab_{{ admin.uniqid }}_{{ loop.index }}"
                        >
                            <div class="box-body  container-fluid">
                                <div class="sonata-ba-collapsed-fields">
                                    {% if show_tab.description != false %}
                                        <p>{{ show_tab.description|raw }}</p>
                                    {% endif %}

                                    {{ show_helper.render_groups(admin, object, elements, show_tab.groups, has_tab) }}
                                </div>
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        {% elseif admin.showtabs is iterable %}
            {{ show_helper.render_groups(admin, object, elements, admin.showtabs.default.groups, has_tab) }}
        {% endif %}

    </div>

    {{ sonata_block_render_event('sonata.admin.show.bottom', { 'admin': admin, 'object': object }) }}
{% endblock %}

4-然后指示您的adminController在当前路线为“show”时显示您的custom_show模板(而不是默认模板base_show.html.twig):

# YourEntityAdminController.php :
class YourEntityAdminController extends Controller
{
    // allows you to chose your custom showAction template :
    public function getTemplate($name){
        if ( $name == "show" )
            return 'YourBundle:Admin:custom_show.html.twig' ;
        return parent::getTemplate($name);
    }

}