Last active
March 22, 2020 15:03
-
-
Save ideag/60d4b1e6185e62fa9a903bcf600f8a95 to your computer and use it in GitHub Desktop.
Remove prefix from CPT URL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Plugin Name: Arunas' No Prefix for CPT | |
* Version: 1.0.0 | |
* Description: Remove prefix from CPT URL | |
* Plugin URI: https://gist.github.com/ideag/60d4b1e6185e62fa9a903bcf600f8a95 | |
* Author: Arūnas Liuiza | |
* Author URI: https://www.arunas.co/ | |
*/ | |
add_action( 'plugins_loaded', array( 'Arunas_No_Prefix_CPT_Class', 'get_instance' ) ); | |
class Arunas_No_Prefix_CPT_Class { | |
protected $options = array( | |
'post_type' => 'arunas_cpt', | |
); | |
private static $instance; | |
public static function get_instance() { | |
if (null === self::$instance) { | |
self::$instance = new self(); | |
} | |
return self::$instance; | |
} | |
public function __construct() { | |
add_filter( 'post_type_link', array( $this, 'cpt_remove_base' ), 10, 2 ); | |
add_action( 'pre_get_posts', array( $this, 'cpt_fix_query' ), 101, 1 ); | |
add_filter( 'url_to_postid', array( $this, 'cpt_fix_url_to_postid' ), 100, 1 ); | |
// Prevent slug clashes. | |
add_filter( 'wp_unique_post_slug', array( $this, 'cpt_slug' ), 10, 6 ); | |
} | |
public function cpt_remove_base( $post_link, $post ) { | |
if ( $this->options['post_type'] !== $post->post_type ) { | |
return $post_link; | |
} | |
if ( 'publish' !== $post->post_status ) { | |
return $post_link; | |
} | |
$post_link = str_replace( "/{$post->post_type}/", '/', $post_link ); | |
return $post_link; | |
} | |
public function cpt_fix_query( $query ) { | |
global $wp; | |
if ( is_admin() ) { | |
return; | |
} | |
if ( ! $query->is_main_query() ) { | |
return; | |
} | |
if ( $query->get( 'queried_object_id' ) ) { | |
return; | |
} | |
if ( ! $query->get( 'pagename' ) && ! $query->get( 'attachment' ) && ! $query->get( 'name' ) && ! $query->get( 'category_name' ) && ! $query->is_404() ) { | |
return; | |
} | |
$post_name = $query->get( 'pagename' ); | |
$post_name = ( ! $post_name ) ? $this->_build_page_name( $query->get( 'attachment' ) ) : $post_name; | |
$post_name = ( ! $post_name ) ? $query->get( 'name' ) : $post_name; | |
$post_name = ( ! $post_name ) ? $query->get( 'category_name' ) : $post_name; | |
$post_name = ( ! $post_name ) ? $wp->request : $post_name; | |
if ( ! $post_name ) { | |
return; | |
} | |
$post_slug = $post_name; | |
$post_slug = substr( $post_slug, -1 ) == '/' ? substr( $post_slug, 0, -1 ) : $post_slug; | |
$pos = strrpos( $post_slug, '/' ); | |
$post_slug = substr( $post_slug, false !== $pos ? $pos + 1 : 0 ); | |
$post = get_page_by_path( $post_name, OBJECT, $this->options['post_type'] ); | |
if ( ! $post ) { | |
return false; | |
} | |
$post_type = $post->post_type; | |
$post_parent = (int) $post->post_parent; | |
$query->tax_query = null; | |
$query->is_attachment = false; | |
$query->is_category = false; | |
$query->is_archive = false; | |
$query->is_page = false; | |
$query->is_404 = false; | |
$query->is_single = true; | |
$query->is_singular = true; | |
$query->set( 'page', '' ); | |
$query->query['page'] = ''; | |
$query->set( 'pagename', null ); | |
unset( $query->query['pagename'] ); | |
$query->set( 'attachment', null ); | |
unset( $query->query['attachment'] ); | |
$query->set( 'category_name', null ); | |
unset( $query->query['category_name'] ); | |
$query->set( 'post_type', $post_type ); | |
$query->query['post_type'] = $post_type; | |
$query->set( 'name', $post_name ); | |
$query->query['name'] = $post_name; | |
$query->set( $post_type, $post_name ); | |
$query->query[ $post_type ] = $post_name; | |
} | |
public function cpt_fix_url_to_postid( $url ) { | |
// if we get a result the standard way, do nothing. | |
remove_filter( 'url_to_postid', array( $this, 'cpt_fix_url_to_postid' ), 100, 1 ); | |
$id = url_to_postid( $url ); | |
add_filter( 'url_to_postid', array( $this, 'cpt_fix_url_to_postid' ), 100, 1 ); | |
if ( 0 !== $id ) { | |
return $url; | |
} | |
// Try for flexi page. If works, convert url to one with ?p=ID. | |
$home = home_url(); | |
$path = untrailingslashit( str_replace( $home, '', $url ) ); | |
$path = explode( '/', $path ); | |
$name = array_pop( $path ); | |
$post_obj = get_page_by_path( $name, OBJECT, 'flexi_page' ); | |
if ( $post_obj ) { | |
$url = add_query_arg( 'p', $post_obj->ID, $home ); | |
} | |
return $url; | |
} | |
public function cpt_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) { | |
global $wpdb; | |
$post_types_no_conflict = array( 'post', 'page', 'attachment', $this->options['post_type'] ); | |
// should we do cross post-type checking? | |
if ( ! in_array( $post_type, $post_types_no_conflict ) ) { | |
return $slug; | |
} | |
$post_types_in = implode( "', '", $post_types_no_conflict ); | |
$post_types_in = "'{$post_types_in}'"; | |
$slug_base = preg_replace( '/(\-[0-9]+)$/ims', '', $slug ); | |
$slug_regex = "^{$slug_base}(\-[0-9]+)?$"; | |
$similar_slugs = $wpdb->get_col( | |
$wpdb->prepare( | |
"SELECT post_name FROM {$wpdb->posts} WHERE post_name RLIKE %s AND post_type IN ( $post_types_in ) AND ID != %d AND post_status = 'publish'", | |
$slug_regex, | |
$post_ID | |
) | |
); | |
// do we have any similar slugs? | |
if ( ! $similar_slugs ) { | |
return $slug; | |
} | |
// is the original slug in the list? | |
if ( ! in_array( $slug, $similar_slugs ) ) { | |
return $slug; | |
} | |
// find the largest slug number. | |
$max = 1; | |
foreach ( $similar_slugs as $similar_slug ) { | |
$similar_slug = explode( '-', $similar_slug ); | |
$no = (int) end( $similar_slug ); | |
$max = $no > $max ? $no : $max; | |
} | |
++$max; | |
$new_slug = "{$slug_base}-{$max}"; | |
return $new_slug; | |
} | |
private function _build_page_name( $post_slug ) { | |
global $wpdb; | |
if ( ! $post_slug ) { | |
return $post_slug; | |
} | |
$post_id = $wpdb->get_var( | |
$wpdb->prepare( | |
"SELECT `ID` FROM {$wpdb->posts} WHERE post_name = %s", | |
$post_slug | |
) | |
); | |
$permalink = get_permalink( $post_id ); | |
$name = str_replace( home_url(), '', $permalink ); | |
return $name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment