Skip to content
Snippets Groups Projects
Verified Commit aec9cf8c authored by Dave Long's avatar Dave Long
Browse files

Issue #2559961 by angrytoast, Krzysztof Domański, drup16, Lendude, vasike,...

Issue #2559961 by angrytoast, Krzysztof Domański, drup16, Lendude, vasike, Leksat, sam711, tar_inet, mlncn, JordiK, adinac, Pascal-, joshua.boltz, froboy, oriol_e9g, alison, codesmith, luenemann, specky_rum, daffie: ManyToOneHelper ignores group configuration for some cases
parent f5de3b7a
No related branches found
No related tags found
43 merge requests!54479.5.x SF update,!5014Issue #3071143: Table Render Array Example Is Incorrect,!4868Issue #1428520: Improve menu parent link selection,!4594Applying patch for Views Global Text area field to allow extra HTML tags. As video, source and iframe tag is not rendering. Due to which Media embedded video and remote-video not rendering in Views Global Text area field.,!3878Removed unused condition head title for views,!38582585169-10.1.x,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3668Resolve #3347842 "Deprecate the trusted",!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3546refactored dialog.pcss file,!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3502Issue #3335308: Confusing behavior with FormState::setFormState and FormState::setMethod,!3452Issue #3332701: Refactor Claro's tablesort-indicator stylesheet,!3451Issue #2410579: Allows setting the current language programmatically.,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3147Issue #3328457: Replace most substr($a, $i) where $i is negative with str_ends_with(),!3146Issue #3328456: Replace substr($a, 0, $i) with str_starts_with(),!3133core/modules/system/css/components/hidden.module.css,!31312878513-10.1.x,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2614Issue #2981326: Replace non-test usages of \Drupal::logger() with IoC injection,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!877Issue #2708101: Default value for link text is not saved,!844Resolve #3036010 "Updaters",!673Issue #3214208: FinishResponseSubscriber could create duplicate headers,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer
......@@ -358,4 +358,137 @@ public function testExposedUnpublishedFilterOptions() {
$this->assertEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
}
/**
* Tests using the TaxonomyIndexTid in a filter group.
*/
public function testFilterGrouping() {
$node_type = $this->drupalCreateContentType(['type' => 'page']);
// Create the tag field itself.
$field_name = 'taxonomy_tags';
$this->createEntityReferenceField('node', $node_type->id(), $field_name, NULL, 'taxonomy_term');
// Create 4 nodes: 1 node without any tagging, 2 nodes tagged with 1 term,
// and 1 node with 2 tagged terms.
$node_no_term = $this->drupalCreateNode();
$node_with_term_1_0 = $this->drupalCreateNode([
$field_name => [['target_id' => $this->terms[1][0]->id()]],
]);
$node_with_terms_1_0_and_1_1 = $this->drupalCreateNode([
$field_name => [
['target_id' => $this->terms[1][0]->id()],
['target_id' => $this->terms[1][1]->id()],
],
]);
$node_with_term_2_0 = $this->drupalCreateNode([
$field_name => [['target_id' => $this->terms[2][0]->id()]],
]);
// Create two groups. The first group contains the published filter and set
// up the second group as an 'OR' group. The first subgroup of the second
// filter group will vary as follows:
// - multiple values vs single value
// - not vs or operator values
$view = View::load('test_filter_taxonomy_index_tid');
$display =& $view->getDisplay('default');
// Case 1:
// - filter "tid" with multiple terms as "is none of"
// - filter "tid_2" with a single term as "is one of"
$display['display_options']['filters']['tid']['value'][0] = $this->terms[1][0]->id();
$display['display_options']['filters']['tid']['value'][1] = $this->terms[1][1]->id();
$display['display_options']['filters']['tid']['operator'] = 'not';
$display['display_options']['filters']['tid']['group'] = 2;
$display['display_options']['filters']['tid_2'] = $display['display_options']['filters']['tid'];
$display['display_options']['filters']['tid_2']['id'] = 'tid_2';
$display['display_options']['filters']['tid_2']['value'][0] = $this->terms[2][0]->id();
$display['display_options']['filters']['tid_2']['operator'] = 'or';
$display['display_options']['filters']['tid_2']['group'] = 2;
$display['display_options']['filter_groups'] = [
'operator' => 'AND',
'groups' => [
1 => 'AND',
2 => 'OR',
],
];
$view->save();
$this->drupalGet('test-filter-taxonomy-index-tid');
// We expect no nodes tagged with term 1.0 or 1.1. The node tagged with
// term 2.0 and the untagged node will be shown.
$this->assertSession()->pageTextNotContains($node_with_term_1_0->label());
$this->assertSession()->pageTextNotContains($node_with_terms_1_0_and_1_1->label());
$this->assertSession()->pageTextContainsOnce($node_with_term_2_0->label());
$this->assertSession()->pageTextContainsOnce($node_no_term->label());
// Case 2:
// - filter "tid" with multiple terms as "is one of"
// - filter "tid_2" with a single term as "is one of"
$view = View::load('test_filter_taxonomy_index_tid');
$display =& $view->getDisplay('default');
$display['display_options']['filters']['tid']['value'][0] = $this->terms[1][0]->id();
$display['display_options']['filters']['tid']['value'][1] = $this->terms[1][1]->id();
$display['display_options']['filters']['tid']['operator'] = 'or';
$display['display_options']['filters']['tid']['group'] = 2;
$display['display_options']['filters']['tid_2'] = $display['display_options']['filters']['tid'];
$display['display_options']['filters']['tid_2']['id'] = 'tid_2';
$display['display_options']['filters']['tid_2']['value'][0] = $this->terms[2][0]->id();
$display['display_options']['filters']['tid_2']['operator'] = 'or';
$display['display_options']['filters']['tid_2']['group'] = 2;
$view->save();
$this->drupalGet('test-filter-taxonomy-index-tid');
// We expect all the tagged nodes but not the untagged node.
$this->assertSession()->pageTextContainsOnce($node_with_term_1_0->label());
// The view does not have DISTINCT query enabled, the node tagged with
// both 1.0 and 1.1 will appear twice.
$this->assertSession()->pageTextMatchesCount(2, "/{$node_with_terms_1_0_and_1_1->label()}/");
$this->assertSession()->pageTextContainsOnce($node_with_term_2_0->label());
$this->assertSession()->pageTextNotContains($node_no_term->label());
// Case 3:
// - filter "tid" with a single term as "is none of"
// - filter "tid_2" with a single term as "is one of"
$view = View::load('test_filter_taxonomy_index_tid');
$display =& $view->getDisplay('default');
$display['display_options']['filters']['tid']['value'] = [];
$display['display_options']['filters']['tid']['value'][0] = $this->terms[1][0]->id();
$display['display_options']['filters']['tid']['operator'] = 'not';
$display['display_options']['filters']['tid']['group'] = 2;
$display['display_options']['filters']['tid_2'] = $display['display_options']['filters']['tid'];
$display['display_options']['filters']['tid_2']['id'] = 'tid_2';
$display['display_options']['filters']['tid_2']['value'][0] = $this->terms[2][0]->id();
$display['display_options']['filters']['tid_2']['operator'] = 'or';
$display['display_options']['filters']['tid_2']['group'] = 2;
$view->save();
$this->drupalGet('test-filter-taxonomy-index-tid');
// We expect none of the nodes tagged with term 1.0. The node tagged with
// term 2.0 and the untagged node should be shown.
$this->assertSession()->pageTextNotContains($node_with_term_1_0->label());
$this->assertSession()->pageTextNotContains($node_with_terms_1_0_and_1_1->label());
$this->assertSession()->pageTextContainsOnce($node_with_term_2_0->label());
$this->assertSession()->pageTextContainsOnce($node_no_term->label());
// Case 4:
// - filter "tid" with a single term as "is one of"
// - filter "tid_2" with a single term as "is one of"
$view = View::load('test_filter_taxonomy_index_tid');
$display =& $view->getDisplay('default');
$display['display_options']['filters']['tid']['value'] = [];
$display['display_options']['filters']['tid']['value'][0] = $this->terms[1][0]->id();
$display['display_options']['filters']['tid']['operator'] = 'or';
$display['display_options']['filters']['tid']['group'] = 2;
$display['display_options']['filters']['tid_2'] = $display['display_options']['filters']['tid'];
$display['display_options']['filters']['tid_2']['id'] = 'tid_2';
$display['display_options']['filters']['tid_2']['value'][0] = $this->terms[2][0]->id();
$view->save();
$this->drupalGet('test-filter-taxonomy-index-tid');
// We expect all the tagged nodes to be shown but not the untagged node.
$this->assertSession()->pageTextContainsOnce($node_with_term_1_0->label());
$this->assertSession()->pageTextContainsOnce($node_with_terms_1_0_and_1_1->label());
$this->assertSession()->pageTextContainsOnce($node_with_term_2_0->label());
$this->assertSession()->pageTextNotContains($node_no_term->label());
}
}
......@@ -327,18 +327,18 @@ public function addFilter() {
$placeholder .= '[]';
if ($operator == 'IS NULL') {
$this->handler->query->addWhereExpression(0, "$field $operator");
$this->handler->query->addWhereExpression($options['group'], "$field $operator");
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", [$placeholder => $value]);
$this->handler->query->addWhereExpression($options['group'], "$field $operator($placeholder)", [$placeholder => $value]);
}
}
else {
if ($operator == 'IS NULL') {
$this->handler->query->addWhereExpression(0, "$field $operator");
$this->handler->query->addWhereExpression($options['group'], "$field $operator");
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator $placeholder", [$placeholder => $value]);
$this->handler->query->addWhereExpression($options['group'], "$field $operator $placeholder", [$placeholder => $value]);
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment