[wp-trac] [WordPress Trac] #42148: url_to_postid plain permalinks for CPTs

WordPress Trac noreply at wordpress.org
Sun Oct 8 11:42:22 UTC 2017


#42148: url_to_postid plain permalinks for CPTs
-------------------------+-----------------------------
 Reporter:  soulseekah   |      Owner:
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  Permalinks   |    Version:  trunk
 Severity:  normal       |   Keywords:
  Focuses:               |
-------------------------+-----------------------------
 Would be nice to have {{{url_to_postid}}} working with plain permalinks
 for custom post types.

 There's are currently some issues in {{{url_to_postid}}} where the wrong
 ID is returned for custom post type plain permalinks (query-based).

 {{{
 <?php
 add_action( 'init', function() {
         /** Register a post type */
         register_post_type( 'findme', array(
                 'public' => true
         ) );

         /** Create a post */
         $post_id = wp_insert_post( array( 'post_type' => 'findme',
 'post_status' => 'publish' ) );
         $findme = get_permalink( $post_id );
         $found = url_to_postid( $findme );

         /** Guess it */
         printf( "%s (%s) == %s (%s)", $post_id, $findme, $found,
 get_permalink( $found ) );
         exit;
 } );
 }}}

 {{{30 (http://localhost:8080/?findme=30) == 0 ()}}} and {{{30
 (http://localhost:8080/?findme=30) == 2 (http://localhost:8080/)}}} if the
 frontpage is setup to point ot a post.

 Why is it not working? Why is the frontpage post being returned? Let's see
 how the {{url_to_postid}} function works:

 {{{
 // First, check to see if there is a 'p=N' or 'page_id=N' to match against
 if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values) )
 {
   $id = absint($values[2]);
   if ( $id )
     return $id;
 }
 }}}

 Then?

 {{{
 if ( trim( $url, '/' ) === home_url() && 'page' == get_option(
 'show_on_front' ) ) {
   $page_on_front = get_option( 'page_on_front' );
   if ( $page_on_front && get_post( $page_on_front ) instanceof WP_Post ) {
     return (int) $page_on_front;
   }
 }
 }}}

 Uh, wait what... already? So a short-circuit without checking the custom
 post types. And that's understandable, since there is inherently no
 support for custom post type ID mappings as pointed out by:

 {{{
 // Check to see if we are using rewrite rules
 $rewrite = $wp_rewrite->wp_rewrite_rules();

 // Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so
 we're out of options
 if ( empty($rewrite) )
   return 0;
 }}}

 What stands in our way to find the URL earlier?

 1. The query var is not one of p, page_id, attachment_id
 2. The query var value for CPTs is not necessarily, and most often not
 numeric (the post_title)

 A proposed solution would be to look at the query parameters much higher,
 maybe by injecting the custom ones, ones that support slugs as well, since
 WordPress sets the {{{page_title}}} for a CPT itself, so that {{{\d+}}}
 check would fail.

 Use case? Well, this was encountered when trying to paste plain oEmbed
 URLs for a custom post type
 (https://github.com/gravityview/GravityView/issues/927).

--
Ticket URL: <https://core.trac.wordpress.org/ticket/42148>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list