Php SilverStripe-自定义分面搜索导航
我正在为一个SilverStripe页面工作,该页面允许用户根据选定的方面对公文包进行排序 以下是要点/要求:Php SilverStripe-自定义分面搜索导航,php,jquery,mysql,ajax,silverstripe,Php,Jquery,Mysql,Ajax,Silverstripe,我正在为一个SilverStripe页面工作,该页面允许用户根据选定的方面对公文包进行排序 以下是要点/要求: 我有两个方面的类别,他们可以搜索:媒体类型(即广告, 海报、电视、网络)和行业(娱乐、金融、医疗、, 体育等) 应该允许用户同时搜索多个方面,并且 同时跨越媒体类型和行业 在SilverStripe管理员中,因为内容管理器需要能够 为了维护媒体类型和行业的方面名称,我这样做了 有两个管理员模型可以输入名称: MediaTypeTagAdmin和IndustryTagAdmin。下面是
- 我有两个方面的类别,他们可以搜索:媒体类型(即广告, 海报、电视、网络)和行业(娱乐、金融、医疗、, 体育等)
- 应该允许用户同时搜索多个方面,并且 同时跨越媒体类型和行业
- 在SilverStripe管理员中,因为内容管理器需要能够 为了维护媒体类型和行业的方面名称,我这样做了 有两个管理员模型可以输入名称: MediaTypeTagAdmin和IndustryTagAdmin。下面是数据对象 管理员使用的MediaTypeTag和IndustryTag类 型号:
<?php
class MediaTypeTag extends DataObject {
private static $db = array(
'Name' => 'varchar(250)',
);
private static $summary_fields = array(
'Name' => 'Title',
);
private static $field_labels = array(
'Name'
);
private static $belongs_many_many = array(
'PortfolioItemPages' => 'PortfolioItemPage'
);
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeByName("PortfolioItemPages");
return $fields;
}
static $default_sort = "Name ASC";
}
我认为最好的方法是使用jQuery和AJAX将所选方面的ID发送到服务器:
(function($) {
$(document).ready(function() {
var industry = $('.industry');
var media = $('.media');
var tag = $('.tag');
var selectedTags = "";
tag.each(function(e) {
$(this).bind('click', function(e) {
e.preventDefault();
$(this).addClass('selectedTag');
if(selectedTags.indexOf($(this).text()) < 0){
if($(this).hasClass('media')){
selectedTags += + $(this).attr("id") + "," +"media;";
}
else{
selectedTags += + $(this).attr("id") + "," +"industry;";
}
}
sendTag(selectedTags);
}.bind($(this)));
});
function sendTag(TagList){
$.ajax({
type: "POST",
url: "/home/getPortfolioItemsByTags/",
data: { tags: TagList },
dataType: "json"
}).done(function(response) {
var div = $('.portfolioItems');
div.empty();
for (var i=0; i<response.length; i++){
div.append(response[i].name + "<br />");
//return portfolio data here
}
})
.fail(function() {
alert("There was a problem processing the request.");
});
}
});
}(jQuery));
然而,这就是我陷入困境的地方。虽然我已经找到了一些在CMS之外构建PHP/MySQL分面搜索的不错的例子,但我不确定我可以修改什么以使搜索在CMS内工作。这些示例将facet放在MySQL数据库中的一个表中,而我有两个表(虽然我希望媒体类型和行业facet都有一个MySQL表,但我不确定这是否是一个好主意,因为内容经理希望自己维护facet名称)
是否有任何教程可以提供进一步的帮助,或者可能是我还没有找到的插件?如果有更好的方法来设置此分面搜索,请务必提出建议。这对我来说是相当新鲜的 最有效的方法是在一个查询中根据标记/媒体类型ID进行过滤(您的示例是对每个标记/类型执行一个数据库查询,然后追加结果) 您应该能够执行以下操作:
<?php
public function getPortfolioItemsByTags(){
$tagString = $this->getRequest()->postVar('tags');
// remove the last comma from the list of tag ids
$tagString = substr($tagString, 0, -1);
//put the tag ids and their tag names (media or industry) into an array
$tags = explode(";", $tagString);
//This will hold the associative array of ids to types (i.e. 34 => media)
$filters = array(
'media' => array(),
'industry' => array()
);
array_walk($tags, function($val, $key) use(&$filters) {
list($id, $type) = explode(',', $val);
$filters[$type][] = $id;
});
$portfolioItems = PortfolioItemPage::get()->filterAny(array(
'MediaTypeTags.ID' => $filters['media'],
'IndustryTags.ID' => $filters['industry']
));
$return = array();
foreach($portfolioItems as $portfolioItem){
$return[] = array(
'thumbnail' => $portfolioItem->Thumbnail()->Link(),
'name' => $portfolioItem->H1,
'logo' => $portfolioItem->Logo()->Link(),
'excerpt' => $portfolioItem->Excerpt,
'id' => $portfolioItem->ID
);
}
return json_encode($return);
}
我想这就是我需要的。我试了一下,它看起来就像我需要的那样工作。谢谢!:)
(function($) {
$(document).ready(function() {
var industry = $('.industry');
var media = $('.media');
var tag = $('.tag');
var selectedTags = "";
tag.each(function(e) {
$(this).bind('click', function(e) {
e.preventDefault();
$(this).addClass('selectedTag');
if(selectedTags.indexOf($(this).text()) < 0){
if($(this).hasClass('media')){
selectedTags += + $(this).attr("id") + "," +"media;";
}
else{
selectedTags += + $(this).attr("id") + "," +"industry;";
}
}
sendTag(selectedTags);
}.bind($(this)));
});
function sendTag(TagList){
$.ajax({
type: "POST",
url: "/home/getPortfolioItemsByTags/",
data: { tags: TagList },
dataType: "json"
}).done(function(response) {
var div = $('.portfolioItems');
div.empty();
for (var i=0; i<response.length; i++){
div.append(response[i].name + "<br />");
//return portfolio data here
}
})
.fail(function() {
alert("There was a problem processing the request.");
});
}
});
}(jQuery));
public function getPortfolioItemsByTags(){
//remove the last comma from the list of tag ids
$IDs = $this->getRequest()->postVar('tags');
$IDSplit = substr($IDs, 0, -1);
//put the tag ids and their tag names (media or industry) into an array
$IDListPartial = explode(";",$IDSplit);
//This will hold the associative array of ids to types (i.e. 34 => media)
$IDListFinal = array();
array_walk($IDListPartial, function($val, $key) use(&$IDListFinal){
list($key, $value) = explode(',', $val);
$IDListFinal[$key] = $value;
});
//get Portfolio Items based on the tag ids and tag type
foreach($IDListFinal as $x => $x_value) {
if($x_value=='media'){
$tag = MediaTypeTag::get()->byId($x);
$portfolioItems = $tag->PortfolioItemPages();
}
else{
$tag = IndustryTag::get()->byId($x);
$portfolioItems = $tag->PortfolioItemPages();
}
$return = array();
foreach($portfolioItems as $portfolioItem){
$return[] = array(
'thumbnail' => $portfolioItem->Thumbnail()->Link(),
'name' => $portfolioItem->H1,
'logo' => $portfolioItem->Logo()->Link(),
'excerpt' => $portfolioItem->Excerpt,
'id' => $portfolioItem->ID
);
}
return json_encode($return);
}
}
<?php
public function getPortfolioItemsByTags(){
$tagString = $this->getRequest()->postVar('tags');
// remove the last comma from the list of tag ids
$tagString = substr($tagString, 0, -1);
//put the tag ids and their tag names (media or industry) into an array
$tags = explode(";", $tagString);
//This will hold the associative array of ids to types (i.e. 34 => media)
$filters = array(
'media' => array(),
'industry' => array()
);
array_walk($tags, function($val, $key) use(&$filters) {
list($id, $type) = explode(',', $val);
$filters[$type][] = $id;
});
$portfolioItems = PortfolioItemPage::get()->filterAny(array(
'MediaTypeTags.ID' => $filters['media'],
'IndustryTags.ID' => $filters['industry']
));
$return = array();
foreach($portfolioItems as $portfolioItem){
$return[] = array(
'thumbnail' => $portfolioItem->Thumbnail()->Link(),
'name' => $portfolioItem->H1,
'logo' => $portfolioItem->Logo()->Link(),
'excerpt' => $portfolioItem->Excerpt,
'id' => $portfolioItem->ID
);
}
return json_encode($return);
}