APYDataGridBundle icon indicating copy to clipboard operation
APYDataGridBundle copied to clipboard

Filter limits and manipulate rendercell

Open FredDut opened this issue 8 years ago • 0 comments

Hello, I have three entities with ManytoOne/OneToMany relations:

class Projet {
	
       /**
	 *
	 * @var string $nom @GRID\Column(title="Nom")
	 *      @ORM\Column(name="nom", type="string", length=255, nullable=false)
	 */
	private $nom;
         /**
	 * @GRID\Column(title="Domaine", field="domaine.nom")
	 * 
	 * @var domaine @ORM\ManyToOne(targetEntity="AppBundle\Entity\Domaine", inversedBy="projets")
	 *      @ORM\JoinColumns({
	 *      @ORM\JoinColumn(name="id_domaine", referencedColumnName="id")
	 *      })
	 */
	private $domaine;

         /**
	 *
	 * @var applis @ORM\OneToMany(targetEntity="Appli", mappedBy="projet", cascade={"persist"})
	 */
	private $applis;

To render ManytoOne relations in a pretty way, I use TextColumn with querybuilder.

		$grid = $this->get ( 'grid' );
		$source->initQueryBuilder($em->createQueryBuilder()
				-> select ('DISTINCT p')
				-> from('AppBundle:Projet', 'p')
				->orderBy('p.nom'));
		$grid->setSource ( $source );
		$grid->setId('index_projets');
$applisColumn= new TextColumn(array('id'=>'applis',
		    'field'=>'applis.nom',
		    'title'=>'Applis,
		    'source'=>true,
		    'filterable'=>true,'sortable'=>true )) ;
		$applisColumn->manipulateRenderCell  (
				function ($value,$row, $router) use ($em) {
					$qb = $em->createQueryBuilder()
					-> select ('g.nom')
					-> from('AppBundle:Projet', 'p')
					->leftjoin('p.applis','g')
					->where('p =:id')
					->setParameter('id', $row->getField('id') )
					;
					$applis='';
					return $qb->getQuery ()->getArrayResult();
					foreach ($qb->getQuery ()->getArrayResult() as $n=>$g) {
						foreach ($g as $l=>$nom) {
							if($applis) $applis.="\n";
							$applis.=$nom;
						}
					}
					return $applis;
				}) ;
		$grid->addColumn($applisColumn);
		$grid->hideColumns(array('domaine.nom'));
		$domaineColumn= new TextColumn(array('id'=>'domaine',
		    'field'=>'domaine.nom',
		    'title'=>'Domaine',
		    'source'=>true,'filterable'=>true,'sortable'=>true )) ;
		$domaineColumn->manipulateRenderCell  (
				function ($value,$row, $router) use ($em) {

					$projet=$em->getRepository ( 'AppBundle:Projet')->find($row->getField('id'));
					if ($projet->getDomaine()){
						return $projet->getDomaine()->getNom();
					}
					return null;
					}) ;
		$grid->addColumn($domaineColumn, 3);
		$grid->setLimits ( array (
				10,
				20,
				100
		) );

That's OK. But when I filter, the datagrid run a first query with 2 left join and limit 10:

SELECT DISTINCT p0_.id AS id_0, d1_.nom AS nom_1, d1_.nom AS nom_2, a2_.nom AS nom_3, p0_.nom AS nom_4 FROM projet p0_ LEFT JOIN domaine d1_ ON p0_.id_domaine = d1_.id LEFT JOIN appli a2_ ON p0_.id = a2_.id_projet WHERE LOWER(p0_.nom) LIKE LOWER(?) ORDER BY p0_.nom ASC LIMIT 10

The next query is limited to this 10 id. So, if there are several applis for a projet, not all relevant results are shown.

Is there a way to change the first query? (may be remove the left join with appli)

Thanks

FredDut avatar Oct 17 '17 15:10 FredDut