From 075e03fd579a02b8d0dfaa39a4c155b2f08e9965 Mon Sep 17 00:00:00 2001 From: florenttorregrosa Date: Wed, 8 Feb 2017 10:07:25 +0100 Subject: [PATCH] Issue #2839351 by Grimreaper: VBO for taxonomy term --- .../system.action.taxonomy_term_delete_action.yml | 9 + .../taxonomy/config/schema/taxonomy.schema.yml | 4 + .../src/Form/TaxonomyTermDeleteMultiple.php | 147 +++++++++++++++ .../src/Plugin/Action/DeleteTaxonomyTerm.php | 93 ++++++++++ .../taxonomy/src/Tests/Views/TaxonomyVboTest.php | 68 +++++++ core/modules/taxonomy/taxonomy.routing.yml | 7 + .../test_views/views.view.taxonomy_vbo_test.yml | 203 +++++++++++++++++++++ 7 files changed, 531 insertions(+) create mode 100644 core/modules/taxonomy/config/install/system.action.taxonomy_term_delete_action.yml create mode 100644 core/modules/taxonomy/src/Form/TaxonomyTermDeleteMultiple.php create mode 100644 core/modules/taxonomy/src/Plugin/Action/DeleteTaxonomyTerm.php create mode 100644 core/modules/taxonomy/src/Tests/Views/TaxonomyVboTest.php create mode 100644 core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_vbo_test.yml diff --git a/core/modules/taxonomy/config/install/system.action.taxonomy_term_delete_action.yml b/core/modules/taxonomy/config/install/system.action.taxonomy_term_delete_action.yml new file mode 100644 index 0000000..cbb2780 --- /dev/null +++ b/core/modules/taxonomy/config/install/system.action.taxonomy_term_delete_action.yml @@ -0,0 +1,9 @@ +id: taxonomy_term_delete_action +label: 'Delete taxonomy term' +status: true +langcode: en +type: taxonomy_term +plugin: taxonomy_term_delete_action +dependencies: + module: + - taxonomy diff --git a/core/modules/taxonomy/config/schema/taxonomy.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.schema.yml index efa08e1..f0a92ae 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.schema.yml @@ -37,3 +37,7 @@ taxonomy.vocabulary.*: field.formatter.settings.entity_reference_rss_category: type: mapping label: 'Taxonomy format settings' + +action.configuration.taxonomy_term_delete_action: + type: action_configuration_default + label: 'Delete taxonomy term configuration' diff --git a/core/modules/taxonomy/src/Form/TaxonomyTermDeleteMultiple.php b/core/modules/taxonomy/src/Form/TaxonomyTermDeleteMultiple.php new file mode 100644 index 0000000..188a46a --- /dev/null +++ b/core/modules/taxonomy/src/Form/TaxonomyTermDeleteMultiple.php @@ -0,0 +1,147 @@ +tempStoreFactory = $temp_store_factory; + $this->taxonomyTermStorage = $entity_type_manager->getStorage('taxonomy_term'); + $this->currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('user.private_tempstore'), + $container->get('entity_type.manager'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'taxonomy_term_multiple_delete_confirm'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->formatPlural(count($this->taxonomyTerms), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?'); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return new Url('entity.taxonomy_vocabulary.collection'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $this->taxonomyTerms = $this->tempStoreFactory->get('taxonomy_term_multiple_delete_confirm') + ->get($this->currentUser->id()); + if (empty($this->taxonomyTerms)) { + return new RedirectResponse($this->getCancelUrl() + ->setAbsolute() + ->toString()); + } + + $items = []; + /** @var \Drupal\Core\Entity\EntityInterface $taxonomy_term */ + foreach ($this->taxonomyTerms as $taxonomy_term) { + $items[] = array( + '#markup' => $taxonomy_term->label(), + ); + } + + $form['taxonomy_terms'] = array( + '#theme' => 'item_list', + '#items' => $items, + ); + $form = parent::buildForm($form, $form_state); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + if ($form_state->getValue('confirm') && !empty($this->taxonomyTerms)) { + $this->taxonomyTermStorage->delete($this->taxonomyTerms); + $this->tempStoreFactory->get('taxonomy_term_multiple_delete_confirm') + ->delete($this->currentUser->id()); + $count = count($this->taxonomyTerms); + $this->logger('taxonomy_term') + ->notice('Deleted @count posts.', array('@count' => $count)); + drupal_set_message($this->formatPlural($count, 'Deleted 1 taxonomy term.', 'Deleted @count taxonomy terms.')); + } + $form_state->setRedirect('entity.taxonomy_vocabulary.collection'); + } + +} diff --git a/core/modules/taxonomy/src/Plugin/Action/DeleteTaxonomyTerm.php b/core/modules/taxonomy/src/Plugin/Action/DeleteTaxonomyTerm.php new file mode 100644 index 0000000..3cfa973 --- /dev/null +++ b/core/modules/taxonomy/src/Plugin/Action/DeleteTaxonomyTerm.php @@ -0,0 +1,93 @@ +currentUser = $current_user; + $this->tempStoreFactory = $temp_store_factory; + + parent::__construct($configuration, $plugin_id, $plugin_definition); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('user.private_tempstore'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + public function executeMultiple(array $entities) { + $this->tempStoreFactory->get('taxonomy_term_multiple_delete_confirm')->set($this->currentUser->id(), $entities); + } + + /** + * {@inheritdoc} + */ + public function execute($object = NULL) { + $this->executeMultiple(array($object)); + } + + /** + * {@inheritdoc} + */ + public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + /** @var \Drupal\taxonomy\TermInterface $object */ + return $object->access('delete', $account, $return_as_object); + } + +} diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyVboTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyVboTest.php new file mode 100644 index 0000000..f512bda --- /dev/null +++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyVboTest.php @@ -0,0 +1,68 @@ +adminUser = $this->drupalCreateUser(array('administer taxonomy')); + } + + /** + * Tests VBO action with a delete action. + */ + function testVboActions() { + // Log in with user with right permissions and test listing. + $this->drupalLogin($this->adminUser); + $this->drupalGet('taxonomy_vbo_test'); + + // Delete both taxonomy terms to check bulk form. + $edit = array( + 'action' => 'taxonomy_term_delete_action', + 'taxonomy_term_bulk_form[0]' => 1, + 'taxonomy_term_bulk_form[1]' => 1, + ); + $this->drupalPostForm('taxonomy_vbo_test', $edit, t('Apply to selected items')); + $this->assertUrl(Url::fromRoute('taxonomy_term.multiple_delete_confirm', array(), array( + 'query' => array( + 'destination' => Url::fromRoute('view.taxonomy_vbo_test.page_1')->toString(), + ), + ))); + // Test cancel link. + $this->assertLinkByHref('taxonomy_vbo_test'); + $this->clickLink(t('Cancel')); + $this->assertUrl('taxonomy_vbo_test'); + // Test confirm to deletion. + $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); + $this->assertText('Are you sure you want to delete these items?'); + $this->drupalPostForm(NULL, array(), t('Delete')); + $this->assertText('Deleted 2 taxonomy terms.'); + } + +} diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index 8a3bd1a..7c3c7ce 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -85,3 +85,10 @@ entity.taxonomy_term.canonical: requirements: _entity_access: 'taxonomy_term.view' taxonomy_term: \d+ + +taxonomy_term.multiple_delete_confirm: + path: '/admin/structure/taxonomy/term/delete' + defaults: + _form: '\Drupal\taxonomy\Form\TaxonomyTermDeleteMultiple' + requirements: + _permission: 'administer taxonomy' diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_vbo_test.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_vbo_test.yml new file mode 100644 index 0000000..a2872c7 --- /dev/null +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_vbo_test.yml @@ -0,0 +1,203 @@ +langcode: en +status: true +dependencies: + module: + - taxonomy + - user +id: taxonomy_vbo_test +label: taxonomy_vbo_test +module: views +description: '' +tag: '' +base_table: taxonomy_term_field_data +base_field: tid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + 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: Filter + 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: mini + 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: ‹‹ + next: ›› + style: + type: table + row: + type: fields + fields: + taxonomy_term_bulk_form: + id: taxonomy_term_bulk_form + table: taxonomy_term_data + field: taxonomy_term_bulk_form + relationship: none + group_type: group + admin_label: '' + label: 'Bulk update' + 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 + action_title: Action + include_exclude: exclude + selected_actions: { } + entity_type: taxonomy_term + plugin_id: bulk_form + name: + id: name + table: taxonomy_term_field_data + field: name + entity_type: taxonomy_term + entity_field: name + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + type: string + settings: + link_to_entity: true + plugin_id: term_name + relationship: none + group_type: group + admin_label: '' + label: Name + exclude: 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_alter_empty: true + click_sort_column: value + 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 + convert_spaces: false + filters: { } + sorts: { } + title: 'taxonomy_vbo_test' + header: { } + footer: { } + empty: { } + relationships: { } + 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: taxonomy_vbo_test + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } -- 1.9.1