From 000f4f98b4eeb100159f9bf38ca47f5e0f76f995 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Fri, 24 Apr 2015 14:56:37 +0000 Subject: [PATCH] In `wp_list_categories()`, 'All' link should point to post type archive if taxonomy is not registered for 'post' or 'page'. Instead, we point to the post type archive of the first registered object_type that supports archives. Props stevegrunwell, hrishiv90, boonebgorges. Fixes #21881. git-svn-id: https://develop.svn.wordpress.org/trunk@32292 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/category-template.php | 23 ++++- .../tests/category/wpListCategories.php | 90 +++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/category-template.php b/src/wp-includes/category-template.php index 9a2120c9e3..5fb7485332 100644 --- a/src/wp-includes/category-template.php +++ b/src/wp-includes/category-template.php @@ -532,7 +532,28 @@ function wp_list_categories( $args = '' ) { } } else { if ( ! empty( $show_option_all ) ) { - $posts_page = ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' ); + + $posts_page = ''; + + // For taxonomies that belong only to custom post types, point to a valid archive. + $taxonomy_object = get_taxonomy( $r['taxonomy'] ); + if ( ! in_array( 'post', $taxonomy_object->object_type ) && ! in_array( 'page', $taxonomy_object->object_type ) ) { + foreach ( $taxonomy_object->object_type as $object_type ) { + $_object_type = get_post_type_object( $object_type ); + + // Grab the first one. + if ( ! empty( $_object_type->has_archive ) ) { + $posts_page = get_post_type_archive_link( $object_type ); + break; + } + } + } + + // Fallback for the 'All' link is the front page. + if ( ! $posts_page ) { + $posts_page = 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' ); + } + $posts_page = esc_url( $posts_page ); if ( 'list' == $r['style'] ) { $output .= "
  • $show_option_all
  • "; diff --git a/tests/phpunit/tests/category/wpListCategories.php b/tests/phpunit/tests/category/wpListCategories.php index 55af2f484e..e2c041c90e 100644 --- a/tests/phpunit/tests/category/wpListCategories.php +++ b/tests/phpunit/tests/category/wpListCategories.php @@ -100,6 +100,96 @@ class Tests_Category_WpListCategories extends WP_UnitTestCase { $this->assertContains( "
  • All
  • ", $found ); } + /** + * @ticket 21881 + */ + public function test_show_option_all_link_should_link_to_post_type_archive_when_taxonomy_does_not_apply_to_posts() { + register_post_type( 'wptests_pt', array( 'has_archive' => true ) ); + register_post_type( 'wptests_pt2', array( 'has_archive' => true ) ); + register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) ); + + $terms = $this->factory->term->create_many( 2, array( + 'taxonomy' => 'wptests_tax', + ) ); + + $found = wp_list_categories( array( + 'echo' => false, + 'show_option_all' => 'All', + 'hide_empty' => false, + 'taxonomy' => 'wptests_tax', + ) ); + + $pt_archive = get_post_type_archive_link( 'wptests_pt' ); + + $this->assertContains( "
  • All
  • ", $found ); + } + + /** + * @ticket 21881 + */ + public function test_show_option_all_link_should_not_link_to_post_type_archive_if_has_archive_is_false() { + register_post_type( 'wptests_pt', array( 'has_archive' => false ) ); + register_post_type( 'wptests_pt2', array( 'has_archive' => true ) ); + register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) ); + + $terms = $this->factory->term->create_many( 2, array( + 'taxonomy' => 'wptests_tax', + ) ); + + $found = wp_list_categories( array( + 'echo' => false, + 'show_option_all' => 'All', + 'hide_empty' => false, + 'taxonomy' => 'wptests_tax', + ) ); + + $pt_archive = get_post_type_archive_link( 'wptests_pt2' ); + + $this->assertContains( "
  • All
  • ", $found ); + } + + public function test_show_option_all_link_should_link_to_post_archive_if_available() { + register_post_type( 'wptests_pt', array( 'has_archive' => true ) ); + register_post_type( 'wptests_pt2', array( 'has_archive' => true ) ); + register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'post', 'wptests_pt2' ) ); + + $terms = $this->factory->term->create_many( 2, array( + 'taxonomy' => 'wptests_tax', + ) ); + + $found = wp_list_categories( array( + 'echo' => false, + 'show_option_all' => 'All', + 'hide_empty' => false, + 'taxonomy' => 'wptests_tax', + ) ); + + $url = home_url( '/' ); + + $this->assertContains( "
  • All
  • ", $found ); + } + + public function test_show_option_all_link_should_link_to_post_archive_if_no_associated_post_types_have_archives() { + register_post_type( 'wptests_pt', array( 'has_archive' => false ) ); + register_post_type( 'wptests_pt2', array( 'has_archive' => false ) ); + register_taxonomy( 'wptests_tax', array( 'foo', 'wptests_pt', 'wptests_pt2' ) ); + + $terms = $this->factory->term->create_many( 2, array( + 'taxonomy' => 'wptests_tax', + ) ); + + $found = wp_list_categories( array( + 'echo' => false, + 'show_option_all' => 'All', + 'hide_empty' => false, + 'taxonomy' => 'wptests_tax', + ) ); + + $url = home_url( '/' ); + + $this->assertContains( "
  • All
  • ", $found ); + } + public function list_cats_callback( $cat ) { if ( 'Test Cat 1' === $cat ) { return '';