When specifying a views relationship, you can add extra conditions to the resulting join as such:

$data['my_table']['my_field']['relationship'] = array(
  'id' => 'standard',
  'base' => 'other_table',
  'base field' => 'other_field',
  'extra' => array(
    array(
      'field' => 'this',
      'value' => 1,
    ),
    array(
      'field' => 'that',
      'value' => array(3,4,5),
    ),
  ),
);

The above extra array should produce a join something like:

LEFT JOIN `other_table` ON `my_table`.`my_field` = `other_table`.`other_field` AND (`other_table`.`this` = 1 AND `other_table`.`that` IN (3, 4, 5))

However, currently it produces this:

LEFT JOIN `other_table` ON `my_table`.`my_field` = `other_table`.`other_field` AND (`other_table`.`this` = 1 AND `other_table`.`that` IN (1, 3, 4, 5))

Note that the argument from the first additional join condition is finding its way into the second additional join's list of arguments.

This is caused by core/modules/views/src/Plugin/views/join/JoinPluginBase.php on about line 257:

$placeholder = '( ' . implode(', ', array_keys($arguments)) . ' )';

The $arguments array is cumulative for all extra join conditions, meaning that any previous join conditions are imploded here for the current join condition. Instead, what is needed here is a local arguments list for the current join condition.

Comments

torrance123’s picture

torrance123’s picture

Status: Active » Needs review
dawehner’s picture

Issue tags: +VDC

I wonder whether we can write a test for that. Do you think you can do that?

jhedstrom’s picture

StatusFileSize
new2.1 KB
new3.32 KB

This adds a test. Attached separately to show existing failure (and roled into the patch to show fix).

The last submitted patch, 4: 2299215-test-only.patch, failed testing.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Nice!

jhedstrom’s picture

Alex Pott recommended on IRC that we should use assertContains() here. However, that doesn't exist from what I can tell in SimpleTest, only in PHPUnit.

Also, there was a question regarding the use of the name field twice, and I think it is simply testing that joins can occur with different conditions on the same field.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

@jhedstrom - sorry I should have checked that - I saw the name *UnitTest and assumed :(

The patch looks great apart from...

+++ b/core/modules/views/src/Tests/Plugin/JoinTest.php
@@ -152,6 +152,29 @@ public function testBasePlugin() {
+    $this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3, :views_join_condition_4, :views_join_condition_5 )") !== FALSE, 'The fourth table was not properly joined to the query.');

I don't really understand the assertion message.

jhedstrom’s picture

Status: Needs work » Needs review
StatusFileSize
new830 bytes
new3.32 KB

How about this message?

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

Bouncing back to RTBC since the only change was wording on the message.

catch’s picture

Status: Reviewed & tested by the community » Fixed

New assertion message looks better. Committed/pushed to 8.0.x, thanks!

  • catch committed eb56c4d on 8.0.x
    Issue #2299215 by jhedstrom, torrance123: Fixed 'extra' join conditions...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.