我正在尝试修改Drupal中的Views查询(Views版本3,Drupal版本7)。
我想要做的是在运行之前更改查询,以便LEFT JOIN一个表,其中我将权重分配给节点。
如果我在SQL中编写我想要的查询,它将如下所示:
SELECT a.nid, a.title, a.description
FROM node a
LEFT OUTER JOIN node_weights b
ON a.nid = b.nid
WHERE b.uid = $uid
ORDER BY b.weight DESC
当我在查询分析器中运行它时,此查询就像一个冠军。所以,现在我需要让它在我的模块中运行。
我已经在不同的博客上看到了针对修改View查询的不同方法的多种方法,但它们似乎正在处理不同版本的视图。因此,尝试确定我正在查看的任何内容是否可能适用于我的应用程序是非常令人困惑的。
似乎我需要使用MODULE_NAME_views_tables()函数来告诉Views我要加入的表和节点表之间的关系。
我已将以下功能添加到MODULE_NAME.views.inc:
function MODULE_NAME_views_tables() {
$tables['node_weights'] = array(
"name" => "node_weights",
"join" => array(
"left" => array(
"table" => "node",
"field" => "nid"
),
"right" => array(
"field" => "nid"
),
),
);
return $table;
}
这似乎有效,因为当我使用Krumo查看查询数组时,我在“table_queue”元素中看到了“node_weights”表。
在views_query_alter()函数中,我希望它能像这样工作:
function MODULE_NAME_views_query_alter(&$view, &$query) {
$uid = $_COOKIE['uid'];
$view->query->add_relationship('node_weights', new views_join('node_weights', 'nid', 'node', 'nid','LEFT'));
$view->query->add_where('node_weights', "node_weights.uid", $uid);
krumo($query);
}
这个功能非常糟糕。虽然我的连接表出现在$ view对象中,但是add_relationship方法为第三个参数抛出了一个错误,但我没有看到任何有3个参数的在线示例,所以我不知道它缺少什么。
另外,我很确定我的add_where方法不正确,但我不知道输入应该是什么。这只是一个盲目的猜测。
底线是我想将节点表连接到我的node_weights表,然后确保在查询中使用我的权重以降序排序结果,其中用户id =我表中的用户ID ,这些表在nid字段上连接。
提前致谢。
答案 0 :(得分:4)
一旦你加入JOIN,你很容易添加。你可以在查询中改变(Drupal 7)。
function MODULE_NAME_views_query_alter(&$view, &$query){
// Only alter the view you mean to.
if($view->name == 'VIEW NAME' && $view->current_display == 'DISPLAY'){
// Create the join.
$join = new views_join();
$join->table = 'table_name';
$join->field = 'entity_id';
$join->left_table = 'node';
$join->left_field = 'nid';
$join->type = 'left';
// Add the join the the view query.
$view->query->add_relationship('table_name', $join, 'node');
// Add the where.
$view->query->where[1]['conditions'][] = array(
'field' => 'table_name.collumn_name',
'value' => 'value',
'operator' => '='
);
}}
答案 1 :(得分:3)
我发现OP的注释有助于在hook_views_query_alter函数中创建连接,所以我想把我认为有用的部分放在一个更容易理解的答案中。 我在Drupal 6x上使用了Views 2x,但我认为它与在D7 Views 2上的使用非常相似。
OP提到在hook_views_table中描述连接的关系。这对我来说不是必需的,因为我没有链接到自定义表,而是存在于核心表中。
HOOK_views_query_alter()函数中的联接创建非常有用:
$join = new views_join;
$join->construct('table_name',
'node', // left table
'nid', // left field
'nid', // field
)
有关详细信息,请参阅views_join::construct documentation。特别是,我不需要使用OP使用的'extra'参数。也许这对于自定义表来说是必要的。
最后,将连接添加到查询中,以及其中需要的任何其他元素:
// Add join to query; 'node' is the left table name
$view->query->add_relationship('table_name',$join,'node');
// Add fields from table (or where clause, or whatever)
$view->query->add_field('table_name','field_name');
...
答案 2 :(得分:0)
你已经在参数中有了$ query,所以你可以这样做:
myhook_views_query_alter(&$view, &$query) {
if ($view->name = ....) {
$join = new views_join();
$join->construct(
...
);
$query
->add_relationship(...)
->add_where(...)
->add_orderby(...)
...
;
}
无需使用$ view-> query-> ...