Opened 10 years ago
Closed 9 years ago
#27918 closed defect (bug) (wontfix)
get_taxonomies() on single post type should return taxonomies registered on multiple post types
Reported by: | johnrork | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.0 |
Component: | Taxonomy | Keywords: | needs-unit-tests needs-refresh needs-patch |
Focuses: | Cc: |
Description
A taxonomy registered on multiple post types is missing from get_taxonomies() when called with only one of those post types.
It seems self-evident that get_taxonomies should return all of a post type's taxonomies, regardless of how they were registered.
//... on init... register_taxonomy('foo', array('bar','baz'), $opts); //... in template ... // returns taxonomies registered only on 'bar', 'foo' is missing get_taxonomies('object_type'=>array('bar')); // returns 'foo' only if exact array is passed get_taxonomies('object_type'=>array('bar','baz'));
Attachments (3)
Change History (17)
#2
@
10 years ago
- Keywords needs-patch needs-unit-tests added
- Milestone changed from Awaiting Review to 4.0
#3
@
10 years ago
I'm at a WordPress Contributor day in Sheffield. I've developed a fix for this problem. Patch coming soon but basically it's this.
In wp_list_filter() replace the second foreach loop to
foreach ( $args as $m_key => $m_value ) { if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) $matched++; }
to cater for $m_value being an array.
foreach ( $args as $m_key => $m_value ) { if ( array_key_exists( $m_key, $to_match ) ) { if ( $m_value == $to_match[ $m_key ] ) { $matched++; } elseif ( is_array( $m_value ) && is_array( $to_match[ $m_key ] ) ) { foreach ( $m_value as $mv_key => $mv_value ) { if ( in_array( $mv_value, $to_match[ $m_key ] ) ) { $matched = $count; } } }
We also check that $to_match[ $m_key ] is an array before checking for the presence of each given value ( $mv_value ). If ANY of the fields is found then the value of $matched is set to $count so that the following tests on the operator will pass.
Note: I haven't tested with different values of operator - just used default 'AND'.
I developed a shortcode to test the changes.
With no parameters passed it returns a list of all registered post types with each of their taxonomy names.
With a post_types=a,b,c parameter the list of taxonomies returned is the set of taxonomies associated with any of the post types.
e.g. for post,page it returns category post_tag post_format
for page,post,nav_menu_item,revision is returns category post_tag nav_menu post_format
#5
@
10 years ago
The call to get_taxonomies
should be:
get_taxonomies( array( 'object_type' => array( 'post' ), ) )
I have an alternative fix:
foreach ( $args as $m_key => $m_value ) { if ( array_key_exists( $m_key, $to_match ) && ( $m_value == $to_match[ $m_key ] ) || ( is_array( $m_value ) && array_key_exists( $m_key, $to_match ) ) ) $matched++; }
This ticket was mentioned in IRC in #wordpress-dev by DrewAPicture. View the logs.
10 years ago
#8
@
10 years ago
- Keywords needs-refresh has-patch added; needs-patch removed
- Milestone changed from 4.0 to Future Release
Sounds like we still need a refresh and unit tests here. Punting.
#10
@
9 years ago
Alternatively, you can check if both the key and the value are arrays, and perform an array_intersect
on them. In the get_taxonomies
use case, this would allow to find taxonomies that belong to more than one post type (they're excluded from the results now).
@
9 years ago
Checking if both the key and the value are arrays, and attempt to perform an intersection between them.
#11
@
9 years ago
- Keywords needs-patch added; has-patch removed
What are we going to break by making wp_list_filter()
match partially like this? I agree that the change makes sense for get_taxonomies()
, but I can think of plenty of cases where you may only want to match the full array.
A more local fix is probably appropriate here. In get_taxonomies()
, if we detect that 'object_type' is an array, we may want to run a separate wp_list_filter()
on it, using the 'OR' operator.
#13
in reply to:
↑ 12
@
9 years ago
Replying to boonebgorges:
Kinda like [27918.3.diff].
That might work. Came up with an almost identical solution.
#14
@
9 years ago
- Milestone Future Release deleted
- Resolution set to wontfix
- Status changed from new to closed
So, I've been thinking this over some more. In the same way that making a general change to wp_list_filter()
will break certain legitimate filters, my suggested fix will make it impossible to do certain legitimate filters on taxonomies. What if I want to find all the taxonomies that are exclusive to 'post'?
More generally, the suggested change breaks the general pattern of functions that use wp_list_filter()
internally, by treating one of the filters as a special case. I think that's a bad idea.
As noted in 4,get_object_taxonomies()
is really meant for this very purpose, so it should be used instead.
johnrork, thanks for the report, sounds like we need to investigate this and write some unit tests