#34175 closed defect (bug) (wontfix)
Add correlating get_fields_terms filter for get_terms
Reported by: | wpsmith | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 4.4 |
Component: | Taxonomy | Keywords: | |
Focuses: | Cc: |
Description
Currently, there is a filter (get_terms_fields
) to filter the fields to select in the terms query. I believe that the use of this filter could be easily expanded to involve additional return types. So I would like to introduce a filter (get_terms_fields_terms
) for the return $_terms
that would only be called if $_fields
is not one of the already pre-defined options (i.e., all
, id=>parent
, ids
, names
, id=>name
, id=>slug
).
While someone could possibly use get_terms
to do this manipulation, the specified/default query will still execute and be cached, and there is no way to really do what one wants to do without having to re-do the entire function, which in my opinion is not preferable. Also modifying the get_terms_fields
will modify the cached results of all queries with the same taxonomies and arguments.
It is noted in the filter (get_terms_fields
) documentation that "Use of this filter can result in unpredictable behavior, and is not recommended." Based on my limited testing, I found that changing the return fields (e.g., array( 't.slug', 't.name', 'tt.count', 'tt.taxonomy' )
) via get_terms_fields
causes the following issues:
- If you do not change the default fields argument or use
all
, PHP throws an error with updating the cache (update_term_cache
called because'all' == $_fields
and there is no check for the term ID there or withinupdate_term_cache
sinceupdate_term_cache
rightly assumes that $terms is an array of term objects).- Notice: Undefined property:
stdClass::$term_id
...
- Notice: Undefined property:
- If you use one of the following pre-defined examples,
id=>parent
,ids
,id=>name
,id=>slug
), each of these will throw an error ifget_terms_fields
removes the term_id ('t.term_id'
).- Notice: Undefined property:
stdClass::$term_id
...
- Notice: Undefined property:
- If using
all
and wantingpad_counts
, another error is thrown by_pad_term_counts
which assumes the first parameter is an array of term objects (not IDs, see #34174). - If you are trying to get a term list of a specific parent (e.g., $child_of), more errors persist as
_get_term_children
(which callsget_term
) also assumes that$terms
is an array of term objects (likeupdate_term_cache
) or an integer (term_id
). This is perpetuated even further by utilization of expected object members (e.g.,$term->parent
); - If you are trying to hide empty terms (
hide_empty
) this causes another error as it also assumes that $terms is an array of term objects. - If you are passing in
update_term_meta_cache
then$term_ids = wp_list_pluck( $terms, 'term_id' );
causes another error as doesupdate_termmeta_cache
. - Potential errors within themes & plugins
A possible solution is to patch wp_pluck_list (#34172) & add checks using wp_pluck_list
(see patch).
Attachments (4)
Change History (7)
@
9 years ago
It should be noted that if considered, then get_terms_fields_terms will need documentation.
#1
@
9 years ago
Here is an example use of the additional filter: https://gist.github.com/wpsmith/f153b7ab746417d73b7d
#2
@
9 years ago
- Milestone Awaiting Review deleted
- Resolution set to wontfix
- Status changed from new to closed
get_terms_fields
was introduced in [11037]. See #9004.
get_terms_fields
is an unpleasant filter. It has been juggled around in various places in get_terms()
through the years in such a way that it's surprise it works for anyone anymore. I'd like to remove it altogether. But there are probably some people who have managed to make it work (after a fashion) and they should continue to be able to do so. Anyway, I do not want to make a bunch of changes to get_terms()
just so that people can more easily use this old filter, especially when improper use of the filter breaks the cache strategy of get_terms()
.
Your proposed get_terms_fields_terms
filter doesn't do anything that you couldn't already do by processing the results of get_terms()
using wp_list_pluck()
or a foreach
loop. If you need to do it via filter, use 'get_terms'
.
Also, the way the filter is currently placed means that it breaks caching in get_terms()
. Let's say you have the following:
function wp34175_customize_get_terms_output( $terms ) { if ( is_page() ) { return wp_list_pluck( $terms, 'name' ); } else { return $terms; } } add_filter( 'get_terms_fields_terms', 'wp34175_customize_get_terms_output' );
If you call it first on a page, the value added to the cache will be an array of names. If you later call it outside of a page context using the same params, you'll be given the same array of names, even though you wanted term objects.
For more background on the relationship between 'get_terms_fields'
, the fields
param, and the get_terms()
cache, see #31174. In the meantime, for your purposes, use the get_terms
filter.
Checks