Doctrine: Comment enlever une partie d'une clause where de requête de sélection à l'intérieur de l'auditeur (preDqlSelect)?
Question
Mon auditeur fait partie d'un comportement, qui devrait supprimer tous les contrôles is_published dans la clause where d'une requête de sélection appelée. Ajout d'une partie à une clause est vraiment facile, mais comment supprimer un.
Il y a quelques fonctions comme Doctrine_Query->removeDqlQueryPart('where')
,
mais supprime la clause where complète, alors que je ne ai besoin la partie 'is_published = ?'
à supprimer.
Cependant, je pouvais gérer manuellement en quelque sorte, avec regex ou quelque chose. Mais la partie la plus délicate est, comment supprimer le paramètre représenté par le « ? » à partir de la matrice de paramètres correspondant (récupérable par Doctrine_Query->getRawParams()
).
Je demande donc, est-il un moyen propre de transformer ce genre de requête:
...FROM Video v WHERE v.is_published = ? AND v.start_date < ? AND v.end_date > ?
à ce dépouillèrent un et sans déconner les params représentés par les points d'interrogation:
...FROM Video v WHERE v.start_date < ? AND v.end_date > ?
Ceci est bien sûr qu'un simple exemple, mes questions sont un peu plus complexes. Malheureusement, je suis coincé avec 1.0.x doctrine à cause du framework symfony.
La solution
L'appel $query->getDqlPart('where')
renverra une array
des parties de la clause where ils ont été ajoutés par le where()
, andWhere()
, etc fonctions. Ainsi, vous pouvez l'utiliser pour trouver et supprimer la partie que vous voulez.
Ensuite, vous devez traiter les params. Alors que le vélo à travers les pièces où vous auriez besoin de trouver tous? et les compter et rappelez-vous les chiffres pour l'un de ceux que vous retirez puis appelez $params = $query->getParams();
et où les paramètres de la clause seront $params['where']
afin que vous puissiez les enlever de là puis appeler $query->setParams($params);
Autres conseils
D'après Joshua Coady Réponse
$qb = <query builder>;
$qb_where_part = $qb->getDqlPart('where')->getParts();
$qb->resetDQLPart('where');
// we know by dumping that it is an and operator in our case, generic way shoud take op in account
//var_dump($qb->getDqlPart('where'));
foreach ($qb_where_part as $where_clause) {
if ('o.date > :date_debut' === $where_clause) continue;
$qb->andWhere($where_clause);
}
$params = $qb->getParameters();
$new_date_fin = null;
foreach ($params as $key => $param) {
if ($param->getName() === 'date_debut') {
$new_date_fin = $param->getValue();
$params->remove($key);
}
if ($param->getName() === 'date_fin' && $new_date_fin) {
$param->setValue($new_date_fin);
//var_dump($param->getValue());
}
}
$qb->setParameters($params);
var_dump($qb->getParameters());
var_dump($qb->getDqlPart('where'));