Symfony KnpPaginator查询,使用表单字段中的自定义筛选器?

Symfony KnpPaginator查询,使用表单字段中的自定义筛选器?,symfony,knppaginator,Symfony,Knppaginator,我正在创建一个表单,该表单修改KnpPaginatorBundle的查询,以显示经过筛选的分页结果 这样做。当表单有效时,我使用要筛选的必需字段构建查询字符串(连接)。我使用自定义查询设置$FiltereDql变量。问题是它的值只保留在第一页。当我更改页面时,它将变为空。和分页重置 我认为,问题可能是我正在块上下文中设置$FiltereDql变量(当表单仅有效时) 如何为整个操作或应用程序范围设置$filteredDql变量?也许使用参数?我尝试从控制器使用容器,但未成功使用: $this-&g

我正在创建一个表单,该表单修改KnpPaginatorBundle的查询,以显示经过筛选的分页结果

这样做。当表单有效时,我使用要筛选的必需字段构建查询字符串(连接)。我使用自定义查询设置$FiltereDql变量。问题是它的值只保留在第一页。当我更改页面时,它将变为空。和分页重置

我认为,问题可能是我正在块上下文中设置$FiltereDql变量(当表单仅有效时)

如何为整个操作或应用程序范围设置$filteredDql变量?也许使用参数?我尝试从控制器使用容器,但未成功使用:

$this->container->setParameter('key', value);
$this->container->getParameter('key');
$this->container->HasParameter('key');
但是这样我就得到了500个内部服务器错误

代码如下:

public function indexAction(Request $request, $page)
{
    $filters = new Filters();

    $form = $this->createForm(new FiltersType(), $filters);

    $dql = "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true";

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $country = $filters->getCountry();
            $city = $filters->getCity();
            $gender = $filters->getGender();
            $sexualOrientation = $filters->getSexualOrientation();

            if (isset($country)) {
                $dql .= " AND a.country = '" . $filters->getCountry() . "'";
            }
            if (isset($city)) {
                $dql .= " AND a.city = '" . $filters->getCity() . "'";
            }
            if (isset($gender)) {
                $dql .= " AND a.gender = '" . $filters->getGender() . "'";
            }
            if (isset($sexualOrientation)) {
                $dql .= " AND a.sexual_orientation = '" . $filters->getSexualOrientation() . "'";
            }
            $filteredDql = $dql;
        }
    }

    $em = $this->get('doctrine.orm.entity_manager');

    if (isset($filteredDql)) {
        $query = $em->createQuery($filteredDql);
    } else {
        $query = $em->createQuery($dql);
    }

    $paginator = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $query,
        $this->get('request')->query->get('page', $page),
        5
    );

    return $this->render('ViciousAmateurBundle:Default:index.html.twig', array(
        'form' => $form->createView(),
        'pagination' => $pagination
        )
    );
}
/**
 * @Route("/{page}", defaults={"page" = 1}, name="homepage")
 * @Route("/")
 * @Template()
 */
public function indexAction(Request $request, $page)
{
    $filters = new Filters();

    $form = $this->createForm(new FiltersType(), $filters);

    $session = $this->getRequest()->getSession();

    if ($session->get('dql') == null) {
        $session->set('dql', "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true");
    }

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $dql = "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true";
            $country = $filters->getCountry();
            $city = $filters->getCity();
            $gender = $filters->getGender();
            $sexualOrientation = $filters->getSexualOrientation();

            if (isset($country)) {
                $dql .= " AND a.country = '" . $filters->getCountry() . "'";
            }
            if (isset($city)) {
                $dql .= " AND a.city = '" . $filters->getCity() . "'";
            }
            if (isset($gender)) {
                $dql .= " AND a.gender = '" . $filters->getGender() . "'";
            }
            if (isset($sexualOrientation)) {
                $dql .= " AND a.sexual_orientation = '" . $filters->getSexualOrientation() . "'";
            }

            $session->set('dql', $dql);
        }
    }

    $em = $this->get('doctrine.orm.entity_manager');

    $query = $em->createQuery($session->get('dql'));

    $paginator = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $query,
        $this->get('request')->query->get('page', $page),
        5
    );

    return $this->render('ViciousAmateurBundle:Default:index.html.twig', array(
        'form' => $form->createView(),
        'pagination' => $pagination
        )
    );
}

