WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 4 months ago

#37043 reviewing enhancement

New filter `pre_unique_post_slug`

Reported by: sebastian.pisula Owned by: boonebgorges
Milestone: Priority: normal
Severity: normal Version:
Component: Posts, Post Types Keywords: has-patch needs-refresh
Focuses: Cc:
PR Number:

Description

This filter will be for multilanguages plugins helpful.

For example I have page:
News in English with url http://example.com/en/news/ and
News in Polish with url http://example.com/pl/news/

For Polish version this will be have slug news-2 but should be have news.

If new filter will be added then we can generate slug for my pages.

I know that I can use wp_unique_post_slug filter but more optimally will be add pre_unique_post_slug filter because will be less SQL Queries because this code:

<?php
if ( is_post_type_hierarchical( $post_type ) ) {
                if ( 'nav_menu_item' == $post_type )
                        return $slug;

                /*
                 * Page slugs must be unique within their own trees. Pages are in a separate
                 * namespace than posts so page slugs are allowed to overlap post slugs.
                 */
                $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
                $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );

                /**
                 * Filters whether the post slug would make a bad hierarchical post slug.
                 *
                 * @since 3.1.0
                 *
                 * @param bool   $bad_slug    Whether the post slug would be bad in a hierarchical post context.
                 * @param string $slug        The post slug.
                 * @param string $post_type   Post type.
                 * @param int    $post_parent Post parent ID.
                 */
                if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug )  || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
                        $suffix = 2;
                        do {
                                $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
                                $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
                                $suffix++;
                        } while ( $post_name_check );
                        $slug = $alt_post_name;
                }
        } else {
                // Post slugs must be unique across all posts.
                $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
                $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );

                // Prevent new post slugs that could result in URLs that conflict with date archives.
                $post = get_post( $post_ID );
                $conflicts_with_date_archive = false;
                if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
                        $permastructs   = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
                        $postname_index = array_search( '%postname%', $permastructs );

                        /*
                         * Potential date clashes are as follows:
                         *
                         * - Any integer in the first permastruct position could be a year.
                         * - An integer between 1 and 12 that follows 'year' conflicts with 'monthnum'.
                         * - An integer between 1 and 31 that follows 'monthnum' conflicts with 'day'.
                         */
                        if ( 0 === $postname_index ||
                                ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num ) ||
                                ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num )
                        ) {
                                $conflicts_with_date_archive = true;
                        }
                }

                /**
                 * Filters whether the post slug would be bad as a flat slug.
                 *
                 * @since 3.1.0
                 *
                 * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
                 * @param string $slug      The post slug.
                 * @param string $post_type Post type.
                 */
                if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || $conflicts_with_date_archive || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
                        $suffix = 2;
                        do {
                                $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
                                $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
                                $suffix++;
                        } while ( $post_name_check );
                        $slug = $alt_post_name;
                }
        }

Will useless for my plugin and unnecessary SQL Queries will be generate

Attachments (4)

37043.patch (1.1 KB) - added by sebastian.pisula 3 years ago.
370431.patch (2.0 KB) - added by sebastian.pisula 3 years ago.
37043.2.patch (2.0 KB) - added by sebastian.pisula 3 years ago.
37043.3.diff (1.8 KB) - added by barryceelen 3 years ago.
Align @param tags according to coding standards

Download all attachments as: .zip

Change History (11)

#1 @boonebgorges
3 years ago

  • Component changed from General to Posts, Post Types
  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 4.6

This seems OK to me. Two things:

  1. I'd like to wait until after the function signature change in #20419, because it'll change the params passed to the filter.
  2. We should do the same thing in wp_unique_term_slug().

#2 @sebastian.pisula
3 years ago

  • Keywords has-patch added; needs-patch removed

#3 @Compute
3 years ago

+1 for this change. Would very much like to see this change for both post and term unique slug.

#4 @ocean90
3 years ago

  • Owner set to boonebgorges
  • Status changed from new to reviewing

This ticket was mentioned in Slack in #core by ocean90. View the logs.


3 years ago

#6 @ocean90
3 years ago

  • Keywords needs-refresh added
  • Milestone changed from 4.6 to Future Release

37043.2.patch: The @param tags should be aligned according to the coding standards.

@barryceelen
3 years ago

Align @param tags according to coding standards

#7 @barryceelen
3 years ago

@ocean90 (I think adding attachments don't trigger notifications without adding a comment?) I updated the @param tags. Is there anything more you think needs doing?

Note: See TracTickets for help on using tickets.