2009-10-14 10 views
5

Mi escucha forma parte de un comportamiento que debería eliminar todas las comprobaciones is_published en la cláusula where de cualquier consulta de selección llamada. Agregar una parte a una cláusula es realmente fácil, pero cómo eliminar una.Doctrine: ¿Cómo eliminar parte de una cláusula where de la consulta de selección dentro del oyente (preDqlSelect)?

Existen algunas funciones como Doctrine_Query->removeDqlQueryPart('where'), pero eso elimina la cláusula where completa, mientras que solo necesito que se elimine la parte 'is_published = ?'.

Sin embargo, podría manejar esto manualmente de alguna manera, con expresiones regulares o algo así. Pero la parte difícil es cómo eliminar el parámetro representado por el '?' de la matriz de parámetros correspondiente (recuperable por Doctrine_Query->getRawParams()).

por lo que pido, es que hay una manera limpia para transformar este tipo de consulta:
...FROM Video v WHERE v.is_published = ? AND v.start_date < ? AND v.end_date > ?

a esta despojado uno y sin alterar los parametros representados por los signos de interrogación:
...FROM Video v WHERE v.start_date < ? AND v.end_date > ?

Esto es, por supuesto, solo un simple ejemplo, mis consultas son un poco más complejas. Lamentablemente, estoy atascado con la doctrina 1.0.x debido a la estructura de Symfony.

Respuesta

6

Calling $query->getDqlPart('where') devolverá un array de las partes de la cláusula where, ya que se han añadido a través de la where(), andWhere(), etc funciones. Entonces puede usar eso para encontrar y eliminar la pieza que desea.

Luego tiene que lidiar con los params. ¿Mientras recorre las partes donde debería encontrar todo? y contarlos y recordar los números para cualquiera de los que quitar y volver a llamar $params = $query->getParams(); y donde los parámetros cláusula estarán en $params['where'] para que pueda sacarlos de allí y luego llamar $query->setParams($params);

5

basado en Joshua Coady respuesta

$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

Gracias por eso. Los ejemplos van un largo camino :) – Aeolun

+0

disfruta y disfruta :) –

+0

Esta solución funciona para la cláusula "where" pero no por ejemplo la cláusula "groupBy": en este caso los getParts() deberían reemplazarse por: ... $ qb_group_by_part = $ qb-> getDqlPart ('groupBy'); $ qb_group_by_part = isset ($ qb_group_by_part ["parts"])? $ qb_group_by_part ["parts"]: array(); .. – Tsounabe

Cuestiones relacionadas