最后使用一个会话变量来存储当前过滤器解决了这个问题。会话是应用程序范围的或无状态的。我对这种方法很满意:D

尽管如此,令人遗憾的是,当数据来自表单验证时,KnpPaginatorBundle在默认情况下无法通过分页记住自定义查询“过滤器”(其中,GROUP BY…),并且仅通过使用可排序函数创建链接以对asc或desc进行排序来支持它,这是一个遗憾

代码如下:

public function indexAction(Request $request, $page)
{
    $filters = new Filters();

    $form = $this->createForm(new FiltersType(), $filters);

    $dql = "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true";

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $country = $filters->getCountry();
            $city = $filters->getCity();
            $gender = $filters->getGender();
            $sexualOrientation = $filters->getSexualOrientation();

            if (isset($country)) {
                $dql .= " AND a.country = '" . $filters->getCountry() . "'";
            }
            if (isset($city)) {
                $dql .= " AND a.city = '" . $filters->getCity() . "'";
            }
            if (isset($gender)) {
                $dql .= " AND a.gender = '" . $filters->getGender() . "'";
            }
            if (isset($sexualOrientation)) {
                $dql .= " AND a.sexual_orientation = '" . $filters->getSexualOrientation() . "'";
            }
            $filteredDql = $dql;
        }
    }

    $em = $this->get('doctrine.orm.entity_manager');

    if (isset($filteredDql)) {
        $query = $em->createQuery($filteredDql);
    } else {
        $query = $em->createQuery($dql);
    }

    $paginator = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $query,
        $this->get('request')->query->get('page', $page),
        5
    );

    return $this->render('ViciousAmateurBundle:Default:index.html.twig', array(
        'form' => $form->createView(),
        'pagination' => $pagination
        )
    );
}
/**
 * @Route("/{page}", defaults={"page" = 1}, name="homepage")
 * @Route("/")
 * @Template()
 */
public function indexAction(Request $request, $page)
{
    $filters = new Filters();

    $form = $this->createForm(new FiltersType(), $filters);

    $session = $this->getRequest()->getSession();

    if ($session->get('dql') == null) {
        $session->set('dql', "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true");
    }

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $dql = "SELECT a FROM ViciousAmateurBundle:Post a WHERE a.is_active = true";
            $country = $filters->getCountry();
            $city = $filters->getCity();
            $gender = $filters->getGender();
            $sexualOrientation = $filters->getSexualOrientation();

            if (isset($country)) {
                $dql .= " AND a.country = '" . $filters->getCountry() . "'";
            }
            if (isset($city)) {
                $dql .= " AND a.city = '" . $filters->getCity() . "'";
            }
            if (isset($gender)) {
                $dql .= " AND a.gender = '" . $filters->getGender() . "'";
            }
            if (isset($sexualOrientation)) {
                $dql .= " AND a.sexual_orientation = '" . $filters->getSexualOrientation() . "'";
            }

            $session->set('dql', $dql);
        }
    }

    $em = $this->get('doctrine.orm.entity_manager');

    $query = $em->createQuery($session->get('dql'));

    $paginator = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $query,
        $this->get('request')->query->get('page', $page),
        5
    );

    return $this->render('ViciousAmateurBundle:Default:index.html.twig', array(
        'form' => $form->createView(),
        'pagination' => $pagination
        )
    );
}

查看日志文件,您会得到什么确切的错误?当我使用$this->container->*方法时,收到500个内部服务器错误。不会记录任何新内容。使用开发或产品环境:当不尝试使用参数时,应用程序工作正常。但我无法获得我想要的行为。请不要一字不差地使用此代码。提供的代码不安全-存在sql注入漏洞。为了避免这种情况,请使用参数占位符(命名参数),而不是使用DQL手动串联值。此外,条令查询生成器具有更好的API来构建查询。此外,我认为没有理由将生成的DQL保持在会话中