#18747 closed defect (bug) (invalid)
Custom Taxonomy Search/Filter Bug
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Query | Version: | |
| Severity: | normal | Keywords: | |
| 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.
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)
- Component changed from General to Query
- Description modified (diff)
- Milestone Awaiting Review deleted
- Resolution set to invalid
- Status changed from new to closed
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).
'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.
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.
It's unfortunate that it takes so much work to do this.
I suggest you add a comment to the gist page.
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.
anyway, thanks for your help. Maybe I have to hardcode my own sql code.
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.
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.
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
scribu — 20 months 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.
edit.php?s&post_status=all&post_type=listing&action=-1&m=0&business=101&paged=1&mode=list&action2=-1
comment:14
scribu — 20 months 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' ) );
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
scribu — 20 months ago
With the URL you gave me, there's no way that could happen, unless there's some other code interfering.
comment:17
scribu — 20 months ago
That is, if you're using my code and using 'business_id' as a query var, not 'business'.
comment:18
scribu — 20 months ago
Follow-up: #18748
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.
$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 )
) );
}

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.