WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#18747 closed defect (bug) (invalid)

Custom Taxonomy Search/Filter Bug

Reported by: wordpressplugindeveloper Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Query Keywords:
Focuses: Cc:

Description (last modified by scribu)

First of all, I'm really sorry for my previous fake report.
This time, I have done enough search and test, and I can't find out a solution.
I'm using fresh 3.2.1 installation for testing this plugin.

http://wordpress.stackexchange.com/questions/578/adding-a-taxonomy-filter-to-admin-list-for-a-custom-post-type/3215

https://gist.github.com/541505

public param value is true.
exclude_from_search is false

However, it doesn't work so I have to trace the wordpress source code.
Here is what I find in the 177th line in wp-includes/query.php.

$tax_query[] = array(
	'taxonomy' => 'category',
	******
);

then,

$this->tax_query = new WP_Tax_Query( $tax_query );

in the 2199th line,

$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );

WP_Tax_Query is in wp-includes/taxonomy.php

get_sql -> clean_query -> transform_query invokes sql operation

SELECT $wpdb->term_taxonomy.******* WHERE taxonomy = 'query['taxonomy']'
AND *****

however, the 'query['taxonomy']' is 'category' which was hardcoded in the 177th line in wp-includes/query.php.

Is this a bug?

Change History (20)

comment:1 scribu3 years ago

  • Component changed from General to Query
  • Description modified (diff)

comment:2 scribu3 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

No, it is not a bug in WP Core.

There are certain query vars such as 'cat', 'category__in' etc. which are meant to be used only for categories.

