在 views_query_alter() 中向视图查询添加表连接、位置和排序依据

use*_*694 5 drupal drupal-views drupal-7

我正在尝试修改 Drupal 中的视图查询(视图版本 3,Drupal 版本 7)。

我想要做的是在运行之前更改查询,使其 LEFT JOINs 一个表,其中我已分配给节点的权重。

如果我要在 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
Run Code Online (Sandbox Code Playgroud)

当我在查询分析器中运行这个查询时,它就像一个冠军。所以,现在我需要让它在我的模块中工作。

我已经在各种博客上看到多种方法详细介绍了修改视图查询的不同方法,但它们似乎是针对不同版本的视图。因此,试图确定我正在查看的任何内容是否可能适用于我的应用程序是非常令人困惑的。

看来我需要使用一个 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;  
    }
Run Code Online (Sandbox Code Playgroud)

这似乎确实有效,因为当我使用 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);
    }
Run Code Online (Sandbox Code Playgroud)

这个功能非常糟糕。虽然我的连接表出现在 $view 对象中,但 add_relationship 方法对第三个参数抛出错误,但我没有在网上看到任何具有 3 个参数的示例,所以我不知道它缺少什么。

另外,我很确定我的 add_where 方法不正确,但我不知道输入实际上应该是什么。这只是一个盲目的猜测。

最重要的是,我想将节点表连接到我的 node_weights 表,然后确保在查询中使用我的权重以降序对结果进行排序,其中用户 ID = 我表中的用户 ID,以及表在 nid 字段上连接。

提前致谢。

umm*_*ian 6

加入 JOIN 后,WHERE 很容易添加。您可以在查询中更改(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' => '='
    );
}}
Run Code Online (Sandbox Code Playgroud)


Twa*_*inJ 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
    )
Run Code Online (Sandbox Code Playgroud)

请参阅views_join::construct 文档以获取更多信息。特别是,我不需要使用 OP 使用的“额外”参数。也许这对于自定义表格是必要的。

最后,将联接添加到查询中,以及其中需要的任何其他元素:

// 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');
...
Run Code Online (Sandbox Code Playgroud)