Skip to content

Commit 61510c9

Browse files
author
Thomas Rabaix
committedMay 4, 2011
[orm] make the QueryProxy behave like Doctrine1 with join and limit close
1 parent ec70a71 commit 61510c9

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed
 

‎Datagrid/Datagrid.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class Datagrid implements DatagridInterface
3737

3838
protected $formFactory;
3939

40+
protected $results;
41+
4042
public function __construct(ProxyQueryInterface $query, ListCollection $columns, PagerInterface $pager, FormFactory $formFactory, array $values = array())
4143
{
4244
$this->pager = $pager;
@@ -58,7 +60,11 @@ public function getResults()
5860
{
5961
$this->buildPager();
6062

61-
return $this->pager->getResults();
63+
if (!$this->results) {
64+
$this->results = $this->pager->getResults();
65+
}
66+
67+
return $this->results;
6268
}
6369

6470
public function buildPager()

‎Datagrid/ListMapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function add($name, array $fieldDescriptionOptions = array())
5151
} else if (is_string($name) && !$this->admin->hasListFieldDescription($name)) {
5252

5353
$fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance(
54-
$this->admin->getClass(),
54+
$this->admin->getClass(),
5555
$name,
5656
$fieldDescriptionOptions
5757
);

‎Datagrid/ORM/ProxyQuery.php

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Sonata\AdminBundle\Datagrid\ORM;
1212

1313
use Doctrine\ORM\QueryBuilder;
14+
use Doctrine\ORM\Query;
1415
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
1516

1617
/**
@@ -31,16 +32,54 @@ public function __construct(QueryBuilder $queryBuilder)
3132

3233
public function execute(array $params = array(), $hydrationMode = null)
3334
{
35+
// always clone the original queryBuilder
36+
$queryBuilder = clone $this->queryBuilder;
37+
3438
// todo : check how doctrine behave, potential SQL injection here ...
3539
if ($this->getSortBy()) {
3640
$sortBy = $this->getSortBy();
3741
if (strpos($sortBy, '.') === false) { // add the current alias
38-
$sortBy = $this->queryBuilder->getRootAlias().'.'.$sortBy;
42+
$sortBy = $queryBuilder->getRootAlias().'.'.$sortBy;
3943
}
40-
$this->queryBuilder->orderBy($sortBy, $this->getSortOrder());
44+
$queryBuilder->orderBy($sortBy, $this->getSortOrder());
4145
}
4246

43-
return $this->queryBuilder->getQuery()->execute($params, $hydrationMode);
47+
return $this->getFixedQueryBuilder($queryBuilder)->getQuery()->execute($params, $hydrationMode);
48+
}
49+
50+
/**
51+
* This method alters the query to return a clean set of object with a working
52+
* set of Object
53+
*
54+
* @param \Doctrine\ORM\QueryBuilder $queryBuilder
55+
* @return void
56+
*/
57+
private function getFixedQueryBuilder(QueryBuilder $queryBuilder)
58+
{
59+
$queryBuilderId = clone $queryBuilder;
60+
61+
// step 1 : retrieve the targeted class
62+
$from = $queryBuilderId->getDQLPart('from');
63+
$class = $from[0]->getFrom();
64+
65+
// step 2 : retrieve the column id
66+
$idName = current($queryBuilderId->getEntityManager()->getMetadataFactory()->getMetadataFor($class)->getIdentifierFieldNames());
67+
68+
// step 3 : retrieve the different subjects id
69+
$select = sprintf('%s.%s', $queryBuilderId->getRootAlias(), $idName);
70+
$queryBuilderId->select($select);
71+
$results = $queryBuilderId->getQuery()->execute(array(), Query::HYDRATE_ARRAY);
72+
$idx = array();
73+
foreach($results as $id) {
74+
$idx[] = $id[$idName];
75+
}
76+
77+
// step 4 : alter the query to match the targeted ids
78+
$queryBuilder->andWhere(sprintf('%s IN (%s)', $select, implode(',', $idx)));
79+
$queryBuilder->setMaxResults(null);
80+
$queryBuilder->setFirstResult(null);
81+
82+
return $queryBuilder;
4483
}
4584

4685
public function __call($name, $args)

‎Model/ORM/ModelManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function getIdentifierValues($entity)
175175

176176
public function getIdentifierFieldNames($class)
177177
{
178-
$this->getMetadata($class)->getIdentifierFieldNames();
178+
return $this->getMetadata($class)->getIdentifierFieldNames();
179179
}
180180

181181
/**

0 commit comments

Comments
 (0)