Also, the code you mentioned $tax_query[] = array( 'taxonomy' => 'category', is not at line 177 but at line 1745.

Last edited 3 years ago by scribu (previous) (diff)

comment:3 wordpressplugindeveloper3 years ago

yep, that's right it is typo.

I know "there are certain query vars such as 'cat', 'category__in', however, 'Custom Taxonomy' is also one type of category, right?

In the business listing plugin case, the taxonomy should be business (according to wp_term_taxonomy table).

Last edited 3 years ago by scribu (previous) (diff)

comment:4 scribu3 years ago

'Custom Taxonomy' is also one type of category, right?

No, 'category' is one type of taxonomy: http://codex.wordpress.org/Taxonomies

If you actually read the detailed answer on WPSE, you will understand what's going on.

comment:5 wordpressplugindeveloper3 years ago

Thanks for your help and I'm feeling sorry to bother you. It is the second time. :[
Really appreciate your work.

Just wonder is there a way to implement the same "View all categories" in the custom post type page.
I'm using the business listing plugin but it doesn't work for me. I can see it was working great accordinng to the screenshots in stackexchange.

comment:6 scribu3 years ago

It's unfortunate that it takes so much work to do this.

I suggest you add a comment to the gist page.

comment:7 wordpressplugindeveloper3 years ago

I hijack the parse_query and try to add taxonomy parm with custom taxonomy.

$tax_query[] = array(

'taxonomy' => 'category',

)

however, as you can see, the $tax_query is an array. So two array then.
That one I hijicak is correct and the other one is generated by the 1745th line.

WP_Tax_Query will use transform_query to get terms data, however, it uses the term_id to get terms data from category taxonomy. You know, it returns nothing.

these code below is part of get_sql.
foreach ( $this->queries as $query ) {

........................

if ( empty( $terms ) ) {

if ( 'OR' == $this->relation )

continue;

else

return self::$no_results;

}

.............
}

Can you see? the terms is absolutely empty because the term_id in category taxonomy didn't exists.

comment:8 wordpressplugindeveloper3 years ago

anyway, thanks for your help. Maybe I have to hardcode my own sql code.

comment:9 scribu3 years ago

Can you see? the terms is absolutely empty because the term_id in category taxonomy didn't exists.

I'm afraid I can't. Give me an example URL.

Last edited 3 years ago by scribu (previous) (diff)

comment:10 wordpressplugindeveloper3 years ago

http://img831.imageshack.us/img831/4650/twoarray.jpg

http://img90.imageshack.us/img90/9959/wrongn.jpg

http://img714.imageshack.us/img714/1388/rightdm.jpg

the wrong and right images are in transform_query in 778th line of taxonomy.php. The transofrm_query is indirectly called by get_sql. get_sql method is very important because it'll generate taxonomy join condition for get_posts.

comment:11 wordpressplugindeveloper3 years ago

due to the array #2,

foreach ( $this->queries as $query ) {

........................

if ( empty( $terms ) ) {

if ( 'OR' == $this->relation )

continue;

else

return self::$no_results;

}

............. }

the whole query just return self::$no_results; and cannot generate join condition.

comment:12 scribu3 years ago

No, that doesn't help me. Give me an actual URL: ?business=123 and what you expect the tax_query object to look like.

comment:13 wordpressplugindeveloper3 years ago

edit.php?s&post_status=all&post_type=listing&action=-1&m=0&business=101&paged=1&mode=list&action2=-1

http://img853.imageshack.us/img853/4451/84593362.jpg

comment:14 scribu3 years ago

Ok, here's an alternative approach:

Define a new query var, 'business_id' and use the 'request' filter to transform it into a 'tax_query':

define( 'MY_TAX_NAME', 'business' );
define( 'MY_TAX_QV', 'business_id' );

class My_Tax_Enhancement {

	function init_qv() {
		$GLOBALS['wp']->add_query_var( MY_TAX_QV );
	}

	function parse_qv( $request ) {
		if ( isset( $request[MY_TAX_QV] ) ) {
			$request['tax_query'] = array(
				array(
					'taxonomy' => MY_TAX_NAME,
					'terms' => $request[MY_TAX_QV],
				)
			);
		}

		return $request;
	}
}

add_filter( 'init', array( 'My_Tax_Enhancement', 'init_qv' ) );
add_filter( 'request', array( 'My_Tax_Enhancement', 'parse_qv' ) );

comment:15 wordpressplugindeveloper3 years ago

lol, don't bother it.

$this->tax_query = new WP_Tax_Query( $tax_query );

$tax_query is

Array
(

[0] => Array

(

[taxonomy] => blog_category
[terms] => Array

(

[0] => 98

)

)

[1] => Array

(

[taxonomy] => category
[terms] => Array

(

[0] => 98

)

[field] => term_id
[include_children] =>

)

)

your approach is working the same way as me. If it still has taxonomy => category , then I definitely get the posts in blog_category in this case.

Never mind. thanks for your anyway.

comment:16 scribu3 years ago

With the URL you gave me, there's no way that could happen, unless there's some other code interfering.

comment:17 scribu3 years ago

That is, if you're using my code and using 'business_id' as a query var, not 'business'.

Last edited 3 years ago by scribu (previous) (diff)

comment:18 scribu3 years ago

Follow-up: #18748

comment:19 wordpressplugindeveloper3 years ago

Sorry for the late reply. I was inspired by your tax_query array.
Here is the ultimate solution

add_action('request','my_request');
			
function my_request($request) {
				
	if ($request['post_type']=='listing' && isset($request['business']) ) {
		$term = get_term_by('id',$request['business'],'business');
			    		
		$request['tax_query'] = array(
			array(
  				'field' => 'slug',
				'taxonomy' => 'business',
				'terms' => array($term->slug),
				)
		);
		$request['business'] = $term->slug;
				
	}
			    
	return $request;
}


in the 1704th line,
$term = $q[$t->query_var]; , the term will be the business taxonomy term id however the field is slug. so I do this $request['business'] = $term->slug; , right now it is working great!

Many thanks to you.

comment:20 wordpressplugindeveloper3 years ago

$tax_query_defaults = array(
					'taxonomy' => $taxonomy,
					'field' => 'slug',
				);

 				if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
					$q[$t->query_var] = wp_basename( $q[$t->query_var] );
				}
				
				$term = $q[$t->query_var];

				if ( strpos($term, '+') !== false ) {
					$terms = preg_split( '/[+]+/', $term );
					foreach ( $terms as $term ) {
						$tax_query[] = array_merge( $tax_query_defaults, array(
							'terms' => array( $term )
						) );
					}
				} else {
					
					$tax_query[] = array_merge( $tax_query_defaults, array(
						'terms' => preg_split( '/[,]+/', $term )
					) );
					
				}

Note: See TracTickets for help on using tickets.