问题描述
我想以编程方式添加/修改filter criteria
。
例如,对于视图,我添加了一个”Email Address”过滤器,其值需要动态更改,需要设置为当前登录用户的电子邮件ID。
怎么实现呢?有关详细信息,请参阅附图。请帮忙。
最佳解决办法
将”test@email.com”放入pic中的”value”字段后,请使用Devel模块和dpm($view)
以及dpm($query)
。从devel输出中查看视图的对象/数组结构和查询。
然后使用模块中的函数hook_views_query_alter(&$view, &$query)
来定位WHERE条件过滤条件并将其设置为所需的值。
就像是:
function MYMODULE_views_query_alter(&$view, &$query) {
global $user;
dpm($view, __FUNCTION__);
dpm($query, __FUNCTION__);
if ($view->name === 'your_view_machine_name') {
// This will only work as-is if you always have something in the filter by
// default, I guess. This hook runs always so you could just put
// 'test@test.com' as the email to filter by in views and this
// will always override it. I'm sure there is a cleaner way to put
// the filter dynamically at runtime. But i think thats more complex
// php that customizes a view.
//
// The index 2 below is the index of the condition for the email filter.
// Your $query structure may be different in your dpm() of the View $query.
$query->where[1]['conditions'][2]['field']['value'] = $user->email;
}
}
次佳解决办法
这是另一种选择:
$view = views_get_view('view_machine_name');
$view->init_display('default');
$view->display_handler->display->display_options['filters']['your_filter_name']['default_value'] = 'your_value';
$view->is_cacheable = FALSE;
$view->execute();
print $view->render();
我知道你应该用一些深奥的,复杂的方法来设置它,但是如果你只是想要快速和脏的访问而不搞乱这将使你到达那里。
第三种解决办法
最好在挂钩中而不是在渲染时更改这些,这样您就不会破坏站点性能和缓存。让我觉得hook_views_pre_build()起火太晚了,你需要hook_views_pre_view()。
我发现使用$view->add_item()的参考但是很难举例,下面是我过滤一组分类术语的解决方案,只包括某些词汇:
function MODULENAME_views_pre_view(&$view, &$display_id, &$args) {
if ($view->name == 'VIEWNAME' && $display_id == 'DISPLAYID') {
// Add all the terms of a vocabulary to the terms listing widget select field
$vids = array();
$vocab = taxonomy_vocabulary_machine_name_load('vocab_name');
$vids[ $vocab->vid ] = $vocab->vid;
// Get the existing filters
$filters = $view->display_handler->get_option('filters');
if (empty($filters['vid'])) {
// There is no vid filter so we have to add it
$view->add_item(
$view->current_display,
'filter',
'taxonomy_term_data',
'vid',
array(
'operator' => 'in',
'value' => $vids,
'group' => 1
)
);
}
else {
// Add to pre-existing filter
foreach($vids as $vid) {
$filters['vid']['value'][ $vid ] = $vid;
}
$view->display_handler->override_option('filters', $filters);
}
}
}
编辑注释:d.o组上的This comment帮助我弄清楚如何使用$view->display_handler->get_option('filters')
获取视图过滤器,然后使用$view->display_handler->override_option('filters', $filters);
覆盖它们。
第四种办法
我有一个类似的问题,但试图将多个参数传递给过滤器。我使用了”views_get_view”方法,但是将参数传递给视图。我希望它对某人有帮助。您可以根据需要替换任何参数类型或值:
我已经为视图本身添加了上下文过滤器(来自高级视图设置字段集)。第一个是“内容:具有分类术语ID”。第二个是“content:nid”,选中”allow multiple”并选中”exclude”复选框(来自上下文过滤器pop-up中的’more’字段集)。
args[] = '1'; // Term ID
args[] = '1+2+3'; // Node IDs to exclude/include
$view = views_get_view($view_name);
$view->init();
$view->set_display($display);
$view->set_arguments($args);
$view->execute();
$view->result
更新:我忘了提及,在上下文过滤器值中,您可能需要选择php代码并返回传入的视图参数。例如:
return $view->args[1];