Opened 12 years ago
Closed 10 years ago
#27918 closed defect (bug) (wontfix)
get_taxonomies() on single post type should return taxonomies registered on multiple post types
| Reported by: |
|
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
@
12 years ago
- Keywords needs-patch needs-unit-tests added
- Milestone changed from Awaiting Review to 4.0
#3
@
12 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
@
11 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.
11 years ago
#8
@
11 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
@
10 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).
@
10 years ago
Checking if both the key and the value are arrays, and attempt to perform an intersection between them.
#11
@
10 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
@
10 years ago
Replying to boonebgorges:
Kinda like [27918.3.diff].
That might work. Came up with an almost identical solution.
#14
@
10 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