Cakephp CakeDC搜索和标记插件-搜索多个标记
希望我错过了一些简单的东西。我正在为我的cake(2.3.4)应用程序使用CakeDC搜索和标签插件 除了一般的按字段搜索功能外,我希望用户能够按标签进行搜索。我几乎可以做到这一点,但如果搜索单个标记而不是多个标记,搜索将只显示结果。例如,如果我添加一篇带有以下标记的文章-黑色、白色、红色。这篇文章将只显示在搜索结果中,如果我搜索一个标签(比如说,黑色),而不是全部3,甚至2。。。我错过了什么 这是我的密码: Article.php模型Cakephp CakeDC搜索和标记插件-搜索多个标记,cakephp,cakedc,Cakephp,Cakedc,希望我错过了一些简单的东西。我正在为我的cake(2.3.4)应用程序使用CakeDC搜索和标签插件 除了一般的按字段搜索功能外,我希望用户能够按标签进行搜索。我几乎可以做到这一点,但如果搜索单个标记而不是多个标记,搜索将只显示结果。例如,如果我添加一篇带有以下标记的文章-黑色、白色、红色。这篇文章将只显示在搜索结果中,如果我搜索一个标签(比如说,黑色),而不是全部3,甚至2。。。我错过了什么 这是我的密码: Article.php模型 class Article extends AppMode
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方法调试$query,我会得到以下结果:
'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')
谢谢使用“方法”键将搜索参数传递给自定义方法
这里的示例向您展示了它的工作原理
在您的自定义方法中,分解()标记并使其成为一个数组,以便CakePHP使用它们作为IN()或更好的方法(IN可能会变慢),使其成为一个and或or链。使用“method”键将搜索参数传递给自定义方法
这里的示例向您展示了它的工作原理
在您的自定义方法中,分解()标记并使其成为一个数组,以便CakePHP使用它们作为IN()或更好的方法(IN可能会变慢),使其成为一个and或or链。提示:
$this->set('emptySeach',false)代码>内容不是必需的。在进行搜索时,插件本身已经将变量向下传递给视图:$this->controller->set('isSearch',$this->isSearch)代码>@马克谢谢。我想我需要向findByTags函数添加某种类型的OR过滤器。提示:$this->set('emptySeach',false)代码>内容不是必需的。在进行搜索时,插件本身已经将变量向下传递给视图:$this->controller->set('isSearch',$this->isSearch)代码>@马克谢谢。我想我需要在findByTags函数中添加某种OR过滤器。
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;
}