Notice: You are browsing the documentation for PrestaShop 8, which is currently in development.

You might want to read the documentation for the current version, PrestaShop 1.7.

How to work with the Search Form

The grid component allows to filter its content, to manage the filtering you will need to define the following elements:

  • GridDefinition::getFilters
  • Filters class
  • Controllers:
    • Search action
    • List action
    • Reset filter action

Add Filters into GridDefinition

<?php
final class EmailLogsDefinitionFactory extends AbstractGridDefinitionFactory
{
    /**
     * @param string $resetActionUrl
     * @param string $redirectionUrl
     */
    public function __construct($resetActionUrl, $redirectionUrl)
    {
        $this->resetActionUrl = $resetActionUrl;
        $this->redirectionUrl = $redirectionUrl;
    }

    /**
     * {@inheritdoc}
     */
    protected function getId()
    {
        return 'email_logs';
    }

    ...
    /**
    * {@inheritdoc}
    */
    protected function getFilters()
    {
        return (new FilterCollection())
            ->add((new Filter('id_meta', TextType::class))
                ->setTypeOptions([
                    'required' => false,
                ])
                ->setAssociatedColumn('id_meta')
            )
            ->add((new Filter('page', TextType::class))
                ->setTypeOptions([
                    'required' => false,
                ])
                ->setAssociatedColumn('page')
            )
            ->add((new Filter('title', TextType::class))
                ->setTypeOptions([
                    'required' => false,
                ])
                ->setAssociatedColumn('title')
            )
            ->add((new Filter('url_rewrite', TextType::class))
                ->setTypeOptions([
                    'required' => false,
                ])
                ->setAssociatedColumn('url_rewrite')
            )
            ->add((new Filter('actions', SearchAndResetType::class))
                ->setTypeOptions([
                    'attr' => [
                        'data-url' => $this->resetActionUrl,
                        'data-redirect' => $this->redirectionUrl,
                    ],
                ])
                ->setAssociatedColumn('actions')
            )
        ;
    }
    ...
}

And here is the service definition associated

    prestashop.core.grid.definition.factory.email_logs:
        class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\EmailLogsDefinitionFactory'
        parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition'
        arguments:
            - "@=service('router').generate('admin_common_reset_search', {'controller': 'email', 'action': 'index'})"
            - "@=service('router').generate('admin_emails_index')"
        public: true

The filters types

In the filters collection you define all the available filters (which will match your grid columns), you can define a specific type depending on the column. You can basically use any Symfony form type (including your custom ones) and PrestaShop provides a few filter types that might be useful to you.

Filters class

You need to define a Filters class linked to your Grid, it will allow you to define the default filters and sorting values. It will also make your list action simpler as PrestaShop provides a parameter resolver responsible of automatically create and fill a Filters object.

<?php
use PrestaShop\PrestaShop\Core\Search\Filters;

/**
 * Class EmailLogsFilter defines default filters for Email logs grid.
 */
final class EmailLogsFilter extends Filters
{
    /**
     * {@inheritdoc}
     */
    public static function getDefaults()
    {
        return [
            'limit' => 50,
            'offset' => 0,
            'orderBy' => 'id_mail',
            'sortOrder' => 'desc',
            'filters' => [],
        ];
    }
}

Controller actions

The Grid filtering workflow is divided into three controllers:

  • search action: it parses the filters from the POST request, then redirects to the list action
  • list action: it parses the filters from GET request, persists them into database and finally renders the grid
  • reset action: to clean the persisted filters and reset to the default ones

Search action

<?php
class EmailController extends FrameworkBundleAdminController
{
    ...
    /**
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.")
     *
     * @param Request $request
     *
     * @return RedirectResponse
     */
    public function searchAction(Request $request)
    {
        $definitionFactory = $this->get('prestashop.core.grid.definition.factory.email_logs');
        $emailLogsDefinition = $definitionFactory->getDefinition();

        $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory');
        $filtersForm = $gridFilterFormFactory->create($emailLogsDefinition);
        $filtersForm->handleRequest($request);

        $filters = [];

        if ($filtersForm->isSubmitted()) {
            $filters = $filtersForm->getData();
        }

        return $this->redirectToRoute('admin_emails_index', ['filters' => $filters]);
    }
    ...
}
# Routing
admin_emails_search:
    path: /
    methods: [POST]
    defaults:
        _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:search'
        _legacy_controller: AdminEmails

List action

Thanks to the internal parameter resolver you can directly use your Filters class as an argument in the controller. It then automatically:

  • parses the potential parameters in the query and fills them into the Filters argument
  • matches thanks to the class the filters from the database and fetch them if present
  • persists the filters in the database
<?php
class EmailController extends FrameworkBundleAdminController
{
    ...
    /**
     * Show email configuration page.
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.")
     *
     * @param Request $request
     * @param EmailLogsFilter $filters
     *
     * @return Response
     */
    public function indexAction(Request $request, EmailLogsFilter $filters)
    {
        $emailLogsGridFactory = $this->get('prestashop.core.grid.factory.email_logs');
        $emailLogsGrid = $emailLogsGridFactory->getGrid($filters);
        $presentedEmailLogsGrid = $this->presentGrid($emailLogsGrid);

        return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Email/index.html.twig', [
            'enableSidebar' => true,
            'emailLogsGrid' => $presentedEmailLogsGrid,
            'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')),
        ]);
    }
    ...
}

Reset action

Last action is used to reset the persisted filters and your grid filtering/sorting. This action is the same for nearly all grids so PrestaShop provides a common controller to manage it, and you actually already set it via the grid definition.

It is defined in the service definition, it uses the admin_common_reset_search route and use email/index as keys to match the controller/action.

    prestashop.core.grid.definition.factory.email_logs:
        class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\EmailLogsDefinitionFactory'
        parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition'
        arguments:
            - "@=service('router').generate('admin_common_reset_search', {'controller': 'email', 'action': 'index'})"
            - "@=service('router').generate('admin_emails_index')"
        public: true