2016-03-27 5 views
1

を提供する場合、私は機能を以下しているcreateQueryBuilderに条件を追加します。Doctrineは条件が

public function latestNews($tags = array(), $categories = array(), $authors = array(), $lang = 'en', $source = '', $limit = 20) { 
    return $this->createQueryBuilder('News') 
    ->field('tags')->in($tags) 
    ->field('categories')->in($category) 
    ->field('authors')->in($authors) 
    ->field('lang')->equals($lang) 
    ->sort('date' -> 'DESC') 
    ->field('source')->equals($source) 
    ->limit($limit) 
    ->getQuery() 
    ->execute(); 
} 

私が欲しい機能の呼び出し元によって提供されるこのような$tags$categories$authorsまたは$sourceのような変数は、この変数はcreateQueryBuilderに影響を与える場合が、それぞれの場合それらの関数呼び出し元(デフォルト値の変数)はcreateQueryBuilderに影響を与えず、この条件をクエリで中立にしません。 1つの方法は、多くのif条件でクエリを作成することですが、非常に面倒です。 もっと良い解決策はありますか?このような

答えて

3

何かがトリックを行う必要があります。

public function latestNews($tags = array(), $categories = array(), authors = array(), $lang = 'en', $source = '', $limit = 20) { 
    $inClauses = ['tags', 'categories', 'authors']; 
    $equalClauses = ['lang', 'source']; 
    $qb = $this->createQueryBuilder('News'); 

    foreach ($inClauses as $field) { 
     $realVar = ${$field}; 

     if (!empty($realVar)) { 
      $qb->field($field)->in($realVar); 
     } 
    } 

    foreach ($equalClauses as $field) { 
     $realVar = ${$field}; 

     if ($realVar) { 
      $qb->field($field)->equals($realVar); 
     } 
    } 

    return $qb 
     ->sort('date' -> 'DESC') 
     ->limit($limit) 
     ->getQuery() 
     ->execute(); 
} 

ビット醜いが、私は任意のより良い代替手段が表示されません。

1

chalasrの応答は良いですが、コード重複(DRY)を避けるために、ビルド条件のロジックを特定の特性に抽出することをお勧めします。

あなたのような何かを行うことができます。そして、

<?php 

namespace Xthiago\My\Path; 

use \Doctrine\DBAL\Query\QueryBuilder; 

trait DoctrineQueryHelper 
{ 
    public function in(QueryBuilder $qb, array $filter, $field) 
    { 
     if (empty($filter[$field])) { 
      return $this; 
     } 

     $qb->field($field)->in($filter[$field]); 

     return $this; 
    } 

    public function equals(QueryBuilder $qb, array $filter, $field) 
    { 
     if (empty($filter[$field])) { 
      return $this; 
     } 

     $qb->field($field)->equals($filter[$field]); 

     return $this; 
    } 

    public function lang(QueryBuilder $qb, $value = 'en') 
    { 
     $qb->field('lang')->equals($value); 

     return $this; 
    } 

    public function limit(QueryBuilder $qb, $value = 20) 
    { 
     $qb->limit($value); 

     return $this; 
    } 

    // you can create a lot of helper methods here in order to avoid duplicity. 
} 

このように形質のク​​ラスのメーク使用:

<?php 

namespace Xthiago\My\Path; 

use \Doctrine\DBAL\Query\QueryBuilder; 

class NewsRepository 
{ 
    use DoctrineQueryHelper; 

    /** 
    * @param array $filter as follow: 
    * <code> 
    * [ 
    * 'tags' => [], 
    * 'categories' => [], 
    * 'authors' => [], 
    * 'lang' => 'en', 
    * 'source' => '', 
    * 'limit' => 20, 
    * ] 
    * </code> 
    * 
    * @return array with results. 
    */ 
    public function latestNews(array $filter = []) 
    { 
     $qb = $this->createQueryBuilder('News'); 

     $this->in($qb, $filter, 'tags') 
      ->in($qb, $filter, 'categories') 
      ->in($qb, $filter, 'authors') 
      ->equals($qb, $filter, 'source') 
      ->lang($qb, $filter) 
      ->limit($qb, $filter); 

     return $qb->sort('date', 'DESC') 
        ->getQuery() 
        ->execute(); 
    } 
}