2013-05-29 153 views
1

希望我在這裏錯過簡單的東西。我爲我的蛋糕(2.3.4)應用程序使用CakeDC Search和Tags插件。CakeDC搜索和標籤插件 - 搜索多個標籤

除了通過字段功能進行通用搜索,我希望用戶能夠通過標籤進行搜索。我幾乎可以正常工作,但是如果您搜索的是單個標籤而不是多個標籤,搜索將僅顯示結果。例如,如果我添加一個包含以下標籤的文章 - 黑色,白色,紅色。這篇文章只會在搜索結果中顯示,如果我搜索一個標籤(例如黑色),而不是全部3個,甚至是2個......我錯過了什麼?

繼承人我的代碼:

Article.php模型

class Article extends AppModel { 
public $actsAs = array(
    'Upload.Upload' => array(
     'screenshot1' => array (
      'fields' => array (
       'dir' => 'dir' 
      ), 
      'thumbnailMethod' => 'php', 
      'thumbnailSizes' => array(
       'xvga' => '1024x768', 
       'vga' => '640x480', 
       'thumb' => '80x80' 
      ), 
     ), 
    ), 
'Search.Searchable', 
'Tags.Taggable' 

); 

// Search plugin filters 
public $filterArgs = array(  
    'title' => array('type' => 'like'), 
    'environment' => array('type' => 'like'), 
    'description' => array('type' => 'like'), 
    'error' => array('type' => 'like'), 
    'cause' => array('type' => 'like'), 
    'resolution' => array('type' => 'like'), 
    'live' => array('type' => 'value'), 
    'synced' => array('type' => 'value'), 
    'tags' => array('type' => 'subquery', 'method' => 'findByTags', 'field' => 'Article.id'), 
    array('name' => 'search', 'type' => 'query', 'method' => 'filterQuery'), 
); 

// This is the OR query that runs when the user uses the client side signle field search 
public function filterQuery($data = array()) { 
    if(empty($data['search'])) { // search is the name of my search field 
     return array(); 
    } 

    $query = '%'.$data['search'].'%'; 
    return array(
     'OR' => array(
      'Article.title LIKE' => $query, 
      'Article.description LIKE' => $query, 
      'Article.error LIKE' => $query, 
      ) 
     ); 
} 

// Find by tags method 
public function findByTags($data = array()) { 
    $this->Tagged->Behaviors->attach('Containable', array('autoFields' => false)); 
    $this->Tagged->Behaviors->attach('Search.Searchable'); 
    $query = $this->Tagged->getQuery('all', array(
     'conditions' => array('Tag.name' => $data['tags']), 
     'fields' => array('foreign_key'), 
     'contain' => array('Tag') 
    )); 
    return $query; 
} 

public $hasAndBelongsToMany = array(
    'Category' => array(
     'className' => 'Category', 
     'joinTable' => 'articles_categories', 
     'foreignKey' => 'article_id', 
     'associationForeignKey' => 'category_id', 
     'unique' => 'keepExisting', 
     'conditions' => '', 
     'fields' => '', 
     'order' => '', 
     'limit' => '', 
     'offset' => '', 
     'finderQuery' => '', 
     'deleteQuery' => '', 
     'insertQuery' => '' 
    ), 
    'Tag' => array('with' => 'Tagged') 
); 

控制方法

public function admin_advancedSearch() { 

     // Disable validation for this action 
     $this->Article->validate = array(); 

     // For search plugin 
     $this->Prg->commonProcess(); 

     // Set searched for details 
     $this->set('searchedFor', $this->passedArgs); 

     // If passed args are all empty 
     if ($this->passedArgs) { 

      if (empty($this->passedArgs['title']) AND 
       empty($this->passedArgs['environment']) AND 
       empty($this->passedArgs['description']) AND 
       empty($this->passedArgs['error']) AND 
       empty($this->passedArgs['cause']) AND 
       empty($this->passedArgs['resolution']) AND 
       empty($this->passedArgs['live']) AND 
       empty($this->passedArgs['synced']) AND 
       empty($this->passedArgs['tags'])) { 

        $this->Session->setFlash('Please enter at least one search criteria', 'flash_failure'); 
        // Set this var for checks in view 
        $this->set('emptySeach', true); 
      } else { 

       $paginateConditions = $this->Article->parseCriteria($this->passedArgs); 
       $this->paginate = array('conditions' => array(
              $paginateConditions), 
             'limit' => 10, 
             'order' => array('Article.modified' => 'DESC'));    
       $this->set('articles', $this->paginate()); 

       // Count number of results 
       $count = 0; 
       foreach ($this->paginate() as $result) { 
        $count++; 
       } 

       $this->set('resultsCount', $count); 

       // Search was not empty - set flag for view 
       $this->set('emptySeach', false); 
      } 
     } 

     // Set layout 
     $this->layout = 'admin'; 

     //debug($this->passedArgs); 
    } 

所有的插件都從引導加載成功,搜索內容,而標籤做工精細。使用標籤搜索只有在輸入一個標籤工作....

* 編輯* 如果我調試從findByTags方法$查詢我得到這個:

'SELECT `Tagged`.`foreign_key` FROM `knowledgebase`.`tagged` AS `Tagged` LEFT JOIN `knowledgebase`.`tags` AS `Tag` ON (`Tagged`.`tag_id` = `Tag`.`id`) WHERE `Tag`.`name` = 'kia, rio, red'' 

所以它看起來像它的嘗試找到一個名稱中包含所有搜索標籤的標籤。我怎樣才能使WHERE部分成爲IN?

例如:

WHERE `Tag`.`name` IN ('kia', 'rio', 'red') 

感謝

+0

提示:'$ this-> set('emptySeach',false);'東西沒有必要。在搜索時,插件本身已經將一個變量傳遞給視圖:'$ this-> controller-> set('isSearch',$ this-> isSearch);' – mark

+0

@mark謝謝。我想我需要添加某種OR過濾器到findByTags函數。 –

回答

1

使用 「方法」 https://github.com/cakedc/search#behavior-and-model-configuration關鍵她搜索ARGS傳遞給定製方法。

這裏的示例顯示了這是怎樣工作https://github.com/cakedc/search#full-example-for-modelcontroller-configuration-with-overriding

public $filterArgs = array(
    'some_related_table_id' => array('type' => 'value'), 
    'search'=> array('type' => 'like', 'encode' => true, 'before' => false, 'after' => false, 'field' => array('ThisModel.name', 'OtherModel.name')), 
    'name'=> array('type' => 'query', 'method' => 'searchNameCondition') 
); 

public function searchNameCondition($data = array()) { 
    $filter = $data['name']; 
    $cond = array(
     'OR' => array(
      $this->alias . '.name LIKE' => '' . $this->formatLike($filter) . '', 
      $this->alias . '.invoice_number LIKE' => '' . $this->formatLike($filter) . '', 
    )); 
    return $cond; 
} 

內,您的自定義的方法爆炸()的標籤和使CakePHP會使用它們作爲IN()或更好地使他們的陣列(罐頭變得緩慢)使其成爲AND或OR的鏈。