- 
      
- 
        Save Slauta/3175282 to your computer and use it in GitHub Desktop. 
| <?php | |
| namespace Acme\UserBundle\Entity; | |
| use Doctrine\ORM\EntityRepository; | |
| use Doctrine\ORM\Query\Expr; | |
| /** | |
| * UserRepository | |
| * | |
| * This class was generated by the Doctrine ORM. Add your own custom | |
| * repository methods below. | |
| */ | |
| class UserRepository extends EntityRepository | |
| { | |
| /** | |
| * @param array $get | |
| * @param bool $flag | |
| * @return array|\Doctrine\ORM\Query | |
| */ | |
| public function ajaxTable(array $get, $flag = false){ | |
| /* Indexed column (used for fast and accurate table cardinality) */ | |
| $alias = 'a'; | |
| /* DB table to use */ | |
| $tableObjectName = 'UserBundle:User'; | |
| /** | |
| * Set to default | |
| */ | |
| if(!isset($get['columns']) || empty($get['columns'])) | |
| $get['columns'] = array('id'); | |
| $aColumns = array(); | |
| foreach($get['columns'] as $value) $aColumns[] = $alias .'.'. $value; | |
| $cb = $this->getEntityManager() | |
| ->getRepository($tableObjectName) | |
| ->createQueryBuilder($alias) | |
| ->select(str_replace(" , ", " ", implode(", ", $aColumns))); | |
| if ( isset( $get['iDisplayStart'] ) && $get['iDisplayLength'] != '-1' ){ | |
| $cb->setFirstResult( (int)$get['iDisplayStart'] ) | |
| ->setMaxResults( (int)$get['iDisplayLength'] ); | |
| } | |
| /* | |
| * Ordering | |
| */ | |
| if ( isset( $get['iSortCol_0'] ) ){ | |
| for ( $i=0 ; $i<intval( $get['iSortingCols'] ) ; $i++ ){ | |
| if ( $get[ 'bSortable_'.intval($get['iSortCol_'.$i]) ] == "true" ){ | |
| $cb->orderBy($aColumns[ (int)$get['iSortCol_'.$i] ], $get['sSortDir_'.$i]); | |
| } | |
| } | |
| } | |
| /* | |
| * Filtering | |
| * NOTE this does not match the built-in DataTables filtering which does it | |
| * word by word on any field. It's possible to do here, but concerned about efficiency | |
| * on very large tables, and MySQL's regex functionality is very limited | |
| */ | |
| if ( isset($get['sSearch']) && $get['sSearch'] != '' ){ | |
| $aLike = array(); | |
| for ( $i=0 ; $i<count($aColumns) ; $i++ ){ | |
| if ( isset($get['bSearchable_'.$i]) && $get['bSearchable_'.$i] == "true" ){ | |
| $aLike[] = $cb->expr()->like($aColumns[$i], '\'%'. $get['sSearch'] .'%\''); | |
| } | |
| } | |
| if(count($aLike) > 0) $cb->andWhere(new Expr\Orx($aLike)); | |
| else unset($aLike); | |
| } | |
| /* | |
| * SQL queries | |
| * Get data to display | |
| */ | |
| $query = $cb->getQuery(); | |
| if($flag) | |
| return $query; | |
| else | |
| return $query->getResult(); | |
| } | |
| /** | |
| * @return int | |
| */ | |
| public function getCount(){ | |
| $aResultTotal = $this->getEntityManager() | |
| ->createQuery('SELECT COUNT(a) FROM UserBundle:User a') | |
| ->setMaxResults(1) | |
| ->getResult(); | |
| return $aResultTotal[0][1]; | |
| } | |
| } | 
| <?php | |
| namespace Antalika\AdminBundle\Controller; | |
| use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
| use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
| use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; | |
| use Doctrine\ORM\PersistentCollection; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpFoundation\Response; | |
| /** | |
| * @Route("/ajax") | |
| */ | |
| class AjaxController extends Controller | |
| { | |
| /** | |
| * @Route("/users/list", name="admin_ajax_users_list") | |
| * @Template() | |
| */ | |
| public function usersListAction(Request $request) | |
| { | |
| $get = $request->query->all(); | |
| /* Array of database columns which should be read and sent back to DataTables. Use a space where | |
| * you want to insert a non-database field (for example a counter or static image) | |
| */ | |
| $columns = array( 'id', 'twitter_username', 'twitterID', 'firstname' ); | |
| $get['columns'] = &$columns; | |
| $em = $this->getDoctrine()->getEntityManager(); | |
| $rResult = $em->getRepository('UserBundle:User')->ajaxTable($get, true)->getArrayResult(); | |
| /* Data set length after filtering */ | |
| $iFilteredTotal = count($rResult); | |
| /* | |
| * Output | |
| */ | |
| $output = array( | |
| "sEcho" => intval($get['sEcho']), | |
| "iTotalRecords" => $em->getRepository('UserBundle:User')->getCount(), | |
| "iTotalDisplayRecords" => $iFilteredTotal, | |
| "aaData" => array() | |
| ); | |
| foreach($rResult as $aRow) | |
| { | |
| $row = array(); | |
| for ( $i=0 ; $i<count($columns) ; $i++ ){ | |
| if ( $columns[$i] == "version" ){ | |
| /* Special output formatting for 'version' column */ | |
| $row[] = ($aRow[ $columns[$i] ]=="0") ? '-' : $aRow[ $columns[$i] ]; | |
| }elseif ( $columns[$i] != ' ' ){ | |
| /* General output */ | |
| $row[] = $aRow[ $columns[$i] ]; | |
| } | |
| } | |
| $output['aaData'][] = $row; | |
| } | |
| unset($rResult); | |
| return new Response( | |
| json_encode($output) | |
| ); | |
| } | |
| } | 
Hello, thanx for your code, it really helped me.
I figured out solution about pagination issue.
In $output array to "iTotalDisplayRecords" assigned $iFilteredTotal which actually contains number of rows to display at table's current page, but it must be count of rows after filtering.
As written in documentation: (int) iTotalDisplayRecords - Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned in this result set).
So my fast and dirty solution is to add this function to repository: https://gist.github.com/asagajda/5973304
Than in controller make following correction:
"iTotalDisplayRecords" => $em->getRepository('Entity')->getFilteredCount($get),
Hello,
I'v implemented the code like, but it seems some exceptions thrown :
" The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?
500 Internal Server Error - LogicException "
for relational table
[Semantical Error] line 0, col 47 near 'createdBy FROM': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
@noufel12 the exception is self-explaining - your controller does not return any response.
Boy, this is awesome. I was looking for something like this. Thank you for the contribution.
hello, thank you very much for your great contribution, but I followed everything to the letter, the problem is that the pagination does not work. everything else if.
I hope you can help, I would greatly appreciate it.
you have any idea why this happens? thanks