WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 17 months ago

#19744 closed defect (bug) (fixed)

Custom post types doesn't receive pingbacks - url_to_postid() doesn't recognize CPT

Reported by: feedmeastraycat Owned by: wonderboymusic
Milestone: 3.7 Priority: normal
Severity: normal Version: 3.3.1
Component: Query Keywords: has-patch
Focuses: Cc:

Description (last modified by dd32)

It seams like custom post type doesn't receive pingbacks. The XML-RPC server doesn't recognize the URL. The url_to_postid() function in rewrite.php finds a match, but the query is all wrong.

Example, if I set up custom post type with no "rewrite" in the arguments.
The URL to a custom post type would be: mydomain.com/custom_post_type_name/post-slug/

The function url_to_postid() finds a match on:

custom_post_type_name/([^/]+)(/[0-9]+)?/?$

The query is:

custom_post_type_name=$matches[1]&page=$matches[2]

But the query string (after WP_MatchesMapRegexp::apply()) looks like this:

custom_post_type_name=post-slug&page=

And the array that is sent into WP_Query looks like this:

Array
(
    [tips_and_trix] => finns-sjukt-manga-tips-har
    [page] => 
)

Which makes url_to_postid() return 0; And XML-RCP server returns IXR_Error(33, ...)

Attachments (5)

url-postid-with-post-type.diff (1.3 KB) - added by wonderboymusic 2 years ago.
19744.patch (1.2 KB) - added by johnjamesjacoby 2 years ago.
Refreshed - added brackets and tweaked whitespace
19744_1.patch (2.6 KB) - added by faishal 23 months ago.
use get_post_types() instead of $GLOBALSwp_post_types? and also replace $GLOBALSwp_post_types? with get_post_types() and $GLOBALSwp_taxonomies? with get_taxonomies() in WP::parse_request() and WP_Query::parse_tax_query()
19744.diff (2.6 KB) - added by wonderboymusic 19 months ago.
19744.2.diff (3.5 KB) - added by wonderboymusic 17 months ago.

Download all attachments as: .zip

Change History (32)

comment:1 @dd323 years ago

  • Keywords reporter-feedback added

That all looks correct to me, the query strings and resulting array looks correct to me. The empty page field is expected.

I don't have the time to work out how to create a proper pingback request right now, but what does die($query->request); look like after line 340 of query.php (near the end of url_to_postid())

comment:2 @feedmeastraycat3 years ago

(I forgot to change my example "tips_and_trix" = "custom_post_type_name" and "finns-sjukt-manga-tips-har" = "post-slug)

die($query->request); after 340 of rewrite.php looks like this

SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND (wp_posts.ID = '0') AND wp_posts.post_type = 'page'  ORDER BY wp_posts.post_date DESC 

comment:3 @dd323 years ago

  • Keywords needs-patch added; reporter-feedback removed

and with a non-hierarchical post type I'm getting this:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')  ORDER BY wp_posts.post_date DESC LIMIT 0, 10

So yes, something isn't working quite right there.

comment:4 @dd323 years ago

The cause is because WP_Query doesn't accept a CPT_Name => CPT_Slug field, you need to pass in the post_type field as well.

Our rewrite rules don't set that, instead, it's set during the Query parsing here: wp-includes/class-wp.php#L274

I don't quite understand why that code isn't within WP_Query myself.

comment:5 @feedmeastraycat3 years ago

Yes. Verified. Adding post_type into the query fixes it.

Does this mean something new has to be added to pingback_ping() in the XML-RPC server for it to be able to understand custom post types?

comment:6 @dd323 years ago

  • Component changed from XML-RPC to Query
  • Description modified (diff)
  • Milestone changed from Awaiting Review to 3.4
  • Summary changed from Custom post type doesn't receive pingback to url_to_postid() doesn't reconise Custom post types

My suggestion is that the logic from WP::parse_request() that I mentioned above should be moved into WP_Query.

I'm going to let another dev weigh in on that however, as I might be missing something related..

I've altered the fields to match the problem a bit more too.

comment:7 @feedmeastraycat3 years ago

Another way of doing it would be to patch this in url_to_postid():

Before the "Look for matches." loop, add this:

$post_type_query_vars = array();
foreach ( $GLOBALS['wp_post_types'] as $post_type => $t )
	if ( $t->query_var )
		$post_type_query_vars[$t->query_var] = $post_type;

And then change this:

// Filter out non-public query 
global $wp;
parse_str($query, $query_vars);
$query = array();
foreach ( (array) $query_vars as $key => $value ) {
	if ( in_array($key, $wp->public_query_vars) )
		$query[$key] = $value;
	}

To this:

