我有一个Expression Engine站点,其中包含以下要求。
我需要能够通过一对匹配字段过滤频道条目结果集,例如我的条目将有一个field_a和field_b。如果这些字段匹配,我希望它成为返回结果集的一部分。我不能在前端检查,因为结果计数不正确。我以为我可以使用钩子将字段传入exp:channel:entries标签并更改返回的数据。
这看起来是否合理?如果有的话,是否有人知道操纵该数据的细节?看看doc我想我想使用'channel_entries_query_result'钩子,但我不确定如何实际操作数据。我已经创建了正常触发的钩子,我可以看到模板tag_data等,但我不知道下一步该去哪里。
由于
答案 0 :(得分:2)
您可以编写自己的模块,扩展频道条目循环。
您可以这样使用它:
{exp:custom_module:entries}
此方法支持任何默认参数。
模块中的方法如下所示:
public function entries()
{
if( ! class_exists('Channel'))
{
require_once PATH_MOD.'channel/mod.channel.php';
}
// queries grabbing entry ids you want
....
$this->EE->TMPL->tagparams['entry_id'] = implode('|', $entry_ids);
$channel = new Channel();
$tagdata = $channel->entries();
return $tagdata;
}
答案 1 :(得分:0)
这听起来像是需要自定义查询,你不会使用任何EEs钩子来实现这一点。
您可以编写自己的插件/模块,也可以使用EE的本机查询模块。
您只需要将两列与您的查询进行比较即可。例如:
SELECT
*
FROM
some_table
WHERE
col1 = col2
答案 2 :(得分:0)
对于其他任何对此如何完成感兴趣的人,这里是代码。我沿着钩子路线走,并使用以下代码绑定到'channel_entries_query_result'钩子。
public function query_result_filtered($c, $res){
# maybe this can be done better? Grabs the tag data for this template call
$tags = $c->EE->TMPL->tag_data;
foreach($tags as $tag):
# We're only interested in exp:channel:entries
if($tag['class'] == 'channel' && $tag['method'] == 'entries'):
# We're only interested if the tag has a param of matching, e.g. {exp:channel:entries matching="field_1|field_2"}
if(isset($tag['params']['matching'])):
$res = $this->_parse_results($res, $tag['params']['matching']);
endif;
endif;
endforeach;
return $res;
}
private function _parse_results($res, $fields){
$ret = array();
$fields = explode('|', $fields);
//If we dont have multiple tags to match against, return the result set as is
if(!is_array($fields)):
return $res;
endif;
# Get the field id's and count how many fields we're checking against
$fields = $this->_get_field_ids($fields);
$field_count = count($fields);
foreach($res as $row):
# Value to match against (just use the first value)
$tomatch = $row[$fields[0]];
# Keep a count on how many matches, so we can check that they all match
$match = 0;
foreach($fields as $field):
# If the current field matches that of the first field then we have a match, increment the count
if($row[$field] == $tomatch):
$match++;
endif;
endforeach;
# If we have matched all fields then add this row to the returned array
if($match == $field_count):
$ret[] = $row;
endif;
endforeach;
return $ret;
}
private function _get_field_ids($fields){
$ret = array();
# Loop through the fields given and find their ID's (this could be better and check site id for multisite compatibility)
foreach($fields as $field):
$q = $this->EE->db->select('field_id')->where('field_name', $field)->get('exp_channel_fields');
# Create a nice name that we can use as an array key when we check each rows value
$ret[] = 'field_id_' . $q->row('field_id');
endforeach;
return $ret;
}
不是特别优雅,但它有效。如果其他人有更好的解决方案,我很乐意听到它。感谢