Je crée un paquet de messages dans lequel les messages sont regroupés par contacts. Sur ma page d'index, j'affiche différents threads. Lorsque vous cliquez sur un fil de discussion, tous les messages échangés entre vous et votre contact s'affichent. J'utilise un générateur de requêtes pour afficher les threads sur ma page d'index:
$qb = $this->createQueryBuilder('m')
->where('m.from = ?1 or m.to = ?1')
->groupBy('m.to, m.from')
->orderBy('m.date', 'DESC')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
Si j'ai 3 entrées, par exemple:
+----+------+----+
| id | from | to |
+----+------+----+
| 1 | 1 | 2 |
+----+------+----+
| 2 | 2 | 1 |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
Je m'attends à:
+----+------+----+
| id | from | to |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
Mais je reçois:
+----+------+----+
| id | from | to |
+----+------+----+
| 2 | 2 | 1 |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
J'ai trouvé un moyen de le faire avec SQL, en utilisant le même alias pour from_id et to_id:
SELECT id, from_id as c, to_id as c FROM Message WHERE c = 1 GROUP BY from_id, to_id
Mais je ne sais pas comment faire avec Doctrine.
MODIFIER:
En attendant d'avoir une meilleure idée, j'utilise une touche pour "grouper par" facilement.
// entity
/**
* @ORM\Column(name="key", type="string", length=40)
*/
private $key;
/**
* @ORM\PrePersist()
*/
public function setOnPrePersist()
{
if($this->from < $this->to) {
$key = $this->from . 't' . $this->to;
} else {
$key = $this->to . 't' . $this->from;
}
$this->key = $key;
}
// query builder
$qb = $this->createQueryBuilder('m')
->where('m.from = ?1 or m.to = ?1')
->groupBy('m.key')
->orderBy('m.date', 'DESC')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
return $qb->getQuery()->getResult();
dans le cas où vous avez plusieurs colonnes dans 'group by', vous devez utiliser la méthode addGroupBy ().
$qb = $this->createQueryBuilder('m')
->where('m.from = ?1 or m.to = ?1')
->groupBy('m.to')
->addGroupBy('m.from')
->orderBy('m.date', 'DESC')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
:)
Essayez ce qui suit en utilisant la méthode doctrine DQL -
$query = $em->createQuery("SELECT m.id, m.from_id as c, m.to_id as c FROM AcmeDemoBunlde:Message as m WHERE m.c = 1 GROUP BY m.from_id, m.to_id");
$messageDetails = $query->getResult();
Au lieu de AcmeDemoBundle replace avec le nom de votre bundle approprié.