3

I am trying to modify an existing views join.

Let's say I am trying to remove the 'langcode' condition.

What I have so far:

function mymodule_views_query_alter(Drupal\views\ViewExecutable $view, Drupal\views\Plugin\views\query\Sql $query) {
    $joindata = $query->getJoinData("node__field_joined_whatever", "node_field_data");

//$joindata contains the join I need, so far so good

    foreach($joindata->extra as $ix=>$val) {
      if (isset($val['field']) && $val['field'] == 'langcode') {
        unset($joindata->extra[$ix]);
      }
    }
//here I have modified join object, but there is nothing like '$query->setJoinData()'
...
}

Does anybody know how to put my modified join back to the query?

2 Answers 2

6

Usually, you should control join type using views Advance relationship options. By enabling "Require this relationship" you are telling Views to use "INNER" Join instead of using "LEFT" Join. If this option is somehow not working here is how I would solve this problem.

use \Drupal\views\ViewExecutable;
use \Drupal\views\Plugin\views\query\QueryPluginBase;

function hook_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
   // check your view ID:
if ($view->id() === 'id') {
 //Get your table info object;
  $table = $query->getTableInfo('table');
if (isset($table['join']->type) && $table['join']->type === "INNER") {
//Change your Join type;
 $table['join']->type = 'LEFT';
   }
 }
}
1
  • It works. A correction: there is a not existing $table_node_revision variable in your "if" statement ($table_node_revision['join']->type === "INNER"). The correct variable name is $table. Jun 13, 2017 at 16:56
4

Another example, which can be useful. How to add your own extra condition to join. In my case, it checks that joined entity has a title not equal to management.

if ($view->current_display === 'my_display') {
  $table = $query->getTableInfo('MY_TABLE');
  // Make 'extra' and array if it's empty.
  $table['join']->extra = empty($table['join']->extra) ? [] : $table['join']->extra;
  $table['join']->extra[] = [
    'field' => 'title',
    'value' => 'management',
    'operator' => '!='
  ];
}

You can use an alias of the table instead of "MY_TABLE".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.