2009-10-14 16 views
5

Trình nghe của tôi là một phần của hành vi, nên xóa tất cả các kiểm tra is_published trong mệnh đề where của bất kỳ truy vấn chọn nào được gọi. Việc thêm một phần vào một mệnh đề thực sự dễ dàng, nhưng làm thế nào để loại bỏ một mệnh đề.Học thuyết: Cách loại bỏ một phần của mệnh đề where từ truy vấn chọn bên trong người nghe (preDqlSelect)?

Có một số chức năng như Doctrine_Query->removeDqlQueryPart('where'), nhưng mà loại bỏ hoàn chỉnh mệnh đề where, trong khi tôi chỉ cần 'is_published = ?' phần phải được loại bỏ.

Tuy nhiên, tôi có thể xử lý thủ công bằng cách nào đó bằng regex hoặc thứ gì đó. Nhưng phần khó khăn là, làm thế nào để loại bỏ các tham số đại diện bởi '?' từ mảng tham số tương ứng (có thể truy xuất bởi Doctrine_Query->getRawParams()).

Vì vậy, tôi hỏi, có cách nào sạch để chuyển đổi loại truy vấn:
...FROM Video v WHERE v.is_published = ? AND v.start_date < ? AND v.end_date > ?

này tước một và không rối tung lên các params đại diện bởi các dấu hỏi:
...FROM Video v WHERE v.start_date < ? AND v.end_date > ?

Đây tất nhiên chỉ là một ví dụ đơn giản, các truy vấn của tôi phức tạp hơn một chút. Thật không may là tôi bị mắc kẹt với doctrine 1.0.x vì khung công tác symfony.

Trả lời

6

Gọi $query->getDqlPart('where') sẽ trả lại một array của các phần của mệnh đề where khi chúng được thêm vào thông qua các hàm where(), andWhere(), v.v. Vì vậy, bạn có thể sử dụng để tìm và loại bỏ phần bạn muốn.

Sau đó, bạn phải xử lý các thông số. Trong khi đi xe đạp qua những nơi mà bạn sẽ cần phải tìm tất cả? và đếm chúng và ghi nhớ những con số cho bất kỳ những người bạn loại bỏ và sau đó gọi $params = $query->getParams(); và nơi các thông số điều khoản sẽ được ở $params['where'] để bạn có thể loại bỏ chúng khỏi đó và sau đó gọi $query->setParams($params);

5

Dựa Joshua Coady trả lời

$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

Cảm ơn vì điều đó. Ví dụ đi một chặng đường dài :) – Aeolun

+0

tận hưởng và tận hưởng :) –

+0

Giải pháp này hoạt động cho mệnh đề "where" nhưng không ví dụ mệnh đề "groupBy": Trong trường hợp này getParts() phải được thay thế bằng: ... $ qb_group_by_part = $ qb-> getDqlPart ('groupBy'); $ qb_group_by_part = isset ($ qb_group_by_part ["phần"])? $ qb_group_by_part ["parts"]: mảng(); .. – Tsounabe