From a37ee6171e1ba969307128cc901fa6cddd461b41 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Tue, 8 Jan 2019 03:46:58 +0000 Subject: [PATCH] Permalinks: Add a `pre_wp_unique_post_slug` filter. Returning a non-`null` value on this fillter will cause `wp_unique_post_slug()` to return early with that value, skipping potentially expensive database queries on some sites. Props coffee2code, javorszky, iCaleb. Fixes #21112. git-svn-id: https://develop.svn.wordpress.org/trunk@44454 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/post.php | 20 ++++++++++++++++++++ tests/phpunit/tests/post.php | 26 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 8debd3db3b..f3696341da 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4117,6 +4117,26 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p return $slug; } + /** + * Filters the post slug before it is generated to be unique. + * + * Returning a non-null value will short-circuit the + * unique slug generation, returning the passed value instead. + * + * @since 5.1.0 + * + * @param string $override_slug Short-circuit return value. + * @param string $slug The desired slug (post_name). + * @param int $post_ID Post ID. + * @param string $post_status The post status. + * @param string $post_type Post type. + * @param int $post_parent Post parent ID. + */ + $override_slug = apply_filters( 'pre_wp_unique_post_slug', null, $slug, $post_ID, $post_status, $post_type, $post_parent ); + if ( null !== $override_slug ) { + return $override_slug; + } + global $wpdb, $wp_rewrite; $original_slug = $slug; diff --git a/tests/phpunit/tests/post.php b/tests/phpunit/tests/post.php index 3239170a09..d0d902978c 100644 --- a/tests/phpunit/tests/post.php +++ b/tests/phpunit/tests/post.php @@ -1357,4 +1357,30 @@ class Tests_Post extends WP_UnitTestCase { $this->assertEquals( $changeset_data, json_decode( get_post( $post_id )->post_content, true ) ); } + /** + * Test ensuring that the post_slug can be filtered with a custom value short circuiting the built in + * function that tries to create a unique name based on the post name. + * + * @see wp_unique_post_slug() + * @ticket 21112 + */ + function test_pre_wp_unique_post_slug_filter() { + add_filter( 'pre_wp_unique_post_slug', array( $this, 'filter_pre_wp_unique_post_slug' ), 10, 6 ); + + $post_id = $this->factory->post->create( + array( + 'title' => 'An example', + 'post_status' => 'publish', + 'post_type' => 'page', + ) + ); + $post = get_post( $post_id ); + $this->assertEquals( 'override-slug-' . $post->post_type, $post->post_name ); + + remove_filter( 'pre_wp_unique_post_slug', array( $this, 'filter_pre_wp_unique_post_slug' ), 10, 6 ); + } + + function filter_pre_wp_unique_post_slug( $default, $slug, $post_ID, $post_status, $post_type, $post_parent ) { + return 'override-slug-' . $post_type; + } }