diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index 6526a10667..e125014dd7 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -99,6 +99,70 @@ function wp_ajax_fetch_list() { wp_die( 0 ); } +/** + * Ajax handler for tag search. + * + * @since 3.1.0 + */ +function wp_ajax_ajax_tag_search() { + if ( ! isset( $_GET['tax'] ) ) { + wp_die( 0 ); + } + + $taxonomy = sanitize_key( $_GET['tax'] ); + $tax = get_taxonomy( $taxonomy ); + if ( ! $tax ) { + wp_die( 0 ); + } + + if ( ! current_user_can( $tax->cap->assign_terms ) ) { + wp_die( -1 ); + } + + $s = wp_unslash( $_GET['q'] ); + + $comma = _x( ',', 'tag delimiter' ); + if ( ',' !== $comma ) { + $s = str_replace( $comma, ',', $s ); + } + if ( false !== strpos( $s, ',' ) ) { + $s = explode( ',', $s ); + $s = $s[ count( $s ) - 1 ]; + } + $s = trim( $s ); + + /** + * Filters the minimum number of characters required to fire a tag search via Ajax. + * + * @since 4.0.0 + * + * @param int $characters The minimum number of characters required. Default 2. + * @param WP_Taxonomy $tax The taxonomy object. + * @param string $s The search term. + */ + $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s ); + + /* + * Require $term_search_min_chars chars for matching (default: 2) + * ensure it's a non-negative, non-zero integer. + */ + if ( ( $term_search_min_chars == 0 ) || ( strlen( $s ) < $term_search_min_chars ) ) { + wp_die(); + } + + $results = get_terms( + $taxonomy, + array( + 'name__like' => $s, + 'fields' => 'names', + 'hide_empty' => false, + ) + ); + + echo join( $results, "\n" ); + wp_die(); +} + /** * Ajax handler for compression testing. * diff --git a/wp-admin/includes/deprecated.php b/wp-admin/includes/deprecated.php index 61989cb5b9..e65fe5a79c 100644 --- a/wp-admin/includes/deprecated.php +++ b/wp-admin/includes/deprecated.php @@ -1514,61 +1514,3 @@ function options_permalink_add_js() { cap->assign_terms ) ) { - wp_die( -1 ); - } - - $s = wp_unslash( $_GET['q'] ); - - $comma = _x( ',', 'tag delimiter' ); - if ( ',' !== $comma ) { - $s = str_replace( $comma, ',', $s ); - } - if ( false !== strpos( $s, ',' ) ) { - $s = explode( ',', $s ); - $s = $s[ count( $s ) - 1 ]; - } - $s = trim( $s ); - - /** This filter is documented in wp-includes/script-loader.php */ - $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s ); - - /* - * Require $term_search_min_chars chars for matching (default: 2) - * ensure it's a non-negative, non-zero integer. - */ - if ( ( $term_search_min_chars == 0 ) || ( strlen( $s ) < $term_search_min_chars ) ) { - wp_die(); - } - - $results = get_terms( - $taxonomy, array( - 'name__like' => $s, - 'fields' => 'names', - 'hide_empty' => false, - ) - ); - - echo join( $results, "\n" ); - wp_die(); -} diff --git a/wp-admin/js/tags-suggest.js b/wp-admin/js/tags-suggest.js index 6c13c815ba..6465cc9959 100644 --- a/wp-admin/js/tags-suggest.js +++ b/wp-admin/js/tags-suggest.js @@ -1,13 +1,12 @@ /** * Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies. - * - * @output wp-admin/js/tags-suggest.js */ ( function( $ ) { if ( typeof window.tagsSuggestL10n === 'undefined' || typeof window.uiAutocompleteL10n === 'undefined' ) { return; } + var tempID = 0; var separator = window.tagsSuggestL10n.tagDelimiter || ','; function split( val ) { @@ -54,15 +53,33 @@ term = getLast( request.term ); - $.get( window.tagsSuggestL10n.restURL, { - _fields: [ 'id', 'name' ], - taxonomy: taxonomy, - search: term + $.get( window.ajaxurl, { + action: 'ajax-tag-search', + tax: taxonomy, + q: term } ).always( function() { $element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes? } ).done( function( data ) { - cache = data; - response( data ); + var tagName; + var tags = []; + + if ( data ) { + data = data.split( '\n' ); + + for ( tagName in data ) { + var id = ++tempID; + + tags.push({ + id: id, + name: data[tagName] + }); + } + + cache = tags; + response( tags ); + } else { + response( tags ); + } } ); last = request.term; @@ -101,7 +118,7 @@ close: function() { $element.attr( 'aria-expanded', 'false' ); }, - minLength: window.tagsSuggestL10n.minChars, + minLength: 2, position: { my: 'left top+2', at: 'left bottom', diff --git a/wp-admin/js/tags-suggest.min.js b/wp-admin/js/tags-suggest.min.js index b701171e3e..984a8863b7 100644 --- a/wp-admin/js/tags-suggest.min.js +++ b/wp-admin/js/tags-suggest.min.js @@ -1 +1 @@ -!function(a){function b(a){return a.split(new RegExp(d+"\\s*"))}function c(a){return b(a).pop()}if("undefined"!=typeof window.tagsSuggestL10n&&"undefined"!=typeof window.uiAutocompleteL10n){var d=window.tagsSuggestL10n.tagDelimiter||",";a.fn.wpTagsSuggest=function(e){var f,g,h=a(this);e=e||{};var i=e.taxonomy||h.attr("data-wp-taxonomy")||"post_tag";return delete e.taxonomy,e=a.extend({source:function(b,d){var e;return g===b.term?void d(f):(e=c(b.term),a.get(window.tagsSuggestL10n.restURL,{_fields:["id","name"],taxonomy:i,search:e}).always(function(){h.removeClass("ui-autocomplete-loading")}).done(function(a){f=a,d(a)}),void(g=b.term))},focus:function(a,b){h.attr("aria-activedescendant","wp-tags-autocomplete-"+b.item.id),a.preventDefault()},select:function(c,e){var f=b(h.val());return f.pop(),f.push(e.item.name,""),h.val(f.join(d+" ")),a.ui.keyCode.TAB===c.keyCode?(window.wp.a11y.speak(window.tagsSuggestL10n.termSelected,"assertive"),c.preventDefault()):a.ui.keyCode.ENTER===c.keyCode&&(c.preventDefault(),c.stopPropagation()),!1},open:function(){h.attr("aria-expanded","true")},close:function(){h.attr("aria-expanded","false")},minLength:window.tagsSuggestL10n.minChars,position:{my:"left top+2",at:"left bottom",collision:"none"},messages:{noResults:window.uiAutocompleteL10n.noResults,results:function(a){return a>1?window.uiAutocompleteL10n.manyResults.replace("%d",a):window.uiAutocompleteL10n.oneResult}}},e),h.on("keydown",function(){h.removeAttr("aria-activedescendant")}).autocomplete(e).autocomplete("instance")._renderItem=function(b,c){return a('