#34175 closed defect (bug) (wontfix)
Add correlating get_fields_terms filter for get_terms
| Reported by: |
|
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_cachecalled because'all' == $_fieldsand there is no check for the term ID there or withinupdate_term_cachesinceupdate_term_cacherightly 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_fieldsremoves the term_id ('t.term_id').- Notice: Undefined property:
stdClass::$term_id...
- Notice: Undefined property:
- If using
alland wantingpad_counts, another error is thrown by_pad_term_countswhich 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$termsis 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_cachethen$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)
@
10 years ago
It should be noted that if considered, then get_terms_fields_terms will need documentation.
#1
@
10 years ago
Here is an example use of the additional filter: https://gist.github.com/wpsmith/f153b7ab746417d73b7d
#2
@
10 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