From a8485376d27b5b3348a68963f6fd38200b6e64cf Mon Sep 17 00:00:00 2001 From: Tonya Mork Date: Tue, 16 Nov 2021 14:55:04 +0000 Subject: [PATCH] Taxonomy: Allow `get_*_*_link()` and `edit_term_link()` functions to accept a term ID, `WP_Term`, or term object. `get_term()` accepts a term ID, instance of `WP_Term`, or an object (i.e. `stdClass` as a result of a db query). Functions that use `get_term()` also now allow for the same data types. Why? For consistency, removing extra processing code in consuming functions, and performance. Functions changed in this commit are: * `get_category_feed_link()` * `get_term_feed_link()` * `get_tag_feed_link()` * `get_edit_tag_link()` * `get_edit_term_link()` * `edit_term_link()` For each of consumer of these functions, changes to pass the object instead of the term ID. Includes unit/integration tests for test coverage of these changes. Follow-up to [6365], [9136], [9340], [14711], [15792], [15800], [18827], [32606], [36646], [37252]. Props davidbinda, johnbillion, peterwilsoncc, hellofromTonya, sergeybiryukov, mista-flo, hareesh-pillai, audrasjb, jeffpaul, chaion07. Fixes #50225. git-svn-id: https://develop.svn.wordpress.org/trunk@52180 602fd350-edb4-49c9-b593-d223f7449a82 --- .../includes/class-wp-terms-list-table.php | 4 +- src/wp-includes/category-template.php | 4 +- src/wp-includes/class-walker-category.php | 2 +- src/wp-includes/link-template.php | 89 +++++---- tests/phpunit/tests/link/editTermLink.php | 180 ++++++++++++++++++ tests/phpunit/tests/link/getEditTermLink.php | 180 ++++++++++++++++++ tests/phpunit/tests/term/getTermLink.php | 123 +++++++++++- 7 files changed, 535 insertions(+), 47 deletions(-) create mode 100644 tests/phpunit/tests/link/editTermLink.php create mode 100644 tests/phpunit/tests/link/getEditTermLink.php diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php index 4823d29c9d..8d0217d40f 100644 --- a/src/wp-admin/includes/class-wp-terms-list-table.php +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -397,7 +397,7 @@ class WP_Terms_List_Table extends WP_List_Table { $uri = wp_doing_ajax() ? wp_get_referer() : $_SERVER['REQUEST_URI']; - $edit_link = get_edit_term_link( $tag->term_id, $taxonomy, $this->screen->post_type ); + $edit_link = get_edit_term_link( $tag, $taxonomy, $this->screen->post_type ); if ( $edit_link ) { $edit_link = add_query_arg( @@ -466,7 +466,7 @@ class WP_Terms_List_Table extends WP_List_Table { $edit_link = add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $uri ) ), - get_edit_term_link( $tag->term_id, $taxonomy, $this->screen->post_type ) + get_edit_term_link( $tag, $taxonomy, $this->screen->post_type ) ); $actions = array(); diff --git a/src/wp-includes/category-template.php b/src/wp-includes/category-template.php index 38c52a79a9..004a4562e2 100644 --- a/src/wp-includes/category-template.php +++ b/src/wp-includes/category-template.php @@ -737,9 +737,9 @@ function wp_tag_cloud( $args = '' ) { foreach ( $tags as $key => $tag ) { if ( 'edit' === $args['link'] ) { - $link = get_edit_term_link( $tag->term_id, $tag->taxonomy, $args['post_type'] ); + $link = get_edit_term_link( $tag, $tag->taxonomy, $args['post_type'] ); } else { - $link = get_term_link( (int) $tag->term_id, $tag->taxonomy ); + $link = get_term_link( $tag, $tag->taxonomy ); } if ( is_wp_error( $link ) ) { diff --git a/src/wp-includes/class-walker-category.php b/src/wp-includes/class-walker-category.php index fcf54a333f..24469e7667 100644 --- a/src/wp-includes/class-walker-category.php +++ b/src/wp-includes/class-walker-category.php @@ -164,7 +164,7 @@ class Walker_Category extends Walker { $link .= '('; } - $link .= 'taxonomy, $args['feed_type'] ) ) . '"'; if ( empty( $args['feed'] ) ) { /* translators: %s: Category name. */ diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index b8a2c30768..1b8a275e1a 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -904,13 +904,13 @@ function get_author_feed_link( $author_id, $feed = '' ) { * * @since 2.5.0 * - * @param int $cat_id Category ID. - * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. - * Default is the value of get_default_feed(). + * @param int|WP_Term|object $cat The ID or term object whose feed link will be retrieved. + * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. + * Default is the value of get_default_feed(). * @return string Link to the feed for the category specified by $cat_id. */ -function get_category_feed_link( $cat_id, $feed = '' ) { - return get_term_feed_link( $cat_id, 'category', $feed ); +function get_category_feed_link( $cat, $feed = '' ) { + return get_term_feed_link( $cat, 'category', $feed ); } /** @@ -921,16 +921,22 @@ function get_category_feed_link( $cat_id, $feed = '' ) { * * @since 3.0.0 * - * @param int $term_id Term ID. - * @param string $taxonomy Optional. Taxonomy of `$term_id`. Default 'category'. - * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. - * Default is the value of get_default_feed(). + * @param int|WP_Term|object $term The ID or term object whose feed link will be retrieved. + * @param string $taxonomy Optional. Taxonomy of `$term_id`. + * Defaults to 'category' if term ID or non WP_Term object is passed. + * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. + * Default is the value of get_default_feed(). * @return string|false Link to the feed for the term specified by $term_id and $taxonomy. */ -function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { - $term_id = (int) $term_id; +function get_term_feed_link( $term, $taxonomy = '', $feed = '' ) { + if ( ! is_object( $term ) ) { + $term = (int) $term; + $taxonomy = 'category'; + } elseif ( ! $term instanceof WP_Term ) { + $taxonomy = $term->taxonomy; + } - $term = get_term( $term_id, $taxonomy ); + $term = get_term( $term, $taxonomy ); if ( empty( $term ) || is_wp_error( $term ) ) { return false; @@ -944,7 +950,7 @@ function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { if ( ! $permalink_structure ) { if ( 'category' === $taxonomy ) { - $link = home_url( "?feed=$feed&cat=$term_id" ); + $link = home_url( "?feed=$feed&cat=$term->term_id" ); } elseif ( 'post_tag' === $taxonomy ) { $link = home_url( "?feed=$feed&tag=$term->slug" ); } else { @@ -952,7 +958,7 @@ function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { $link = home_url( "?feed=$feed&$t->query_var=$term->slug" ); } } else { - $link = get_term_link( $term_id, $term->taxonomy ); + $link = get_term_link( $term, $term->taxonomy ); if ( get_default_feed() == $feed ) { $feed_link = 'feed'; } else { @@ -1003,13 +1009,13 @@ function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { * * @since 2.3.0 * - * @param int $tag_id Tag ID. - * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. - * Default is the value of get_default_feed(). - * @return string The feed permalink for the given tag. + * @param int|WP_Term|object $tag The ID or term object whose feed link will be retrieved. + * @param string $feed Optional. Feed type. Possible values include 'rss2', 'atom'. + * Default is the value of get_default_feed(). + * @return string The feed permalink for the given tag. */ -function get_tag_feed_link( $tag_id, $feed = '' ) { - return get_term_feed_link( $tag_id, 'post_tag', $feed ); +function get_tag_feed_link( $tag, $feed = '' ) { + return get_term_feed_link( $tag, 'post_tag', $feed ); } /** @@ -1017,11 +1023,11 @@ function get_tag_feed_link( $tag_id, $feed = '' ) { * * @since 2.7.0 * - * @param int $tag_id Tag ID. - * @param string $taxonomy Optional. Taxonomy slug. Default 'post_tag'. + * @param int|WP_Term|object $tag The ID or term object whose edit link will be retrieved. + * @param string $taxonomy Optional. Taxonomy slug. Default 'post_tag'. * @return string The edit tag link URL for the given tag. */ -function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) { +function get_edit_tag_link( $tag, $taxonomy = 'post_tag' ) { /** * Filters the edit link for a tag (or term in another taxonomy). * @@ -1029,7 +1035,7 @@ function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) { * * @param string $link The term edit link. */ - return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag_id, $taxonomy ) ); + return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag, $taxonomy ) ); } /** @@ -1062,28 +1068,29 @@ function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) { * @since 3.1.0 * @since 4.5.0 The `$taxonomy` parameter was made optional. * - * @param int $term_id Term ID. - * @param string $taxonomy Optional. Taxonomy. Defaults to the taxonomy of the term identified - * by `$term_id`. - * @param string $object_type Optional. The object type. Used to highlight the proper post type - * menu on the linked page. Defaults to the first object_type associated - * with the taxonomy. + * @param int|WP_Term|object $term The ID or term object whose edit link will be retrieved. + * @param string $taxonomy Optional. Taxonomy. Defaults to the taxonomy of the term identified + * by `$term`. + * @param string $object_type Optional. The object type. Used to highlight the proper post type + * menu on the linked page. Defaults to the first object_type associated + * with the taxonomy. * @return string|null The edit term link URL for the given term, or null on failure. */ -function get_edit_term_link( $term_id, $taxonomy = '', $object_type = '' ) { - $term = get_term( $term_id, $taxonomy ); +function get_edit_term_link( $term, $taxonomy = '', $object_type = '' ) { + $term = get_term( $term, $taxonomy ); if ( ! $term || is_wp_error( $term ) ) { return; } - $tax = get_taxonomy( $term->taxonomy ); - if ( ! $tax || ! current_user_can( 'edit_term', $term->term_id ) ) { + $tax = get_taxonomy( $term->taxonomy ); + $term_id = $term->term_id; + if ( ! $tax || ! current_user_can( 'edit_term', $term_id ) ) { return; } $args = array( 'taxonomy' => $taxonomy, - 'tag_ID' => $term->term_id, + 'tag_ID' => $term_id, ); if ( $object_type ) { @@ -1116,16 +1123,18 @@ function get_edit_term_link( $term_id, $taxonomy = '', $object_type = '' ) { * * @since 3.1.0 * - * @param string $link Optional. Anchor text. If empty, default is 'Edit This'. Default empty. - * @param string $before Optional. Display before edit link. Default empty. - * @param string $after Optional. Display after edit link. Default empty. - * @param WP_Term $term Optional. Term object. If null, the queried object will be inspected. Default null. - * @param bool $echo Optional. Whether or not to echo the return. Default true. + * @param string $link Optional. Anchor text. If empty, default is 'Edit This'. Default empty. + * @param string $before Optional. Display before edit link. Default empty. + * @param string $after Optional. Display after edit link. Default empty. + * @param int|WP_Term|null $term Optional. Term ID or object. If null, the queried object will be inspected. Default null. + * @param bool $echo Optional. Whether or not to echo the return. Default true. * @return string|void HTML content. */ function edit_term_link( $link = '', $before = '', $after = '', $term = null, $echo = true ) { if ( is_null( $term ) ) { $term = get_queried_object(); + } else { + $term = get_term( $term ); } if ( ! $term ) { diff --git a/tests/phpunit/tests/link/editTermLink.php b/tests/phpunit/tests/link/editTermLink.php new file mode 100644 index 0000000000..a0d8f3f4d1 --- /dev/null +++ b/tests/phpunit/tests/link/editTermLink.php @@ -0,0 +1,180 @@ +term->create_and_get( array( 'taxonomy' => $taxonomy ) ); + } + + self::$user_ids['admin'] = $factory->user->create( array( 'role' => 'administrator' ) ); + self::$user_ids['subscriber'] = $factory->user->create( array( 'role' => 'subscriber' ) ); + } + + public function set_up() { + parent::set_up(); + self::register_custom_taxonomy(); + } + + /** + * @dataProvider data_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + * @param string $expected Expected URL within admin of edit link. + */ + public function test_edit_term_link_for_permitted_user( $taxonomy, $use_id, $expected ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + // Term IDs are not known by the data provider so need to be replaced. + $expected = str_replace( '%ID%', $use_id ? $term : $term->term_id, $expected ); + $expected = '"' . admin_url( $expected ) . '"'; + + $this->assertStringContainsString( $expected, edit_term_link( '', '', '', $term, false ) ); + $this->assertStringContainsString( $expected, edit_term_link( '', '', '', get_term( $term, $taxonomy ), false ) ); + } + + /** + * @dataProvider data_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_edit_term_link_for_denied_user( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['subscriber'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + $this->assertNull( edit_term_link( '', '', '', $term, false ) ); + $this->assertNull( edit_term_link( '', '', '', get_term( $term, $taxonomy ), false ) ); + } + + /** + * @dataProvider data_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_edit_term_link_filter_is_int_by_term_id( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'edit_term_link', + function( $location, $term ) { + $this->assertIsInt( $term ); + }, + 10, + 2 + ); + + edit_term_link( '', '', '', $term, false ); + } + + /** + * @dataProvider data_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_edit_term_link_filter_is_int_by_term_object( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'edit_term_link', + function( $location, $term ) { + $this->assertIsInt( $term ); + }, + 10, + 2 + ); + + edit_term_link( '', '', '', get_term( $term, $taxonomy ), false ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_edit_term_link() { + return array( + 'category passing term_id' => array( + 'taxonomy' => 'category', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=category&tag_ID=%ID%&post_type=post', + ), + 'category passing term object' => array( + 'taxonomy' => 'category', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=category&tag_ID=%ID%&post_type=post', + ), + 'post_tag passing term_id' => array( + 'taxonomy' => 'post_tag', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=post_tag&tag_ID=%ID%&post_type=post', + ), + 'post_tag passing term object' => array( + 'taxonomy' => 'post_tag', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=post_tag&tag_ID=%ID%&post_type=post', + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'custom_taxonomy', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=custom_taxonomy&tag_ID=%ID%&post_type=post', + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'custom_taxonomy', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=custom_taxonomy&tag_ID=%ID%&post_type=post', + ), + ); + } + + /** + * Helper to register a custom taxonomy for use in tests. + * + * @since 5.9.0 + */ + private static function register_custom_taxonomy() { + register_taxonomy( 'custom_taxonomy', 'post' ); + } + + /** + * Helper to get the term for the given taxonomy. + * + * @since 5.9.0 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + * @return WP_Term|int If $use_id is true, term ID is returned; else instance of WP_Term. + */ + private function get_term( $taxonomy, $use_id ) { + $term = self::$terms[ $taxonomy ]; + if ( $use_id ) { + $term = $term->term_id; + } + + return $term; + } +} diff --git a/tests/phpunit/tests/link/getEditTermLink.php b/tests/phpunit/tests/link/getEditTermLink.php new file mode 100644 index 0000000000..d7448d6d79 --- /dev/null +++ b/tests/phpunit/tests/link/getEditTermLink.php @@ -0,0 +1,180 @@ +term->create_and_get( array( 'taxonomy' => $taxonomy ) ); + } + + self::$user_ids['admin'] = $factory->user->create( array( 'role' => 'administrator' ) ); + self::$user_ids['subscriber'] = $factory->user->create( array( 'role' => 'subscriber' ) ); + } + + public function set_up() { + parent::set_up(); + self::register_custom_taxonomy(); + } + + /** + * @dataProvider data_get_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + * @param string $expected Expected URL within admin of edit link. + */ + public function test_get_edit_term_link_for_permitted_user( $taxonomy, $use_id, $expected ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + // Term IDs are not known by the data provider so need to be replaced. + $expected = str_replace( '%ID%', $use_id ? $term : $term->term_id, $expected ); + $expected = admin_url( $expected ); + + $this->assertSame( $expected, get_edit_term_link( $term, $taxonomy ) ); + $this->assertSame( $expected, get_edit_term_link( get_term( $term, $taxonomy ), $taxonomy ) ); + } + + /** + * @dataProvider data_get_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_get_edit_term_link_for_denied_user( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['subscriber'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + $this->assertNull( get_edit_term_link( $term, $taxonomy ) ); + $this->assertNull( get_edit_term_link( get_term( $term, $taxonomy ), $taxonomy ) ); + } + + /** + * @dataProvider data_get_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_get_edit_term_link_filter_is_int_by_term_id( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'get_edit_term_link', + function( $location, $term ) { + $this->assertIsInt( $term ); + }, + 10, + 2 + ); + + get_edit_term_link( $term, $taxonomy ); + } + + /** + * @dataProvider data_get_edit_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_get_edit_term_link_filter_is_int_by_term_object( $taxonomy, $use_id ) { + wp_set_current_user( self::$user_ids['admin'] ); + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'get_edit_term_link', + function( $location, $term ) { + $this->assertIsInt( $term ); + }, + 10, + 2 + ); + + get_edit_term_link( get_term( $term, $taxonomy ), $taxonomy ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_get_edit_term_link() { + return array( + 'category passing term_id' => array( + 'taxonomy' => 'category', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=category&tag_ID=%ID%&post_type=post', + ), + 'category passing term object' => array( + 'taxonomy' => 'category', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=category&tag_ID=%ID%&post_type=post', + ), + 'post_tag passing term_id' => array( + 'taxonomy' => 'post_tag', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=post_tag&tag_ID=%ID%&post_type=post', + ), + 'post_tag passing term object' => array( + 'taxonomy' => 'post_tag', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=post_tag&tag_ID=%ID%&post_type=post', + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'custom_taxonomy', + 'use_id' => false, + 'expected' => 'term.php?taxonomy=custom_taxonomy&tag_ID=%ID%&post_type=post', + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'custom_taxonomy', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=custom_taxonomy&tag_ID=%ID%&post_type=post', + ), + ); + } + + /** + * Helper to register a custom taxonomy for use in tests. + * + * @since 5.9.0 + */ + private static function register_custom_taxonomy() { + register_taxonomy( 'custom_taxonomy', 'post' ); + } + + /** + * Helper to get the term for the given taxonomy. + * + * @since 5.9.0 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + * @return WP_Term|int If $use_id is true, term ID is returned; else instance of WP_Term. + */ + private function get_term( $taxonomy, $use_id ) { + $term = self::$terms[ $taxonomy ]; + if ( $use_id ) { + $term = $term->term_id; + } + + return $term; + } +} diff --git a/tests/phpunit/tests/term/getTermLink.php b/tests/phpunit/tests/term/getTermLink.php index c5b9fbbe32..af41f9e92a 100644 --- a/tests/phpunit/tests/term/getTermLink.php +++ b/tests/phpunit/tests/term/getTermLink.php @@ -2,13 +2,24 @@ /** * @group taxonomy + * @covers ::get_term_link */ class Tests_Term_GetTermLink extends WP_UnitTestCase { + public static $terms; + + public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { + self::register_custom_taxonomy(); + + $taxonomies = array( 'category', 'post_tag', 'wptests_tax' ); + foreach ( $taxonomies as $taxonomy ) { + self::$terms[ $taxonomy ] = $factory->term->create_and_get( array( 'taxonomy' => $taxonomy ) ); + } + } + public function set_up() { parent::set_up(); - - register_taxonomy( 'wptests_tax', 'post' ); + self::register_custom_taxonomy(); } public function test_integer_should_be_interpreted_as_term_id() { @@ -207,4 +218,112 @@ class Tests_Term_GetTermLink extends WP_UnitTestCase { $this->assertStringContainsString( '/foo/term2/', $actual ); } + + /** + * @dataProvider data_get_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_get_term_link_filter_is_object_by_term_id( $taxonomy, $use_id ) { + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'term_link', + function( $location, $term ) { + $this->assertInstanceOf( 'WP_Term', $term ); + }, + 10, + 2 + ); + + get_term_link( $term, $taxonomy ); + } + + /** + * @dataProvider data_get_term_link + * + * @ticket 50225 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + */ + public function test_get_term_link_filter_is_object_by_term_object( $taxonomy, $use_id ) { + $term = $this->get_term( $taxonomy, $use_id ); + + add_filter( + 'term_link', + function( $location, $term ) { + $this->assertInstanceOf( 'WP_Term', $term ); + }, + 10, + 2 + ); + + get_term_link( get_term( $term, $taxonomy ), $taxonomy ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_get_term_link() { + return array( + 'category passing term_id' => array( + 'taxonomy' => 'category', + 'use_id' => false, + ), + 'category passing term object' => array( + 'taxonomy' => 'category', + 'use_id' => true, + ), + 'post_tag passing term_id' => array( + 'taxonomy' => 'post_tag', + 'use_id' => false, + ), + 'post_tag passing term object' => array( + 'taxonomy' => 'post_tag', + 'use_id' => true, + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'wptests_tax', + 'use_id' => false, + ), + 'a custom taxonomy passing term_id' => array( + 'taxonomy' => 'wptests_tax', + 'use_id' => true, + 'expected' => 'term.php?taxonomy=custom_taxonomy&tag_ID=%ID%&post_type=post', + ), + ); + } + + /** + * Helper to register a custom taxonomy for use in tests. + * + * @since 5.9.0 + */ + private static function register_custom_taxonomy() { + register_taxonomy( 'wptests_tax', 'post' ); + } + + /** + * Helper to get the term for the given taxonomy. + * + * @since 5.9.0 + * + * @param string $taxonomy Taxonomy been tested (used for index of term keys). + * @param bool $use_id When true, pass term ID. Else, pass term object. + * @return WP_Term|int If $use_id is true, term ID is returned; else instance of WP_Term. + */ + private function get_term( $taxonomy, $use_id ) { + $term = self::$terms[ $taxonomy ]; + if ( $use_id ) { + $term = $term->term_id; + } + + return $term; + } }