// Filter out non-public query vars
global $wp;
parse_str($query, $query_vars);
$query = array();
foreach ( (array) $query_vars as $key => $value ) {
	if ( in_array($key, $wp->public_query_vars) ) {
		$query[$key] = $value;
		if ( isset($post_type_query_vars[$key] ) ) {
			$query['post_type'] = $post_type_query_vars[$key];
			$query['name'] = $value;
		}
	}
}

Sorry. Don't know how to do patches here yet. :)
But that makes url_to_postid() recognize custom post types anyway. Just like in WP::parse_query().
(Copied code from there)

I've tested this and it works fine. And CPT receives pingbacks whit this fix.

So my original problem with CPT not receiving pingback seems to be valid. But the fix might be to make WP_Query understand CPT_Name => CPT_Slug. :) Thanks so far!

comment:8 @feedmeastraycat3 years ago

  • Summary changed from url_to_postid() doesn't reconise Custom post types to Custom post types doesn't receive pingbacks - url_to_postid() doesn't recognize CPT

Changed the summary because I feel that CPT being unable to receive pingbacks might be the bigger thing here. And that url_to_postid() is the underlaying cause, together with WP::parse_request() vs how WP_Query parses the same params.

comment:9 @rich_brat3 years ago

Is comment:7 by feedmeastraycat a working patch? Where do I put that code, what line numbers etc?

comment:10 @feedmeastraycat3 years ago

Well. More of an example on how a patch could be created. I'm not sure I'm confident enough to create an actual patch. It's just code that I've tested locally which seams to be fixing the issue.

The main issue here is that Custom post types doesn't receive pingbacks.
And according to my investigation (with the help from dd32) the reason is becuase url_to_postid() doesn't recognize CPT.

dd32 had his suggestion in comment 6.
And I had another suggestion on comment 7.
But I guess someone that knows more about WP_Query() needs to decide. :)

comment:11 @ryan3 years ago

  • Milestone changed from 3.4 to Future Release

comment:12 @wonderboymusic2 years ago

  • Keywords has-patch added; needs-patch removed
  • Owner set to wonderboymusic
  • Status changed from new to accepted

Patched - works with CPTs now

comment:13 @netweb2 years ago

  • Cc netweb added

comment:14 @SergeyBiryukov2 years ago

  • Milestone changed from Future Release to 3.6

comment:15 @johnjamesjacoby2 years ago

Patch is good, and works, and necessary for future bbPress enhancements. Thanks for bringing this back into the 3.6 scope, Sergey.

comment:16 @feedmeastraycat2 years ago

Great! Thanks as well. I'll be happy to see this fixed! :)

@johnjamesjacoby2 years ago

Refreshed - added brackets and tweaked whitespace

comment:17 @johnjamesjacoby2 years ago

Confirmed working as intended.

comment:18 @SergeyBiryukov2 years ago

We could probably use get_post_types() instead of $GLOBALS['wp_post_types'].

Could also create a separate ticket to replace $GLOBALS['wp_post_types'] with get_post_types() and $GLOBALS['wp_taxonomies'] with get_taxonomies() in WP::parse_request() and WP_Query::parse_tax_query().

comment:19 @alex-ye2 years ago

  • Cc nashwan.doaqan@… added

@faishal23 months ago

use get_post_types() instead of $GLOBALSwp_post_types? and also replace $GLOBALSwp_post_types? with get_post_types() and $GLOBALSwp_taxonomies? with get_taxonomies() in WP::parse_request() and WP_Query::parse_tax_query()

comment:20 @faishal23 months ago

  • Cc saiyedfaishal@… added

comment:21 @benjmay22 months ago

  • Cc bmay@… added

comment:22 @wonderboymusic21 months ago

  • Milestone changed from 3.6 to Future Release

@wonderboymusic19 months ago

comment:23 @wonderboymusic19 months ago

  • Milestone changed from Future Release to 3.7

Refreshed the whitespace, etc in the latest patch - using funcs instead of globals

comment:24 @MZAWeb19 months ago

Tested the last patch from @wonderboymusic on 3.6 for this http://bbpress.trac.wordpress.org/ticket/1430 and works great.
It'd be really cool to get this on into 3.7

comment:25 @ramiy17 months ago

  • Cc r_a_m_i@… added

+1 for 3.7!

@wonderboymusic17 months ago

comment:26 @wonderboymusic17 months ago

19744.2.diff​ makes url_to_postid() work for CPTs

comment:27 @wonderboymusic17 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 25659:

Make url_to_postid() work for custom post type URLs. Use get_post_types() and get_taxonomies() instead of directly accessing globals. Adds unit test.

Props faishal, for the globals fix.
Fixes #19744.

Note: See TracTickets for help on using tickets.