我目前正在使用symfony2进行一个项目。当我显示所有事务时,我有一个分页,并且在相同的控制器函数和存储库中,我还添加了搜索。我现在的问题是,如何通过将搜索结果整合到一个功能中,对搜索结果进行分页,同时显示所有交易。到目前为止,这是我所尝试的,在这段代码中分页工作得很好,但搜索结果不是。
库
public function getAllTransaction($rNumber,$gNumber,$senderId,$receiverId,$docType,$direction,$startDate,$endDate,$page = 1, $limit = 10) {
$em = $this->getEntityManager();
$query = $em->createQuery(
'SELECT partial a.{supplierTransactionDetailId, rNumber, pNumber, invNumber, anNumber, adNumber, amount},
partial b.{supplierTransactionId, transactionDate, senderId, receiverId, isaNumber, gsNumber, fileName},
partial c.{supplierDocTypeId, docType, direction}
FROM SupplierBundle:SupplierTransactionDetail a
JOIN a.supplierTransaction b
JOIN b.supplierDocType c
WHERE (a.rNumber LIKE :rNumber OR a.pNumber LIKE :rNumber
OR a.invNumber LIKE :rNumber
OR a.anNumber LIKE :rNumber
OR a.adNumber LIKE :rNumber )
AND b.gsNumber LIKE :gsNumber
AND b.senderId LIKE :senderId
AND b.receiverId LIKE :receiverId
AND c.docType LIKE :docType
AND c.direction LIKE :direction
OR b.transactionDate BETWEEN :startDate AND :endDate
ORDER BY b.transactionDate desc'
)
->setParameter('rNumber', "%$rNumber%")
->setParameter('gsNumber', "%$gsNumber%")
->setParameter('senderId', "%$senderId%")
->setParameter('receiverId' , "%$receiverId%")
->setParameter('docType',"%$docType%")
->setParameter('direction', "%$direction%")
->setParameter('startDate', "%$startDate%")
->setParameter('endDate', "%$endDate%")
->setFirstResult(($page - 1) *$limit )
->setMaxResults($limit);
$paginator = new Paginator ($query, $fetchJoinCollection = false );
$paginator->setUseOutputWalkers(false);
return $paginator;
}
控制器:
public function trackAction(Request $request,$page){
$rNumber = $request->query->get('rNumber');
$gsNumber = $request->query->get('gsNumber');
$senderId = $request->query->get('senderId');
$receiverId = $request->query->get('receiverId');
$docType = $request->query->get('docType');
$direction = $request->query->get('direction');
$startDate = $request->query->get('startDate');
$endDate = $request->query->get('endDate');
$max_records = 10;
$em = $this->getDoctrine()->getManager();
$trans = $em->getRepository('SupplierBundle:SupplierTransactionDetail')->getAllTransaction($rNumber,$gsNumber,$senderId,$receiverId,$docType,$direction,$startDate,$endDate,$page , 10);
$count = $trans->count();
$pagination = array(
'page' => $page,
'route' => 'supplier_tracking',
'route_params' => array()
);
if ($max_records > 0 ){
$pagination['pages_count'] = max(ceil($count / $max_records), 1);
}
return $this->render('SupplierBundle:Supplier:tracking.html.twig',array('trans' => $trans, 'pagination' => $pagination));
}
谢谢。
我将试着解释我是如何解决这种情况的;我将以User
实体为例。
搜索路由(/user/search
, POST)
搜索表单发送它的POST数据到这个路由;在这里,我将所有带有控制器特定前缀(如app_user_filter_
)的过滤器保存到会话中。
重置搜索路线(/user/search/reset
,)
用于移除当前控制器会话中的所有过滤器。
List route (/user
, GET)
此路由呈现用户列表并接受page
参数(类似于/user?page=2
)。
getEntities
存储库方法接受一个过滤器数组(键=>值对)和一个页码;该过滤器数组是从控制器内部的会话中通过提取键以控制器特定前缀(例如,app_user_filter_email
或app_user_filter_username
)开头的所有值来创建的。
<标题>结论您的方法,在每个页面更改时,松开过滤器,因为您试图从当前请求($request->query->get('rNumber')
)获得它们,但您没有将它们重新发送到更改页面url (localhost:2224/Tracker/web/app_dev.php/tracking/2
)。
我的解决方案有点复杂,但有助于简化您的工作。我已经在4个项目中应用了这种解决方案,效果非常好。
如果你愿意,你可以查看我在工作中使用的包,特别是那个方法。
<标题> 例子控制器"track"动作:
public function trackAction(Request $request, $page) {
$filters = array();
$prefix = 'transaction_filter_';
$session = $request->getSession();
foreach ($request->getSession()->all() as $key => $value) {
if (strpos($key, $prefix) === 0) {
$filters[str_replace($prefix, '', $key)] = $value;
}
}
$repo = $this->getDoctrine()->getRepository('SupplierBundle:SupplierTransactionDetail');
$trans = $repo->getAllTransaction($filters, $page, 10);
// [...]
}
控制器"search"动作:
public function searchAction(Request $request)
{
$prefix = 'transaction_filter_';
$validFilters = array(
'rNumber',
'gsNumber'
// Add the other filters to this list
);
$session = $request->getSession();
foreach ($validFilters as $filter) {
if ($request->has($filter)) {
$session->set($prefix . $filter, $request->get($filter));
}
}
// Redirect to the trackAction url
}
控制器"reset search"动作:
public function resetSearchAction(Request $request)
{
$prefix = 'transaction_filter_';
$session = $request->getSession();
foreach ($request->getSession()->all() as $key => $value) {
if (strpos($key, $prefix) === 0) {
$session->remove($key);
}
}
// Redirect to the trackAction url
}
库方法:
public function getAllTransaction($filters, $page, $elementsPerPage)
{
$queryBuilder = $this->createQueryBuilder('a')
->addSelect('b, c')
->from('SupplierBundle:SupplierTransactionDetail', 'a')
->join('a.supplierTransaction', 'b')
->join('b.supplierDocType', 'c')
->addOrderBy('b.transactionDate', 'desc')
->setFirstResult(($page - 1) * $elementsPerPage )
->setMaxResults($elementsPerPage);
foreach ($filters as $filter => $value) {
if ($filter == 'rNumber') {
$queryBuilder->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->like('a.rNumber', $value),
$queryBuilder->expr()->like('a.pNumber', $value),
$queryBuilder->expr()->like('a.invNumber', $value),
$queryBuilder->expr()->like('a.anNumber', $value),
$queryBuilder->expr()->like('a.adNumber', $value)
)
);
}
if ($filter == 'gsNumber') {
$queryBuilder->andWhere('b.gsNumber = :gsNumber')->setParameter('gsNumber', $value);
}
// Add the other filters here
}
return new Paginator($queryBuilder);
}
标题>标题>标题>标题>