diff --git a/.gitignore b/.gitignore
index 2f4d4eb9d2..2bb7d567fb 100644
|
a
|
b
|
wp-tests-config.php |
| 76 | 76 | |
| 77 | 77 | # Files for local environment config |
| 78 | 78 | /docker-compose.override.yml |
| | 79 | .vscode |
diff --git a/src/wp-includes/capabilities.php b/src/wp-includes/capabilities.php
index e3a18f6b28..5a4e34f7ef 100644
|
a
|
b
|
function map_meta_cap( $cap, $user_id, ...$args ) { |
| 524 | 524 | break; |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | | if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) { |
| | 527 | if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) || $term->term_id == get_option( 'default_taxonomy_' . $term->taxonomy ) ) ) { |
| 528 | 528 | $caps[] = 'do_not_allow'; |
| 529 | 529 | break; |
| 530 | 530 | } |
diff --git a/src/wp-includes/class-wp-taxonomy.php b/src/wp-includes/class-wp-taxonomy.php
index 716da8d384..7b47c4b5c8 100644
|
a
|
b
|
final class WP_Taxonomy { |
| 204 | 204 | */ |
| 205 | 205 | public $rest_controller_class; |
| 206 | 206 | |
| | 207 | /** |
| | 208 | * The default term name. If you pass an array you have to set |
| | 209 | * 'name' and optionally slug' and 'description'. |
| | 210 | * |
| | 211 | * @since 5.0.0 |
| | 212 | * @var array|string |
| | 213 | */ |
| | 214 | public $default_term; |
| | 215 | |
| 207 | 216 | /** |
| 208 | 217 | * Whether it is a built-in taxonomy. |
| 209 | 218 | * |
| … |
… |
final class WP_Taxonomy { |
| 273 | 282 | 'show_in_rest' => false, |
| 274 | 283 | 'rest_base' => false, |
| 275 | 284 | 'rest_controller_class' => false, |
| | 285 | 'default_term' => null, |
| 276 | 286 | '_builtin' => false, |
| 277 | 287 | ); |
| 278 | 288 | |
| … |
… |
final class WP_Taxonomy { |
| 371 | 381 | } |
| 372 | 382 | } |
| 373 | 383 | |
| | 384 | // Default taxonomy term. |
| | 385 | if ( ! empty( $args['default_term'] ) ) { |
| | 386 | if ( ! is_array( $args['default_term'] ) ) { |
| | 387 | $args['default_term'] = array( 'name' => $args['default_term'] ); |
| | 388 | } |
| | 389 | $args['default_term'] = wp_parse_args( $args['default_term'], array( 'name' => '', 'slug' => '', 'description' => '' ) ); |
| | 390 | } |
| | 391 | |
| 374 | 392 | foreach ( $args as $property_name => $property_value ) { |
| 375 | 393 | $this->$property_name = $property_value; |
| 376 | 394 | } |
diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
index 491fc666a4..73be6a8f9a 100644
|
a
|
b
|
function wp_insert_post( $postarr, $wp_error = false ) { |
| 3916 | 3916 | wp_set_post_tags( $post_ID, $postarr['tags_input'] ); |
| 3917 | 3917 | } |
| 3918 | 3918 | |
| | 3919 | // Add default term for all associated custom taxonomies. |
| | 3920 | if ( 'auto-draft' !== $post_status ) { |
| | 3921 | foreach ( get_object_taxonomies( $post_type, 'object' ) as $taxonomy => $tax_object ) { |
| | 3922 | if ( ! empty( $tax_object->default_term ) && ( empty( $postarr['tax_input'] ) || ! isset( $postarr['tax_input'][ $taxonomy ] ) ) ) { |
| | 3923 | $postarr['tax_input'][ $taxonomy ] = array(); |
| | 3924 | } |
| | 3925 | } |
| | 3926 | } |
| | 3927 | |
| 3919 | 3928 | // New-style support for all custom taxonomies. |
| 3920 | 3929 | if ( ! empty( $postarr['tax_input'] ) ) { |
| 3921 | 3930 | foreach ( $postarr['tax_input'] as $taxonomy => $tags ) { |
diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php
index d93da9f138..1d50184f69 100644
|
a
|
b
|
function is_taxonomy_hierarchical( $taxonomy ) { |
| 334 | 334 | * @since 4.7.0 Introduced `show_in_rest`, 'rest_base' and 'rest_controller_class' |
| 335 | 335 | * arguments to register the Taxonomy in REST API. |
| 336 | 336 | * @since 5.1.0 Introduced `meta_box_sanitize_cb` argument. |
| | 337 | * @since 5.3.0 Introduced `default_term` argument. |
| 337 | 338 | * |
| 338 | 339 | * @global array $wp_taxonomies Registered taxonomies. |
| 339 | 340 | * |
| … |
… |
function is_taxonomy_hierarchical( $taxonomy ) { |
| 405 | 406 | * to post types, which confirms that the objects are published before |
| 406 | 407 | * counting them. Default _update_generic_term_count() for taxonomies |
| 407 | 408 | * attached to other object types, such as users. |
| | 409 | * @type string|array $default_term { |
| | 410 | * Default term to be used for the taxonomy. |
| | 411 | * |
| | 412 | * @type string $name Name of default term. |
| | 413 | * @type string $slug Slug for default term (default empty). |
| | 414 | * @type string $description Description for default term (default empty). |
| | 415 | * } |
| 408 | 416 | * @type bool $_builtin This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY! |
| 409 | 417 | * Default false. |
| 410 | 418 | * } |
| … |
… |
function register_taxonomy( $taxonomy, $object_type, $args = array() ) { |
| 431 | 439 | |
| 432 | 440 | $taxonomy_object->add_hooks(); |
| 433 | 441 | |
| | 442 | // Add default term. |
| | 443 | if ( ! empty( $taxonomy_object->default_term ) ) { |
| | 444 | if ( $term = term_exists( $taxonomy_object->default_term['name'], $taxonomy ) ) { |
| | 445 | update_option('default_taxonomy_' . $taxonomy_object->name, $term['term_id'] ); |
| | 446 | } else { |
| | 447 | $term = wp_insert_term( $taxonomy_object->default_term['name'], $taxonomy, array( |
| | 448 | 'slug' => sanitize_title( $taxonomy_object->default_term['slug'] ), |
| | 449 | 'description' => $taxonomy_object->default_term['description'], |
| | 450 | )); |
| | 451 | |
| | 452 | // Update term id in options. |
| | 453 | if ( ! is_wp_error( $term ) ) { |
| | 454 | update_option('default_taxonomy_' . $taxonomy_object->name, $term['term_id']); |
| | 455 | } |
| | 456 | } |
| | 457 | } |
| | 458 | |
| 434 | 459 | /** |
| 435 | 460 | * Fires after a taxonomy is registered. |
| 436 | 461 | * |
| … |
… |
function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) { |
| 2438 | 2463 | $terms = array( $terms ); |
| 2439 | 2464 | } |
| 2440 | 2465 | |
| | 2466 | // Add default term |
| | 2467 | $taxonomy_obj = get_taxonomy( $taxonomy ); |
| | 2468 | |
| | 2469 | // Default term for this taxonomy. |
| | 2470 | if ( empty( $terms ) && ! empty ( $taxonomy_obj->default_term ) && ! empty( $default_term_id = get_option( 'default_taxonomy_' . $taxonomy ) ) ) { |
| | 2471 | $terms[] = (int) $default_term_id; |
| | 2472 | } |
| | 2473 | |
| 2441 | 2474 | if ( ! $append ) { |
| 2442 | 2475 | $old_tt_ids = wp_get_object_terms( |
| 2443 | 2476 | $object_id, |
diff --git a/tests/phpunit/tests/taxonomy.php b/tests/phpunit/tests/taxonomy.php
index 6d30ccf778..155d36be28 100644
|
a
|
b
|
class Tests_Taxonomy extends WP_UnitTestCase { |
| 958 | 958 | |
| 959 | 959 | $this->assertEquals( $problematic_term, $term_name ); |
| 960 | 960 | } |
| | 961 | |
| | 962 | /** |
| | 963 | * Test default term for custom taxonomy. |
| | 964 | * |
| | 965 | * @ticket 43517 |
| | 966 | */ |
| | 967 | function test_default_term_for_custom_taxonomy() { |
| | 968 | wp_set_current_user( self::factory()->user->create( array( 'role' => 'editor' ) ) ); |
| | 969 | |
| | 970 | $tax = 'custom-tax'; |
| | 971 | |
| | 972 | // Create custom taxonomy to test with. |
| | 973 | register_taxonomy( |
| | 974 | $tax, |
| | 975 | 'post', |
| | 976 | array( |
| | 977 | 'hierarchical' => true, |
| | 978 | 'public' => true, |
| | 979 | 'default_term' => array( |
| | 980 | 'name' => 'Default category', |
| | 981 | 'slug' => 'default-category', |
| | 982 | ), |
| | 983 | ) |
| | 984 | ); |
| | 985 | |
| | 986 | // Add post. |
| | 987 | $post_id = wp_insert_post( |
| | 988 | array( |
| | 989 | 'post_title' => 'Foo', |
| | 990 | 'post_type' => 'post', |
| | 991 | ) |
| | 992 | ); |
| | 993 | |
| | 994 | $term = wp_get_post_terms( $post_id, $tax ); |
| | 995 | $this->assertSame( get_option( 'default_taxonomy_' . $tax ), $term[0]->term_id ); |
| | 996 | |
| | 997 | // Add custom post. |
| | 998 | register_post_type( |
| | 999 | 'post-custom-tax', |
| | 1000 | array( 'taxonomies' => array( $tax ) ) |
| | 1001 | ); |
| | 1002 | |
| | 1003 | $post_id = wp_insert_post( |
| | 1004 | array( |
| | 1005 | 'post_title' => 'Foo', |
| | 1006 | 'post_type' => 'post-custom-tax', |
| | 1007 | ) |
| | 1008 | ); |
| | 1009 | |
| | 1010 | $term = wp_get_post_terms( $post_id, $tax ); |
| | 1011 | $this->assertSame( get_option( 'default_taxonomy_' . $tax ), $term[0]->term_id ); |
| | 1012 | } |
| 961 | 1013 | } |