From 74d7ef73b361fff82605291282588dc05059dc27 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 15 Nov 2021 22:23:01 +0000 Subject: [PATCH] Taxonomy: Display update notices when adding terms. Display notice and announce to screen readers when a new term is added. Props manishamakhija, birgire, dilipbheda, afercia, hellofromTonya. Fixes #42937. git-svn-id: https://develop.svn.wordpress.org/trunk@52170 602fd350-edb4-49c9-b593-d223f7449a82 --- src/js/_enqueues/lib/ajax-response.js | 12 +- src/wp-admin/includes/ajax-actions.php | 10 ++ tests/phpunit/tests/ajax/AddTag.php | 145 +++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 2 deletions(-) create mode 100755 tests/phpunit/tests/ajax/AddTag.php diff --git a/src/js/_enqueues/lib/ajax-response.js b/src/js/_enqueues/lib/ajax-response.js index 38816f3c38..659b91e023 100644 --- a/src/js/_enqueues/lib/ajax-response.js +++ b/src/js/_enqueues/lib/ajax-response.js @@ -18,7 +18,7 @@ window.wpAjax = jQuery.extend( { return r; }, parseAjaxResponse: function( x, r, e ) { // 1 = good, 0 = strange (bad data?), -1 = you lack permission. - var parsed = {}, re = jQuery('#' + r).empty(), err = ''; + var parsed = {}, re = jQuery('#' + r).empty(), err = '', successmsg = ''; if ( x && typeof x === 'object' && x.getElementsByTagName('wp_ajax') ) { parsed.responses = []; @@ -27,6 +27,7 @@ window.wpAjax = jQuery.extend( { var th = jQuery(this), child = jQuery(this.firstChild), response; response = { action: th.attr('action'), what: child.get(0).nodeName, id: child.attr('id'), oldId: child.attr('old_id'), position: child.attr('position') }; response.data = jQuery( 'response_data', child ).text(); + successmsg += response.data; response.supplemental = {}; if ( !jQuery( 'supplemental', child ).children().each( function() { response.supplemental[this.nodeName] = jQuery(this).text(); @@ -46,7 +47,14 @@ window.wpAjax = jQuery.extend( { } ).length ) { response.errors = false; } parsed.responses.push( response ); } ); - if ( err.length ) { re.html( '
' + err + '
' ); } + if ( err.length ) { + re.html( '
' + err + '
' ); + wp.a11y.speak( err ); + } else { + re.html( '

' + successmsg + '

'); + jQuery(document).trigger( 'wp-updates-notice-added' ); + wp.a11y.speak( successmsg ); + } return parsed; } if ( isNaN(x) ) { return !re.html('

' + x + '

'); } diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 1ba480f2f1..191e5b54dd 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -1102,9 +1102,19 @@ function wp_ajax_add_tag() { $wp_list_table->single_row( $tag ); $parents = ob_get_clean(); + require ABSPATH . 'wp-admin/includes/edit-tag-messages.php'; + + $message = ''; + if ( isset( $messages[ $tax->name ][1] ) ) { + $message = $messages[ $tax->name ][1]; + } elseif ( isset( $messages['_item'][1] ) ) { + $message = $messages['_item'][1]; + } + $x->add( array( 'what' => 'taxonomy', + 'data' => $message, 'supplemental' => compact( 'parents', 'noparents' ), ) ); diff --git a/tests/phpunit/tests/ajax/AddTag.php b/tests/phpunit/tests/ajax/AddTag.php new file mode 100755 index 0000000000..48b5fc5f24 --- /dev/null +++ b/tests/phpunit/tests/ajax/AddTag.php @@ -0,0 +1,145 @@ +_setRole( 'administrator' ); + + $_POST = $post_data; + $_POST['_wpnonce_add-tag'] = wp_create_nonce( 'add-tag' ); + + if ( ! empty( $callback ) ) { + add_filter( 'term_updated_messages', $callback ); + } + + try { + $this->_handleAjax( 'add-tag' ); + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + $this->assertSame( $expected, (string) $this->get_xml_response_taxonomy()->response_data ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_add_tag() { + return array( + 'add a category' => array( + 'post_data' => array( + 'taxonomy' => 'category', + 'post_type' => 'post', + 'screen' => 'edit-category', + 'action' => 'add-tag', + 'tag-name' => 'blues', + ), + 'expected' => 'Category added.', + ), + 'add a category with message filtering' => array( + 'post_data' => array( + 'taxonomy' => 'category', + 'post_type' => 'post', + 'screen' => 'edit-category', + 'action' => 'add-tag', + 'tag-name' => 'techno', + ), + 'expected' => 'A new category added.', + 'callback' => static function( array $messages ) { + $messages['category'][1] = 'A new category added.'; + return $messages; + }, + ), + 'add a post_tag' => array( + 'post_data' => array( + 'taxonomy' => 'post_tag', + 'post_type' => 'post', + 'screen' => 'edit-post_tag', + 'action' => 'add-tag', + 'tag-name' => 'Louis Armstrong', + ), + 'expected' => 'Tag added.', + ), + ); + } + + /** + * @ticket 42937 + */ + public function test_adding_category_without_capability_should_error() { + $this->_setRole( 'subscriber' ); + + $_POST['taxonomy'] = 'category'; + $_POST['post_type'] = 'post'; + $_POST['screen'] = 'edit-category'; + $_POST['action'] = 'add-tag'; + $_POST['tag - name'] = 'disco'; + $_POST['_wpnonce_add-tag'] = wp_create_nonce( 'add-tag' ); + + $this->expectException( 'WPAjaxDieStopException' ); + $this->expectExceptionMessage( '-1' ); + $this->_handleAjax( 'add-tag' ); + } + + /** + * @ticket 42937 + */ + public function test_adding_existing_category_should_error() { + $this->_setRole( 'administrator' ); + + wp_insert_term( 'testcat', 'category' ); + + $_POST = array( + 'taxonomy' => 'category', + 'post_type' => 'post', + 'screen' => 'edit-category', + 'action' => 'add-tag', + 'tag-name' => 'testcat', + '_wpnonce_add-tag' => wp_create_nonce( 'add-tag' ), + ); + + try { + $this->_handleAjax( 'add-tag' ); + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + $expected = 'A term with the name provided already exists with this parent.'; + $this->assertSame( $expected, (string) $this->get_xml_response_taxonomy()->wp_error ); + } + + /** + * Helper method to get the taxonomy's response or error. + * + * @since 5.9.0 + * + * @return SimpleXMLElement Response or error object. + */ + private function get_xml_response_taxonomy() { + $xml = simplexml_load_string( $this->_last_response, 'SimpleXMLElement', LIBXML_NOCDATA ); + + return $xml->response->taxonomy; + } +}