diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 70a7d73e07..efb7330b52 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -1638,6 +1638,28 @@ function post_type_supports( $post_type, $feature ) { return ( isset( $_wp_post_type_features[$post_type][$feature] ) ); } +/** + * Get a list of post type names that support a specific feature. + * + * @since 4.5.0 + * + * @global array $_wp_post_type_features + * + * @param array|string $args Single feature or an array of features the post types should support. + * @param string $operator Optional. The logical operation to perform. 'or' means + * only one element from the array needs to match; 'and' + * means all elements must match; 'not' means no elements may + * match. Default 'and'. + * @return array A list of post type names. + */ +function get_post_types_by_support( $args, $operator = 'and' ) { + global $_wp_post_type_features; + + $features = array_fill_keys( (array) $args, true ); + + return array_keys( wp_filter_object_list( $_wp_post_type_features, $features, $operator ) ); +} + /** * Update the post type for the post ID. * diff --git a/tests/phpunit/tests/post/types.php b/tests/phpunit/tests/post/types.php index 9d19a84213..9cf44c84fb 100644 --- a/tests/phpunit/tests/post/types.php +++ b/tests/phpunit/tests/post/types.php @@ -379,4 +379,53 @@ class Tests_Post_Types extends WP_UnitTestCase { $this->assertFalse( post_type_exists( 'foo' ) ); } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_single_feature() { + $this->assertContains( 'post', get_post_types_by_support( 'title' ) ); + $this->assertContains( 'page', get_post_types_by_support( 'title' ) ); + $this->assertContains( 'attachment', get_post_types_by_support( 'title' ) ); + $this->assertContains( 'nav_menu_item', get_post_types_by_support( 'title' ) ); + } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_multiple_features() { + $this->assertContains( 'post', get_post_types_by_support( array( 'thumbnail', 'author' ) ) ); + $this->assertContains( 'page', get_post_types_by_support( array( 'thumbnail', 'author' ) ) ); + } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_or_operator() { + $this->assertContains( 'post', get_post_types_by_support( array( 'post-formats', 'page-attributes' ), 'or' ) ); + $this->assertContains( 'page', get_post_types_by_support( array( 'post-formats', 'page-attributes' ), 'or' ) ); + } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_not_operator() { + $this->assertContains( 'attachment', get_post_types_by_support( array( 'thumbnail' ), 'not' ) ); + $this->assertContains( 'revision', get_post_types_by_support( array( 'thumbnail' ), 'not' ) ); + $this->assertContains( 'nav_menu_item', get_post_types_by_support( array( 'thumbnail' ), 'not' ) ); + } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_excluding_features() { + $this->assertEqualSets( array(), get_post_types_by_support( array( 'post-formats', 'page-attributes' ) ) ); + } + + /** + * @ticket 34010 + */ + public function test_get_post_types_by_support_non_existant_feature() { + $this->assertEqualSets( array(), get_post_types_by_support( 'somefeature' ) ); + } }