I am currently working on a project using symfony2. I have a pagination when I display all the transaction and in the same controller function and repository I also add search. My problem now is on how can I paginate my search result and the same time my display for all transaction, by just consolidating it in one function,... So far here is what I tried, the pagination is working perfectly in this code but the search result is not.
Repository
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;
}
Controller :
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));
}
Thanks ahead .
I'll try to explain how I solved this situation; I'll use the User
entity as an example.
Search route ( /user/search
, POST)
The search form sends its POST data to this route; here I save into the session all the filters with a controller-specific prefix (something like app_user_filter_
).
Reset search route ( /user/search/reset
, GET)
Used to remove all the filters from the session for the current controller.
List route ( /user
, GET)
This route renders the users list and accept a page
parameter (something like /user?page=2
).
My getEntities
repository method accepts an array of filters (as key => value pairs) and a page number; that array of filters is created from the session inside the controller by extracting all the values whose key starts with my controller-specific prefix (for example, app_user_filter_email
or app_user_filter_username
).
Your method, on each page change, loose the filters because you try to get them from the current request ( $request->query->get('rNumber')
) but you do not re-send them into the change page url ( localhost:2224/Tracker/web/app_dev.php/tracking/2
).
My solution is a bit complex but helps to streamline your work. I've applied this kind of solution into 4 projects already, and it works like a charm.
If you want you can check out the bundle I use at work , expecially that method .
Controller "track" action:
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);
// [...]
}
Controller "search" action:
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
}
Controller "reset search" action:
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
}
Repository method:
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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.