From cc0a0cc14eb57bda1342094fa537360381d77de9 Mon Sep 17 00:00:00 2001 From: dereine <dereine@99340.no-reply.drupal.org> Date: Fri, 12 Oct 2012 10:49:10 +0200 Subject: [PATCH] Issue #1799040 by dawehner: Fixed groupwise max relationship. --- .../views/relationship/GroupwiseMax.php | 28 ++-- .../Taxonomy/RelationshipNodeTermDataTest.php | 104 +------------ .../RelationshipRepresentativeNode.php | 42 ++++++ .../views/Tests/Taxonomy/TaxonomyTestBase.php | 137 ++++++++++++++++++ .../User/RelationshipRepresentativeNode.php | 43 ++++++ lib/Drupal/views/Tests/User/UserTestBase.php | 23 +++ modules/taxonomy.views.inc | 1 + modules/user.views.inc | 7 +- .../config/views.view.test_groupwise_term.yml | 66 +++++++++ .../config/views.view.test_groupwise_user.yml | 76 ++++++++++ ...iews.view.test_taxonomy_node_term_data.yml | 6 + 11 files changed, 419 insertions(+), 114 deletions(-) create mode 100644 lib/Drupal/views/Tests/Taxonomy/RelationshipRepresentativeNode.php create mode 100644 lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php create mode 100644 lib/Drupal/views/Tests/User/RelationshipRepresentativeNode.php create mode 100644 tests/views_test_config/config/views.view.test_groupwise_term.yml create mode 100644 tests/views_test_config/config/views.view.test_groupwise_user.yml diff --git a/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php b/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php index ef8ffaf9c6a4..a915544c2e16 100644 --- a/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php +++ b/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php @@ -8,6 +8,7 @@ namespace Drupal\views\Plugin\views\relationship; use Drupal\Core\Database\Query\AlterableInterface; +use Drupal\views\ViewExecutable; use Drupal\Core\Annotation\Plugin; /** @@ -161,11 +162,9 @@ public function buildOptionsForm(&$form, &$form_state) { * We use this to obtain our subquery SQL. */ function get_temporary_view() { - $view = new View(array(), 'view'); - $view->vid = 'new'; // @todo: what's this? - $view->base_table = $this->definition['base']; + $view = entity_create('view', array('base_table' => $this->definition['base'])); $view->addDisplay('default'); - return $view; + return $view->getExecutable(); } /** @@ -173,7 +172,7 @@ function get_temporary_view() { */ public function submitOptionsForm(&$form, &$form_state) { $cid = 'views_relationship_groupwise_max:' . $this->view->storage->name . ':' . $this->view->current_display . ':' . $this->options['id']; - cache('views_data')->delete($cid); + cache('views_results')->delete($cid); } /** @@ -224,15 +223,18 @@ function left_query($options) { $base_field = $views_data['table']['base']['field']; $temp_view->addItem('default', 'field', $this->definition['base'], $this->definition['field']); + $relationship_id = NULL; + // Add the used relationship for the subjoin, if defined. + if (isset($this->definition['relationship'])) { + list($relationship_table, $relationship_field) = explode(':', $this->definition['relationship']); + $relationship_id = $temp_view->addItem('default', 'relationship', $relationship_table, $relationship_field); + } + $temp_item_options = array('relationship' => $relationship_id); + // Add the correct argument for our relationship's base // ie the 'how to get back to base' argument. // The relationship definition tells us which one to use. - $temp_view->addItem( - 'default', - 'argument', - $this->definition['argument table'], // eg 'term_node', - $this->definition['argument field'] // eg 'tid' - ); + $temp_view->addItem('default', 'argument', $this->definition['argument table'], $this->definition['argument field'], $temp_item_options); // Build the view. The creates the query object and produces the query // string but does not run any queries. @@ -361,13 +363,13 @@ public function query() { else { // Get the stored subquery SQL string. $cid = 'views_relationship_groupwise_max:' . $this->view->storage->name . ':' . $this->view->current_display . ':' . $this->options['id']; - $cache = cache('views_data')->get($cid); + $cache = cache('views_results')->get($cid); if (isset($cache->data)) { $def['left_query'] = $cache->data; } else { $def['left_query'] = $this->left_query($this->options); - cache('views_data')->set($cid, $def['left_query']); + cache('views_results')->set($cid, $def['left_query']); } } diff --git a/lib/Drupal/views/Tests/Taxonomy/RelationshipNodeTermDataTest.php b/lib/Drupal/views/Tests/Taxonomy/RelationshipNodeTermDataTest.php index dbfd8fae472c..f9c4bad385f4 100644 --- a/lib/Drupal/views/Tests/Taxonomy/RelationshipNodeTermDataTest.php +++ b/lib/Drupal/views/Tests/Taxonomy/RelationshipNodeTermDataTest.php @@ -12,14 +12,7 @@ /** * Tests the node_term_data relationship handler. */ -class RelationshipNodeTermDataTest extends ViewTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('taxonomy'); +class RelationshipNodeTermDataTest extends TaxonomyTestBase { /** * The vocabulary for the test. @@ -36,99 +29,14 @@ public static function getInfo() { ); } - /** - * Returns a new term with random properties in vocabulary $vid. - */ - function createTerm() { - $term = entity_create('taxonomy_term', array( - 'name' => $this->randomName(), - 'description' => $this->randomName(), - // Use the first available text format. - 'format' => db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField(), - 'vid' => $this->vocabulary->vid, - 'langcode' => LANGUAGE_NOT_SPECIFIED, - )); - taxonomy_term_save($term); - return $term; - } - - function setUp() { - parent::setUp(); - $this->mockStandardInstall(); - - $this->term_1 = $this->createTerm(); - $this->term_2 = $this->createTerm(); - - $node = array(); - $node['type'] = 'article'; - $node['field_views_testing_tags'][LANGUAGE_NOT_SPECIFIED][]['tid'] = $this->term_1->tid; - $node['field_views_testing_tags'][LANGUAGE_NOT_SPECIFIED][]['tid'] = $this->term_2->tid; - $this->node = $this->drupalCreateNode($node); - } - - /** - * Provides a workaround for the inability to use the standard profile. - * - * @see http://drupal.org/node/1708692 - */ - protected function mockStandardInstall() { - $type = array( - 'type' => 'article', - ); - - $type = node_type_set_defaults($type); - node_type_save($type); - node_add_body_field($type); - - // Create the vocabulary for the tag field. - $this->vocabulary = entity_create('taxonomy_vocabulary', array( - 'name' => 'Views testing tags', - 'machine_name' => 'views_testing_tags', - )); - $this->vocabulary->save(); - $field = array( - 'field_name' => 'field_' . $this->vocabulary->machine_name, - 'type' => 'taxonomy_term_reference', - // Set cardinality to unlimited for tagging. - 'cardinality' => FIELD_CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->machine_name, - 'parent' => 0, - ), - ), - ), - ); - field_create_field($field); - $instance = array( - 'field_name' => 'field_' . $this->vocabulary->machine_name, - 'entity_type' => 'node', - 'label' => 'Tags', - 'bundle' => 'article', - 'widget' => array( - 'type' => 'taxonomy_autocomplete', - 'weight' => -4, - ), - 'display' => array( - 'default' => array( - 'type' => 'taxonomy_term_reference_link', - 'weight' => 10, - ), - 'teaser' => array( - 'type' => 'taxonomy_term_reference_link', - 'weight' => 10, - ), - ), - ); - field_create_instance($instance); - } - function testViewsHandlerRelationshipNodeTermData() { - $this->executeView($this->view, array($this->term_1->tid, $this->term_2->tid)); + $this->executeView($this->view, array($this->term1->tid, $this->term2->tid)); $resultset = array( array( - 'nid' => $this->node->nid, + 'nid' => $this->nodes[0]->nid, + ), + array( + 'nid' => $this->nodes[1]->nid, ), ); $this->column_map = array('nid' => 'nid'); diff --git a/lib/Drupal/views/Tests/Taxonomy/RelationshipRepresentativeNode.php b/lib/Drupal/views/Tests/Taxonomy/RelationshipRepresentativeNode.php new file mode 100644 index 000000000000..70a9c99f454e --- /dev/null +++ b/lib/Drupal/views/Tests/Taxonomy/RelationshipRepresentativeNode.php @@ -0,0 +1,42 @@ +<?php + +/** + * @file + * Definition of Drupal\views\Tests\Taxonomy\RelationshipRepresentativeNode. + */ + +namespace Drupal\views\Tests\Taxonomy; + +/** + * Tests the representative node relationship for terms. + */ +class RelationshipRepresentativeNode extends TaxonomyTestBase { + + public static function getInfo() { + return array( + 'name' => 'Taxonomy: Representative Node Relationship', + 'description' => 'Tests the representative node relationship for terms.', + 'group' => 'Views Modules', + ); + } + + /** + * Tests the relationship. + */ + public function testRelationship() { + $view = views_get_view('test_groupwise_term'); + $this->executeView($view); + $map = array('node_taxonomy_term_data_nid' => 'nid', 'tid' => 'tid'); + $expected_result = array( + array( + 'nid' => $this->nodes[1]->nid, + 'tid' => $this->term2->tid, + ), + array( + 'nid' => $this->nodes[1]->nid, + 'tid' => $this->term1->tid, + ), + ); + $this->assertIdenticalResultset($view, $expected_result, $map); + } +} diff --git a/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php b/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php new file mode 100644 index 000000000000..9c2835abee3a --- /dev/null +++ b/lib/Drupal/views/Tests/Taxonomy/TaxonomyTestBase.php @@ -0,0 +1,137 @@ +<?php + +/** + * @file + * Definition of Drupal\views\Tests\Taxonomy\TaxonomyTestBase. + */ + +namespace Drupal\views\Tests\Taxonomy; + +use Drupal\views\Tests\ViewTestBase; + +/** + * Base class for all taxonomy tests. + */ +abstract class TaxonomyTestBase extends ViewTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('taxonomy'); + + /** + * Stores the nodes used for the different tests. + * + * @var array + */ + protected $nodes = array(); + + /** + * Stores the first term used in the different tests. + * + * @var Drupal\taxonomy\Term + */ + protected $term1; + + /** + * Stores the second term used in the different tests. + * + * @var Drupal\taxonomy\Term + */ + protected $term2; + + function setUp() { + parent::setUp(); + $this->mockStandardInstall(); + + $this->term1 = $this->createTerm(); + $this->term2 = $this->createTerm(); + + $node = array(); + $node['type'] = 'article'; + $node['field_views_testing_tags'][LANGUAGE_NOT_SPECIFIED][]['tid'] = $this->term1->tid; + $node['field_views_testing_tags'][LANGUAGE_NOT_SPECIFIED][]['tid'] = $this->term2->tid; + $this->nodes[] = $this->drupalCreateNode($node); + $this->nodes[] = $this->drupalCreateNode($node); + } + + /** + * Provides a workaround for the inability to use the standard profile. + * + * @see http://drupal.org/node/1708692 + */ + protected function mockStandardInstall() { + $type = array( + 'type' => 'article', + ); + + $type = node_type_set_defaults($type); + node_type_save($type); + node_add_body_field($type); + + // Create the vocabulary for the tag field. + $this->vocabulary = entity_create('taxonomy_vocabulary', array( + 'name' => 'Views testing tags', + 'machine_name' => 'views_testing_tags', + )); + $this->vocabulary->save(); + $field = array( + 'field_name' => 'field_' . $this->vocabulary->machine_name, + 'type' => 'taxonomy_term_reference', + // Set cardinality to unlimited for tagging. + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'settings' => array( + 'allowed_values' => array( + array( + 'vocabulary' => $this->vocabulary->machine_name, + 'parent' => 0, + ), + ), + ), + ); + field_create_field($field); + $instance = array( + 'field_name' => 'field_' . $this->vocabulary->machine_name, + 'entity_type' => 'node', + 'label' => 'Tags', + 'bundle' => 'article', + 'widget' => array( + 'type' => 'taxonomy_autocomplete', + 'weight' => -4, + ), + 'display' => array( + 'default' => array( + 'type' => 'taxonomy_term_reference_link', + 'weight' => 10, + ), + 'teaser' => array( + 'type' => 'taxonomy_term_reference_link', + 'weight' => 10, + ), + ), + ); + field_create_instance($instance); + } + + /** + * Returns a new term with random properties in vocabulary $vid. + * + * @return Drupal\taxonomy\Term + * The created taxonomy term. + */ + protected function createTerm() { + $term = entity_create('taxonomy_term', array( + 'name' => $this->randomName(), + 'description' => $this->randomName(), + // Use the first available text format. + 'format' => db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField(), + 'vid' => $this->vocabulary->vid, + 'langcode' => LANGUAGE_NOT_SPECIFIED, + )); + $term->save(); + return $term; + } + +} diff --git a/lib/Drupal/views/Tests/User/RelationshipRepresentativeNode.php b/lib/Drupal/views/Tests/User/RelationshipRepresentativeNode.php new file mode 100644 index 000000000000..a46965c3107f --- /dev/null +++ b/lib/Drupal/views/Tests/User/RelationshipRepresentativeNode.php @@ -0,0 +1,43 @@ +<?php + +/** + * @file + * Definition of Drupal\views\Tests\User\RelationshipRepresentativeNode. + */ + +namespace Drupal\views\Tests\User; + +/** + * Tests the representative node relationship for users. + */ +class RelationshipRepresentativeNode extends UserTestBase { + + public static function getInfo() { + return array( + 'name' => 'User: Representative Node Relationship', + 'description' => 'Tests the representative node relationship for users.', + 'group' => 'Views Modules', + ); + } + + /** + * Tests the relationship. + */ + public function testRelationship() { + $view = views_get_view('test_groupwise_user'); + $this->executeView($view); + $map = array('node_users_nid' => 'nid', 'uid' => 'uid'); + $expected_result = array( + array( + 'uid' => $this->users[1]->uid, + 'nid' => $this->nodes[1]->nid, + ), + array( + 'uid' => $this->users[0]->uid, + 'nid' => $this->nodes[0]->nid, + ), + ); + $this->assertIdenticalResultset($view, $expected_result, $map); + } + +} diff --git a/lib/Drupal/views/Tests/User/UserTestBase.php b/lib/Drupal/views/Tests/User/UserTestBase.php index 28eeb018b7ed..27829877354f 100644 --- a/lib/Drupal/views/Tests/User/UserTestBase.php +++ b/lib/Drupal/views/Tests/User/UserTestBase.php @@ -14,4 +14,27 @@ */ abstract class UserTestBase extends ViewTestBase { + /** + * Users to use during this test. + * + * @var array + */ + protected $users = array(); + + /** + * Nodes to use during this test. + * + * @var array + */ + protected $nodes = array(); + + protected function setUp() { + parent::setUp(); + + $this->users[] = $this->drupalCreateUser(); + $this->users[] = user_load(1); + $this->nodes[] = $this->drupalCreateNode(array('uid' => $this->users[0]->uid)); + $this->nodes[] = $this->drupalCreateNode(array('uid' => 1)); + } + } diff --git a/modules/taxonomy.views.inc b/modules/taxonomy.views.inc index 1779bf0de178..c7e208d44839 100644 --- a/modules/taxonomy.views.inc +++ b/modules/taxonomy.views.inc @@ -169,6 +169,7 @@ function taxonomy_views_data() { 'argument field' => 'tid', 'base' => 'node', 'field' => 'nid', + 'relationship' => 'node:term_node_tid' ), ); diff --git a/modules/user.views.inc b/modules/user.views.inc index ad6d9ffd1ceb..83fa4903543f 100644 --- a/modules/user.views.inc +++ b/modules/user.views.inc @@ -76,9 +76,10 @@ function user_views_data() { 'relationship field' => 'uid', 'outer field' => 'users.uid', 'argument table' => 'users', - 'argument field' => 'uid', - 'base' => 'node', - 'field' => 'nid', + 'argument field' => 'uid', + 'base' => 'node', + 'field' => 'nid', + 'relationship' => 'node:uid' ), ); diff --git a/tests/views_test_config/config/views.view.test_groupwise_term.yml b/tests/views_test_config/config/views.view.test_groupwise_term.yml new file mode 100644 index 000000000000..5240f0c50a08 --- /dev/null +++ b/tests/views_test_config/config/views.view.test_groupwise_term.yml @@ -0,0 +1,66 @@ +api_version: '3.0' +base_field: tid +base_table: taxonomy_term_data +core: 8.0-dev +description: '' +disabled: '0' +display: + default: + display_options: + access: + type: perm + cache: + type: none + exposed_form: + type: basic + fields: + name: + field: name + id: name + table: taxonomy_term_data + nid: + field: nid + id: nid + relationship: tid_representative + table: node + pager: + options: + items_per_page: '10' + type: full + query: + type: views_query + relationships: + tid_representative: + admin_label: '' + field: tid_representative + group_type: group + id: tid_representative + label: 'Representative node' + relationship: none + required: '0' + subquery_namespace: '' + subquery_order: DESC + subquery_regenerate: '1' + subquery_sort: node.nid + subquery_view: '' + table: taxonomy_term_data + row: + type: fields + sorts: + tid: + field: tid + id: tid + order: DESC + table: taxonomy_term_data + style: + type: default + title: test_groupwise + display_plugin: default + display_title: Master + id: default + position: { } +human_name: test_groupwise +langcode: und +module: views +name: test_groupwise_term +tag: default diff --git a/tests/views_test_config/config/views.view.test_groupwise_user.yml b/tests/views_test_config/config/views.view.test_groupwise_user.yml new file mode 100644 index 000000000000..7d79d1123d52 --- /dev/null +++ b/tests/views_test_config/config/views.view.test_groupwise_user.yml @@ -0,0 +1,76 @@ +api_version: '3.0' +base_field: uid +base_table: users +core: 8.0-dev +description: '' +disabled: '0' +display: + default: + display_options: + access: + perm: 'access user profiles' + type: perm + cache: + type: none + exposed_form: + type: basic + fields: + name: + field: name + id: name + table: users + nid: + field: nid + id: nid + relationship: uid_representative + table: node + filters: + status: + expose: + operator: '0' + field: status + group: '1' + id: status + table: users + value: '1' + pager: + options: + items_per_page: '10' + type: full + query: + type: views_query + relationships: + uid_representative: + admin_label: '' + field: uid_representative + group_type: group + id: uid_representative + label: 'Representative node' + relationship: none + required: '0' + subquery_namespace: '' + subquery_order: DESC + subquery_regenerate: '1' + subquery_sort: node.nid + subquery_view: '' + table: users + row: + type: fields + sorts: + created: + field: created + id: created + order: DESC + table: users + style: + type: default + title: test_groupwise_user + display_plugin: default + display_title: Master + id: default + position: { } +human_name: test_groupwise_user +langcode: und +module: views +name: test_groupwise_user +tag: default diff --git a/tests/views_test_config/config/views.view.test_taxonomy_node_term_data.yml b/tests/views_test_config/config/views.view.test_taxonomy_node_term_data.yml index 2cecd63a4d6c..383766a9e991 100644 --- a/tests/views_test_config/config/views.view.test_taxonomy_node_term_data.yml +++ b/tests/views_test_config/config/views.view.test_taxonomy_node_term_data.yml @@ -54,6 +54,12 @@ display: table: node vocabularies: tags: '0' + sorts: + nid: + field: nid + id: nid + order: DESC + table: nid style: type: default row: -- GitLab