diff --git a/src/FlaggingViewsData.php b/src/FlaggingViewsData.php index b12c469..7910161 100644 --- a/src/FlaggingViewsData.php +++ b/src/FlaggingViewsData.php @@ -2,6 +2,7 @@ namespace Drupal\flag; +use Drupal\flag\Entity\Flag; use Drupal\views\EntityViewsData; /** @@ -48,6 +49,29 @@ class FlaggingViewsData extends EntityViewsData { ], ]; + /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */ + $entity_type_manager = \Drupal::entityTypeManager(); + foreach (Flag::loadMultiple(NULL) as $flag_id => $flag) { + /** @var \Drupal\flag\Entity\Flag $flag */ + $entity_type = $entity_type_manager->getDefinition($flag->getFlaggableEntityTypeId()); + if ($base = $entity_type->getDataTable() ?: $entity_type->getBaseTable()) { + $data['flagging']['flag_' . $flag_id]['relationship'] = [ + 'title' => $entity_type->getLabel(), + 'help' => $this->t('The @entity_type this flagging belongs to.', ['@entity_type' => $entity_type->getLabel()]), + 'base' => $base, + 'base field' => $entity_type->getKey('id'), + 'relationship field' => 'entity_id', + 'id' => 'standard', + 'label' => $entity_type->getLabel(), + 'extra' => [[ + 'field' => 'flag_id', + 'value' => $flag_id, + 'table' => 'flagging' + ]], + ]; + } + } + return $data; } diff --git a/src/Tests/FlaggingViewTest.php b/src/Tests/FlaggingViewTest.php new file mode 100644 index 0000000..279f9aa --- /dev/null +++ b/src/Tests/FlaggingViewTest.php @@ -0,0 +1,98 @@ +node = $this->drupalCreateNode([ + 'body' => [ + [ + 'value' => $this->randomMachineName(32), + 'format' => filter_default_format(), + ], + ], + 'type' => $this->nodeType, + 'title' => $this->randomMachineName(8), + 'uid' => $this->adminUser->id(), + 'status' => 1, + 'promote' => 1, + 'sticky' => 0, + ]); + + // Create a user to follow. + $auth_user = $this->drupalCreateUser([ + 'flag bookmark', + 'flag following', + ]); + + // Bookmark the node. + $bookmark_flag = $this->flagService->getFlagById('bookmark'); + $this->flagService->flag($bookmark_flag, $this->node, $auth_user); + + // Follow the admin user. + $follower_flag = $this->flagService->getFlagById('following'); + $this->flagService->flag($follower_flag, $this->adminUser, $auth_user); + } + + /** + * Test the flagging admin view. + */ + public function testFlaggingView() { + // Login as the admin. + $this->drupalLogin($this->adminUser); + + // Go to the view. + $this->drupalGet('admin/structure/flags/flagging'); + + // Check if there's a bookmark flagging. + $this->assertText('bookmark'); + + // Check if there's a node title. This would come from the entity + // relationship on the flagging view. + $this->assertText($this->node->getTitle()); + + // Check if there's a following flagging. + $this->assertText('following'); + } + +} diff --git a/tests/modules/flagging_admin/config/install/views.view.flagging_admin.yml b/tests/modules/flagging_admin/config/install/views.view.flagging_admin.yml new file mode 100644 index 0000000..fb299be --- /dev/null +++ b/tests/modules/flagging_admin/config/install/views.view.flagging_admin.yml @@ -0,0 +1,524 @@ +uuid: 2ab3c10e-641e-4c12-a307-f318f6d2e9c4 +langcode: en +status: true +dependencies: + module: + - flag + - node + - user +id: flagging_admin +label: 'Flagging Admin' +module: views +description: '' +tag: '' +base_table: flagging +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'administer flags' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ Previous' + next: 'Next ›' + first: '« First' + last: 'Last »' + quantity: 9 + style: + type: table + row: + type: fields + fields: + id: + id: id + table: flagging + field: id + relationship: none + group_type: group + admin_label: '' + label: 'Flagging ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: flagging + entity_field: id + plugin_id: field + flag_id: + id: flag_id + table: flagging + field: flag_id + relationship: none + group_type: group + admin_label: '' + label: 'Flag ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: flagging + entity_field: flag_id + plugin_id: field + created: + id: created + table: flagging + field: created + relationship: none + group_type: group + admin_label: '' + label: Created + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: flagging + entity_field: created + plugin_id: field + uid: + id: uid + table: flagging + field: uid + relationship: none + group_type: group + admin_label: '' + label: 'User ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: true + group_column: target_id + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: flagging + entity_field: uid + plugin_id: field + entity_type: + id: entity_type + table: flagging + field: entity_type + relationship: none + group_type: group + admin_label: '' + label: 'Entity Type' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: flagging + entity_field: entity_type + plugin_id: field + title: + id: title + table: node_field_data + field: title + relationship: flag_bookmark + group_type: group + admin_label: '' + label: Title + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: node + entity_field: title + plugin_id: field + filters: { } + sorts: { } + title: Flaggings + header: { } + footer: { } + empty: { } + relationships: + flag_bookmark: + id: flag_bookmark + table: flagging + field: flag_bookmark + relationship: none + group_type: group + admin_label: Content + required: false + entity_type: flagging + plugin_id: standard + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: admin/structure/flags/flagging + menu: + type: tab + title: Flagging + description: '' + expanded: true + parent: flag.admin.structure.flag + weight: 10 + context: '0' + menu_name: admin + tab_options: + type: none + title: '' + description: '' + weight: 0 + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } diff --git a/tests/modules/flagging_admin/flagging_admin.info.yml b/tests/modules/flagging_admin/flagging_admin.info.yml new file mode 100644 index 0000000..6dc32b0 --- /dev/null +++ b/tests/modules/flagging_admin/flagging_admin.info.yml @@ -0,0 +1,12 @@ +name: Flagging Admin +description: Provides an admin view for Flaggings. +core: 8.x +type: module +dependencies: + - flag + - flag_follower + - flag_bookmark + - views + - node + - user +package: Testing diff --git a/tests/modules/flagging_admin/flagging_admin.module b/tests/modules/flagging_admin/flagging_admin.module new file mode 100644 index 0000000..537d62c --- /dev/null +++ b/tests/modules/flagging_admin/flagging_admin.module @@ -0,0 +1,7 @@ +