2016-03-27 7 views
1
versehen

ich folgende Funktion haben:Lehre Bedingung createQueryBuilder hinzufügen, wenn Bedingung

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(); 
} 

Ich möchte, wenn Variablen wie $tags, $categories, $authors oder $source durch Funktion Anrufer sofern diese Variablen auf die createQueryBuilder beeinflussen, aber wenn jeder von ihnen bietet nicht von der Funktion Aufrufer (Variable mit Standardwert) sie nicht beeinflussen createQueryBuilder und machen diese Bedingung neutral auf Abfrage. Eine Möglichkeit ist, die Abfrage mit vielen, wenn Bedingung, aber es ist sehr chaotisch. Gibt es eine bessere Lösung?

Antwort

3

So etwas sollte es tun:

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(); 
} 

Ein bisschen hässlich, aber ich habe keine bessere Alternative.

1

Die Antwort des Chalasr ist gut, aber ich schlage vor, die Logik der Build-Bedingungen zu einem bestimmten Merkmal zu extrahieren, so dass Sie Code-Duplizierung (DRY) vermeiden.

Sie können so etwas wie tun:

<?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. 
} 

Dann Ihre Klasse nutzen die Eigenschaft auf diese Weise:

<?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(); 
    } 
}