Skip to content

Instantly share code, notes, and snippets.

@ideag
Last active March 22, 2020 15:03
Show Gist options
  • Save ideag/60d4b1e6185e62fa9a903bcf600f8a95 to your computer and use it in GitHub Desktop.
Save ideag/60d4b1e6185e62fa9a903bcf600f8a95 to your computer and use it in GitHub Desktop.
Remove prefix from CPT URL
<?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