1
votes

I use Sonata admin Generator. I'd like to create multiple lists from a symfony class. For example I have a list of invoices and I would like to create a tab with paid bills, an other tab with pending bills and a last tab with invoices disabled. This status is in the class. I saw this page(admin/admin) in the Sonata demo who use context but I wouldn't like install mediabundle if it's possible.

1

1 Answers

2
votes

It is possible without the mediabundle. I had the same use-case as you with 'project-statuses'. These statuses are in my database.

A few steps are necessary:

  1. Override the CRUDController. Maybe this step isn't needed, but I couldn't figure out how to without. I want to display the different statuses as tabs, so I inject a collection in the list-template.

Make your own CRUDController:

    namespace Your\OwnBundle\Controller;

    use Sonata\AdminBundle\Controller\CRUDController as Controller;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Request;

    class ProjectCrudController extends Controller
    {
        /**
         * {@inheritdoc}
         *
         * @param Request $request
         */
        public function render($view, array $parameters = array(), Response $response = null, Request $request = null)
        {
            $projectStatusRepo = $this->getDoctrine()->getRepository('EvinceObjectsBundle:ProjectStatus');
            // here inject the params you'll need
            // you can do it only when $parameters['action'] == 'list' if you want
            $parameters['projectStatuses'] = $projectStatusRepo->findAll();
            $parameters['activeProjectStatus'] = $request->get('status', 1);

            return parent::render($view, $parameters, $response);
        }
    }

Inject your own CRUDController in the services.yml (or xml)

    sonata.admin.project:
        class: Your\OwnBundle\Admin\ProjectAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: "project", label: "Project" }
        arguments:
            - ~
            - Your\OwnBundle\Entity\Project
            - YourOwnBundle:ProjectCrud
        calls:
            - [ setLabelTranslatorStrategy, ["@sonata.admin.label.strategy.underscore"]]
            - [ setTemplate, [list, YourOwnBundle:ProjectAdmin:list.html.twig]]

Notice the setTemplate-call, so lets create your template

  1. Create your own list-template

    {% extends 'SonataAdminBundle:CRUD:base_list.html.twig' %}
    
    {% block preview %}
    
        <ul class="nav nav-pills">
            <li><a><strong>{{ "label.select_projectstatus"|trans({}, 'SonataProjectBundle') }}</strong></a></li>
    
            {% for projectStatus in projectStatuses %}
                {% set active = false %}
                {% if projectStatus.id == activeProjectStatus %}
                    {% set active = true %}
                {% endif %}
                <li class="{% if active %}active{% endif %}" ><a href="{{ admin.generateUrl('list', {'status' : projectStatus.id }) }}">{{ projectStatus.status }}</a></li>
            {% endfor %}
        </ul>
    {% endblock %}
    
  2. Override the Admin::getFilterParameters function in your own admin class. Here you want to set the filter based on your requestparam:

    /**
     * {@inheritdoc}
     */
    public function getFilterParameters()
    {
        $parameters = parent::getFilterParameters();   
    
        return array_merge(array(
            'status'  => array(
                'type' => '',
                'value' => $this->getRequest()->get('status', 1),
            )
        ), $parameters);
    }