symfony apply_filter无法在lexik表单过滤器上运行

时间:2016-03-24 05:49:52

标签: php forms symfony

我使用LexikFormFilterBundle来过滤实体及其关系。我试图添加apply_filter闭包,这样我就可以在运行查询之前修改我有过滤器的字段的值。无论我做什么,封闭都不会被调用。你们可以帮帮我,或者告诉我可能发生的事情。谢谢。

TimesheetController.php

    <?php

    namespace Homecare\HomecareBundle\Controller;

    use Homecare\HomecareBundle\Form\TimesheetFilterType;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Homecare\HomecareBundle\Entity\CareGoals;
    use Homecare\HomecareBundle\Entity\User;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Session\Session;

    class TimesheetController extends Controller
    {


        public function indexAction(Request $request)
        {

            $form = $this->createForm(new TimesheetFilterType(), null, [
                'action' => $this->generateUrl('Homecare_HomecareBundle_dashboard_timesheets'),
                'method' => 'GET',
            ]);


            $filterBuilder = $this->getDoctrine()->getManager()->getRepository(
                'HomecareHomecareBundle:Timesheet'
            )->createQueryBuilder('t');
             //->join('t.recipient', 'r');

            $form->handleRequest($request);

            if ($form->isValid()) {

                $this->get('lexik_form_filter.query_builder_updater')
                     ->addFilterConditions($form, $filterBuilder);

                $timesheets = $filterBuilder->getQuery()->getResult();


               // dump($filterBuilder->getDql());
            }


            $timesheets = $filterBuilder->getQuery()->getResult();

            return $this->render(
                'HomecareHomecareBundle:Timesheet:index.html.twig',
                array(
                    'form' => $form->createView(),
                    'timesheets' => $timesheets
                )
            );

        } 

}

TimesheetFilterType.php

<?php
/**
 * Created by PhpStorm.
 * User: joshuacrawmer
 * Date: 3/23/16
 * Time: 4:49 PM
 */

namespace Homecare\HomecareBundle\Form;

use Ambta\DoctrineEncryptBundle\Encryptors\Rijndael256Encryptor;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderExecuterInterface;
use Lexik\Bundle\FormFilterBundle\Filter\Form\Type as Filters;
use Lexik\Bundle\FormFilterBundle\Filter\Query\QueryInterface;


class TimesheetFilterType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {


        $builder->add('recipient', Filters\CollectionAdapterFilterType::class, array(
            'entry_type'       => new RecipientFilterType(),
            'label' => false,
            'add_shared' => function (FilterBuilderExecuterInterface $qbe)  {

                $closure = function (QueryBuilder $filterBuilder, $alias, $joinAlias, Expr $expr) {
                    // add the join clause to the doctrine query builder
                    // the where clause for the label and color fields will be added automatically with the right alias later by the Lexik\Filter\QueryBuilderUpdater
                    $filterBuilder->join($alias . '.recipient', $joinAlias);
                    //$filterBuilder->join($alias . '.options', $joinAlias);
                };



                // then use the query builder executor to define the join and its alias.
                $qbe->addOnce($qbe->getAlias().'.recipient', 'r', $closure);
            },
            'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
                $encryptor = new Rijndael256Encryptor( 'ABCDEFGHIJKLMNOPQRSTUVWXZY123456' );

                if (empty($values['value'])) {
                    return null;
                }

                $paramName = sprintf('p_%s', str_replace('.', '_', $field));

                // expression that represent the condition
                $expression = $filterQuery->getExpr()->eq($field, ':'.$paramName);

                // expression parameters
                $parameters = array($paramName => $encryptor->encrypt($values['value'])); // [ name => value ]
                // or if you need to define the parameter's type
                // $parameters = array($paramName => array($values['value'], \PDO::PARAM_STR)); // [ name => [value, type] ]

                return $filterQuery->createCondition($expression, $parameters);


            },
        ));


    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'csrf_protection'   => false,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'timesheet_filter';
    }

}

1 个答案:

答案 0 :(得分:0)

我发现了伙计们。实际上需要在关联表单类型上添加'apply_filter'。然后它会工作。