not-only-code / qtranslate-slug

Adds support for permalink translations and fix some Qtranslate deficiencies since wordpress 3.0
http://wordpress.org/extend/plugins/qtranslate-slug
46 stars 31 forks source link

Change rules for Slug prevent duplicates #4

Open not-only-code opened 12 years ago

not-only-code commented 12 years ago

Reference: http://wordpress.org/support/topic/plugin-qtranslate-slug-multiple-pages-with-same-slug-name-does-not-work?replies=4

page-a/page-b/

page-c/page-b-2/ => should be => page-c/page-b/

kuchenundkakao commented 11 years ago

I changed the function some time ago like this for a specific website. It seems to work (for the site), but i think it needs testing:

public function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $lang ) {
        if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
            return $slug;

        global $wpdb, $wp_rewrite;

        $feeds = $wp_rewrite->feeds;
        if ( ! is_array( $feeds ) )
            $feeds = array();

        $meta_key = $this->get_meta_key($lang);
        $hierarchical_post_types = get_post_types( array('hierarchical' => true) );
        if ( 'attachment' == $post_type ) {
            // Attachment slugs must be unique across all types.
            $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
            $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );

            if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
                $suffix = 2;
                do {
                    $alt_post_name = substr ($slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
                    $post_name_check = $wpdb->get_var( $wpdb->prepare($check_sql, $alt_post_name, $post_ID ) );
                    $suffix++;
                } while ( $post_name_check );
                $slug = $alt_post_name;
            }
        } elseif ( in_array( $post_type, $hierarchical_post_types ) ) {
                    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 $wpdb->postmeta.meta_value FROM $wpdb->posts,$wpdb->postmeta WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '%s' AND $wpdb->postmeta.meta_value = '%s' AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d LIMIT 1";
            $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $meta_key, $slug, $post_ID, $post_parent ) );

                    if ( $post_name_check || in_array( $slug, $feeds ) || 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 = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
                                    $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $meta_key, $alt_post_name, $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 $wpdb->postmeta.meta_value FROM $wpdb->posts,$wpdb->postmeta WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '%s' AND $wpdb->postmeta.meta_value = '%s' AND $wpdb->posts.post_type = %s AND ID != %d LIMIT 1";
            $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $meta_key, $slug, $post_type, $post_ID ) );

            if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
                $suffix = 2;
                do {
                    $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
                    $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $meta_key, $alt_post_name, $post_type, $post_ID ) );
                    $suffix++;
                } while ( $post_name_check );
                $slug = $alt_post_name;
            }
        }

        return $slug;
    }
not-only-code commented 11 years ago

is pending review