2009-10-14 9 views
5

Mein Listener ist Teil eines Verhaltens, das alle is_published-Prüfungen in der WHERE-Klausel einer beliebigen aufgerufenen SELECT-Abfrage entfernen sollte. Es ist wirklich einfach, ein Teil zu einer Klausel hinzuzufügen, aber wie man es entfernt.Lehre: Wie man Teil einer where-Klausel von der auserwählten Abfrage innerhalb des Zuhörers entfernt (preDqlSelect)?

Es gibt einige Funktionen wie Doctrine_Query->removeDqlQueryPart('where'), , aber das entfernt die komplette Where-Klausel, während ich nur den 'is_published = ?' Teil entfernt werden muss.

Allerdings könnte ich das manuell irgendwie, mit Regex oder so etwas. Aber der schwierige Teil ist, wie man den durch das '?' Dargestellten Parameter entfernt. aus dem entsprechenden Parameter-Array (abrufbar unter Doctrine_Query->getRawParams()).

Also frage ich, ist es eine saubere Art und Weise, diese Art von Abfrage zu transformieren:
...FROM Video v WHERE v.is_published = ? AND v.start_date < ? AND v.end_date > ?

zu diesem abgezogen und ohne die params durch die Fragezeichen dargestellt vermasselt:
...FROM Video v WHERE v.start_date < ? AND v.end_date > ?

Dies ist natürlich nur ein einfaches Beispiel, meine Abfragen sind etwas komplexer. Leider bin ich wegen des Symfony-Frameworks mit Doktrin 1.0.x festgefahren.

Antwort

6

$query->getDqlPart('where') Aufruf wird eine array der Teile der Where-Klausel zurück, wie sie über die where(), andWhere() hinzugefügt wurden, etc Funktionen. So können Sie den gewünschten Teil finden und entfernen.

Dann müssen Sie sich mit den Parametern beschäftigen. Beim Radfahren durch die Teile, die Sie alle finden müssten? und zähle sie und denken Sie daran, die Zahlen für alle die, die Sie entfernen, und dann rufen $params = $query->getParams(); und die where-Klausel Parameter in $params['where'] sein, so können Sie sie entfernen von dort aus und rufen Sie dann $query->setParams($params);

5

Based Joshua Coady Antwort

$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')); 
+0

Danke dafür. Beispiele gehen einen langen Weg :) – Aeolun

+0

genießen und genießen :) –

+0

Diese Lösung funktioniert für die "where" -Klausel aber nicht zum Beispiel die "groupBy" -Klausel: In diesem Fall sollte die getParts() ersetzt werden durch: ... $ qb_group_by_part = $ qb-> getDqlPart ('groupBy'); $ qb_group_by_part = isset ($ qb_group_by_part ["Teile"])? $ qb_group_by_part ["Teile"]: array(); .. – Tsounabe