WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 months ago

#20783 closed enhancement (fixed)

Add filter to wp_unique_term_slug()

Reported by: bolo1988 Owned by: boonebgorges
Milestone: 4.3 Priority: normal
Severity: normal Version: 3.3.2
Component: Taxonomy Keywords: has-patch needs-testing
Focuses: Cc:

Description

I can't modify the result of wp_unique_term_slug(), but if using the following code:

function wp_unique_term_slug($slug, $term) {
	global $wpdb;

	if ( ! term_exists( $slug ) )
		return $slug;

	// If the taxonomy supports hierarchy and the term has a parent, make the slug unique
	// by incorporating parent slugs.
	if ( is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent) ) {
		$the_parent = $term->parent;
		while ( ! empty($the_parent) ) {
			$parent_term = get_term($the_parent, $term->taxonomy);
			if ( is_wp_error($parent_term) || empty($parent_term) )
				break;
			$slug .= '-' . $parent_term->slug;
			if ( ! term_exists( $slug ) )
				return $slug;

			if ( empty($parent_term->parent) )
				break;
			$the_parent = $parent_term->parent;
		}
	}

	// If we didn't get a unique slug, try appending a number to make it unique.
	if ( !empty($args['term_id']) )
		$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $args['term_id'] );
	else
		$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug );

	if ( $wpdb->get_var( $query ) ) {
		$num = 2;
		do {
			$alt_slug = $slug . "-$num";
			$num++;
			$slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) );
		} while ( $slug_check );
		$slug = $alt_slug;
	}

	return apply_filters('unique_term_slug', $slug);
}

Attachments (3)

20783.diff (1.2 KB) - added by coffee2code 3 years ago.
20783.2.diff (2.6 KB) - added by coffee2code 3 years ago.
Updated patch to better align with wp_unique_post_slug()
20783.3.diff (3.8 KB) - added by boonebgorges 4 months ago.

Download all attachments as: .zip

Change History (14)

@coffee2code3 years ago

comment:1 @coffee2code3 years ago

  • Component changed from General to Taxonomy
  • Keywords has-patch added
  • Type changed from defect (bug) to enhancement
  • Version set to 3.3.2

Patch 20783.diff adds 'wp_unique_term_slug' filter. The $original_slug arg was put last to be consistent with the proposed patch for wp_unique_post_slug() in #20480.

comment:2 @coffee2code3 years ago

  • Summary changed from wp_unique_term_slug() have no filter to Add filter to wp_unique_term_slug()

@coffee2code3 years ago

Updated patch to better align with wp_unique_post_slug()

comment:3 follow-up: @coffee2code3 years ago

Patch 20783.2.diff brings wp_unique_term_slug() into greater alignment with its post counterpart, wp_unique_post_slug():

  • Calls wp_unique_term_slug on an earlier return of $slug
  • Adds wp_unique_term_slug_is_bad_hierarchical_slug and wp_unique_term_slug_is_bad_flat_slug filters as introduced in [16960] for #15726 to allow filtering of potentially bad hierarchical or flat slugs.
  • Adds pre_wp_unique_term_slug filter early in function to short-circuit add the db queries, filters, etc if the hooking function's intent is to fully implement its own slug handling (the only thing not already part of wp_unique_post_slug(), but proposed in #21112)

(The addition of the *is_bad* slugs prompted by #21093, which was closed in favor of this ticket.)

comment:4 in reply to: ↑ 3 @wpsmith3 years ago

  • Cc travis@… added
  • Keywords dev-feedback needs-testing added

Replying to coffee2code:

Patch 20783.2.diff brings wp_unique_term_slug() into greater alignment with its post counterpart, wp_unique_post_slug():

  • Calls wp_unique_term_slug on an earlier return of $slug
  • Adds wp_unique_term_slug_is_bad_hierarchical_slug and wp_unique_term_slug_is_bad_flat_slug filters as introduced in [16960] for #15726 to allow filtering of potentially bad hierarchical or flat slugs.
  • Adds pre_wp_unique_term_slug filter early in function to short-circuit add the db queries, filters, etc if the hooking function's intent is to fully implement its own slug handling (the only thing not already part of wp_unique_post_slug(), but proposed in #21112)

(The addition of the *is_bad* slugs prompted by #21093, which was closed in favor of this ticket.)

Thanks coffee2code for incorporating my patch with this patch.

comment:5 @SergeyBiryukov3 years ago

#22291 was marked as a duplicate.

comment:6 @Chouby22 months ago

  • Cc frederic.demarle@… added

comment:7 @boonebgorges4 months ago

In 32507:

Improve unit tests for wp_unique_term_slug().

See #20783.

comment:8 @boonebgorges4 months ago

  • Keywords dev-feedback removed
  • Milestone changed from Awaiting Review to 4.3

I like the idea of adding filters here, but I'm going to propose something a bit different. See 20783.3.diff.

First, I've rearranged the logic so that we return only once. This allows us to have just a single apply_filters() call on the return value, which I think is nicer.

Second, I've removed the distinction between the different 'is_bad' filters. wp_unique_post_slug() has branching logic for attachment vs hierarchical vs non-hierarchical. wp_unique_term_slug() doesn't branch in such a clean way, so having two different filters doesn't make sense to me. The taxonomy will be available in the $term object passed to the filter, so the callback can make its own distinction if necessary.

Does this reordering make sense, @coffee2code and others?

@boonebgorges4 months ago

comment:9 follow-up: @obenland3 months ago

It does, although I'd probably prefer a more verbose variable name than $is_bad.

We have only two weeks left to make a decision on this ticket for 4.3.

comment:10 in reply to: ↑ 9 @boonebgorges3 months ago

Replying to obenland:

It does, although I'd probably prefer a more verbose variable name than $is_bad.

I was trying to emulate the delightful spirit of the "wp_unique_term_slug_is_bad_slug" filter, but point taken.

comment:11 @boonebgorges3 months ago

  • Owner set to boonebgorges
  • Resolution set to fixed
  • Status changed from new to closed

In 32837:

Add filters to wp_unique_term_slug().

This changeset adds two new filters:

  • 'wp_unique_term_slug_is_bad_slug' lets developers control whether a test slug needs to be made unique, before the queries required to build a suffix are performed.
  • 'wp_unique_term_slug' filters the output of the function.

These changes introduce parity with the filters in wp_unique_post_slug().

Props coffee2code, bolo1988, boonebgorges.
Fixes #20783.

Note: See TracTickets for help on using tickets.