[wp-trac] [WordPress Trac] #31174: The get_terms() argument "fields" renders "get_terms_fields" & "terms_clauses" filter callbacks useless
WordPress Trac
noreply at wordpress.org
Thu Jan 29 10:58:26 UTC 2015
#31174: The get_terms() argument "fields" renders "get_terms_fields" &
"terms_clauses" filter callbacks useless
--------------------------+-----------------------------
Reporter: F J Kaiser | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Taxonomy | Version: 4.1
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
The `get_terms( $tax, [ args ] );` function accepts an argument named
`fields`. This allows to chose which columns should be fetched from either
the `wp_terms` or `wp_term_taxonomy` table. Example:
{{{
$terms = get_terms( 'example_tax', [ 'fields' => 'names', ] );
var_dump( $names );
/* Result:
array (size=1)
0 => string 'Code Review' (length=11)
*/
}}}
In this case, the resulting query inside the function would be the
following:
{{{
SELECT t.term_id, tt.parent, tt.count, t.name
FROM wp_terms AS t
INNER JOIN wp_term_taxonomy AS tt
ON t.term_id = tt.term_id
WHERE tt.taxonomy IN ('project_type')
ORDER BY t.name ASC
}}}
In fact, `fields` does not really any combination of fields, but allows to
chose from a list:
* `all` : `$selects = array( 't.*', 'tt.*' )`
* `ids` : `$selects = array( 't.term_id', 'tt.parent', 'tt.count' )`
* `id=>parent` : `$selects = array( 't.term_id', 'tt.parent', 'tt.count'
)` (the same as above)
* `names` : `$selects = array( 't.term_id', 'tt.parent', 'tt.count',
't.name' )`
* `count` : `$selects = array( 'COUNT(*)' )`
* `id=>name` : `$selects = array( 't.term_id', 't.name', 'tt.count' )`
* `id=>slug` : `$selects = array( 't.term_id', 't.slug', 'tt.count' )`
After this preselection ran, there are two filters available to alter the
list:
{{{
$fields = implode( ', ', apply_filters( 'get_terms_fields', $selects,
$args, $taxonomies ) );
$pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits'
);
}}}
But no matter if you attached an filter to either of those or not: The
result stays the same. This is due to the following filtering done in a
final loop through all results:
* `ids` : `$_terms[] = $term->term_id`
* `id=>parent` : `$_terms[$term->term_id] = $term->parent`
* `names` : `$_terms[] = $term->name`
* `id=>name` : `$_terms[$term->term_id] = $term->name`
* `id=>slug` : `$_terms[$term->term_id] = $term->slug`
And that renders callbacks to both attached filters useless. The only
cases where this does not happen are the argument values `all` and
`count`.
I'm not sure if this should be called an "undocumented feature" or if this
actually needs a patch. I'm in for later if there is support for changing
this awkward behavior as this is not clear until one jumps and dumps in
core.
Proposed fix: Only run the final filter-loop if ...
{{{
if ( ! (
has_filter( 'get_terms_fields' ) or has_filter( 'terms_clauses' )
) )
// do final filtering
}}}
--
Ticket URL: <https://core.trac.wordpress.org/ticket/31174>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list