2009-10-14 15 views
5

Il mio listener fa parte di un comportamento che dovrebbe rimuovere tutti i controlli is_published nella clausola where di qualsiasi query di selezione chiamata. Aggiungere una parte a una clausola è davvero semplice, ma come rimuoverne una.Doctrine: come rimuovere parte di una clausola where da select query inside listener (preDqlSelect)?

Ci sono alcune funzioni come Doctrine_Query->removeDqlQueryPart('where'), ma che rimuove la clausola where completa, mentre ho solo bisogno della parte 'is_published = ?' da rimuovere.

Tuttavia ho potuto gestire manualmente in qualche modo, con regex o qualcosa del genere. Ma la parte difficile è, come rimuovere il parametro rappresentato dal '?' dalla matrice dei parametri corrispondenti (recuperabile da Doctrine_Query->getRawParams()).

Quindi chiedo, c'è un modo pulito per trasformare questo tipo di query:
...FROM Video v WHERE v.is_published = ? AND v.start_date < ? AND v.end_date > ?

a questo spogliato uno e senza rovinare i params rappresentati dai punti interrogativi:
...FROM Video v WHERE v.start_date < ? AND v.end_date > ?

Questo è ovviamente solo un semplice esempio, le mie domande sono un po 'più complesse. Sfortunatamente sono bloccato con doctrine 1.0.x a causa del framework symfony.

risposta

6

Calling $query->getDqlPart('where') restituirà un array delle parti della clausola in cui come sono stati aggiunti tramite il where(), andWhere(), ecc funzioni. Quindi puoi usarlo per trovare e rimuovere la parte che desideri.

Quindi devi gestire i parametri. Mentre percorri in bici le parti dove dovresti trovare tutto? e li contare e ricordare i numeri per qualsiasi di quelli che rimuovere e quindi chiamare $params = $query->getParams(); e la cui parametri clausola saranno in $params['where'] modo da poter rimuovere da lì e quindi chiamare $query->setParams($params);

5

Based Joshua Coady risposta

$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

Grazie per quello. Esempi andare un lungo cammino :) – Aeolun

+0

godere e godere :) –

+0

Questa soluzione funziona per il "dove" clausola, ma non ad esempio la clausola "groupBy": In questo caso i getParts() dovrebbe essere sostituito da: ... $ qb_group_by_part = $ qb-> getDqlPart ('groupBy'); $ qb_group_by_part = isset ($ qb_group_by_part ["parts"])? $ qb_group_by_part ["parts"]: array(); .. – Tsounabe