WordPress.org

Make WordPress Core

Ticket #43517: 43517.4.patch

File 43517.4.patch, 8.2 KB (added by enrico.sorcinelli, 17 months ago)
  • src/wp-includes/capabilities.php

    diff --git src/wp-includes/capabilities.php src/wp-includes/capabilities.php
    index a19487757c..d2eae061bc 100644
    function map_meta_cap( $cap, $user_id, ...$args ) { 
    539539                                break;
    540540                        }
    541541
    542                         if ( 'delete_term' === $cap && ( get_option( 'default_' . $term->taxonomy ) == $term->term_id ) ) {
     542                        if ( 'delete_term' === $cap && ( get_option( 'default_' . $term->taxonomy ) == $term->term_id || get_option( 'default_taxonomy_' . $term->taxonomy ) == $term->term_id ) ) {
    543543                                $caps[] = 'do_not_allow';
    544544                                break;
    545545                        }
  • src/wp-includes/class-wp-taxonomy.php

    diff --git src/wp-includes/class-wp-taxonomy.php src/wp-includes/class-wp-taxonomy.php
    index ebc7b0406f..c34a03c38e 100644
    final class WP_Taxonomy { 
    209209         */
    210210        public $rest_controller_class;
    211211
     212        /**
     213         * The default term name for this taxonomy. If you pass an array you have
     214         * to set 'name' and optionally 'slug' and 'description'.
     215         *
     216         * @since 5.5.0
     217         * @var array|string
     218         */
     219        public $default_term;
     220
    212221        /**
    213222         * The controller instance for this taxonomy's REST API endpoints.
    214223         *
    final class WP_Taxonomy { 
    288297                        'show_in_rest'          => false,
    289298                        'rest_base'             => false,
    290299                        'rest_controller_class' => false,
     300                        'default_term'          => null,
    291301                        '_builtin'              => false,
    292302                );
    293303
    final class WP_Taxonomy { 
    386396                        }
    387397                }
    388398
     399                // Default taxonomy term.
     400                if ( ! empty( $args['default_term'] ) ) {
     401                        if ( ! is_array( $args['default_term'] ) ) {
     402                                $args['default_term'] = array( 'name' => $args['default_term'] );
     403                        }
     404                        $args['default_term'] = wp_parse_args(
     405                                $args['default_term'],
     406                                array(
     407                                        'name'        => '',
     408                                        'slug'        => '',
     409                                        'description' => '',
     410                                )
     411                        );
     412                }
     413
    389414                foreach ( $args as $property_name => $property_value ) {
    390415                        $this->$property_name = $property_value;
    391416                }
  • src/wp-includes/post.php

    diff --git src/wp-includes/post.php src/wp-includes/post.php
    index d677b4afe0..65c7b6c15c 100644
    function wp_insert_post( $postarr, $wp_error = false ) { 
    40334033                wp_set_post_tags( $post_ID, $postarr['tags_input'] );
    40344034        }
    40354035
     4036        // Add default term for all associated custom taxonomies.
     4037        if ( 'auto-draft' !== $post_status ) {
     4038                foreach ( get_object_taxonomies( $post_type, 'object' ) as $taxonomy => $tax_object ) {
     4039                        if ( ! empty( $tax_object->default_term ) && ( empty( $postarr['tax_input'] ) || ! isset( $postarr['tax_input'][ $taxonomy ] ) ) ) {
     4040                                $postarr['tax_input'][ $taxonomy ] = array();
     4041                        }
     4042                }
     4043        }
     4044
    40364045        // New-style support for all custom taxonomies.
    40374046        if ( ! empty( $postarr['tax_input'] ) ) {
    40384047                foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
  • src/wp-includes/taxonomy.php

    diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
    index 707e26359c..db95d9bf50 100644
    function is_taxonomy_hierarchical( $taxonomy ) { 
    335335 *              arguments to register the Taxonomy in REST API.
    336336 * @since 5.1.0 Introduced `meta_box_sanitize_cb` argument.
    337337 * @since 5.4.0 Added the registered taxonomy object as a return value.
     338 * @since 5.5.0 Introduced `default_term` argument.
    338339 *
    339340 * @global array $wp_taxonomies Registered taxonomies.
    340341 *
    function is_taxonomy_hierarchical( $taxonomy ) { 
    406407 *                                                to post types, which confirms that the objects are published before
    407408 *                                                counting them. Default _update_generic_term_count() for taxonomies
    408409 *                                                attached to other object types, such as users.
     410 *     @type string|array  $default_term {
     411 *         Default term to be used for the taxonomy. To specify also slug and/or description an array can be passed
     412 *         with following keys:
     413 *
     414 *         @type string $name         Name of default term.
     415 *         @type string $slug         Slug for default term. Default empty.
     416 *         @type string $description  Description for default term. Default empty.
     417 *     }
    409418 *     @type bool          $_builtin              This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY!
    410419 *                                                Default false.
    411420 * }
    function register_taxonomy( $taxonomy, $object_type, $args = array() ) { 
    432441
    433442        $taxonomy_object->add_hooks();
    434443
     444        // Add default term.
     445        if ( ! empty( $taxonomy_object->default_term ) ) {
     446                if ( $term = term_exists( $taxonomy_object->default_term['name'], $taxonomy ) ) {
     447                        update_option( 'default_taxonomy_' . $taxonomy_object->name, $term['term_id'] );
     448                } else {
     449                        $term = wp_insert_term(
     450                                $taxonomy_object->default_term['name'],
     451                                $taxonomy,
     452                                array(
     453                                        'slug'        => sanitize_title( $taxonomy_object->default_term['slug'] ),
     454                                        'description' => $taxonomy_object->default_term['description'],
     455                                )
     456                        );
     457
     458                        // Update term id in options.
     459                        if ( ! is_wp_error( $term ) ) {
     460                                update_option( 'default_taxonomy_' . $taxonomy_object->name, $term['term_id'] );
     461                        }
     462                }
     463        }
     464
    435465        /**
    436466         * Fires after a taxonomy is registered.
    437467         *
    function unregister_taxonomy( $taxonomy ) { 
    476506        $taxonomy_object->remove_rewrite_rules();
    477507        $taxonomy_object->remove_hooks();
    478508
     509        // Remove custom taxonomy default term option.
     510        if ( ! empty( $taxonomy_object->default_term ) ) {
     511                delete_option( 'default_taxonomy_' . $taxonomy_object->name );
     512        }
     513
    479514        // Remove the taxonomy.
    480515        unset( $wp_taxonomies[ $taxonomy ] );
    481516
    function wp_delete_term( $term, $taxonomy, $args = array() ) { 
    17941829                }
    17951830        }
    17961831
     1832        // Don't delete the default custom taxonomy term.
     1833        $taxonomy_object = get_taxonomy( $taxonomy );
     1834        if ( ! empty( $taxonomy_object->default_term ) ) {
     1835                $defaults['default'] = (int) get_option( 'default_taxonomy_' . $taxonomy );
     1836                if ( $defaults['default'] === $term ) {
     1837                        return 0;
     1838                }
     1839        }
     1840
    17971841        $args = wp_parse_args( $args, $defaults );
    17981842
    17991843        if ( isset( $args['default'] ) ) {
    function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) { 
    24822526                $terms = array( $terms );
    24832527        }
    24842528
     2529        // Add default term.
     2530        $taxonomy_obj = get_taxonomy( $taxonomy );
     2531
     2532        // Default term for this taxonomy.
     2533        if ( empty( $terms ) && ! empty ( $taxonomy_obj->default_term ) && ! empty( $default_term_id = get_option( 'default_taxonomy_' . $taxonomy ) ) ) {
     2534                $terms[] = (int) $default_term_id;
     2535        }
     2536
    24852537        if ( ! $append ) {
    24862538                $old_tt_ids = wp_get_object_terms(
    24872539                        $object_id,
  • tests/phpunit/tests/taxonomy.php

    diff --git tests/phpunit/tests/taxonomy.php tests/phpunit/tests/taxonomy.php
    index adf61e76fc..d2972729ca 100644
    class Tests_Taxonomy extends WP_UnitTestCase { 
    965965
    966966                $this->assertEquals( $problematic_term, $term_name );
    967967        }
     968
     969        /**
     970         * Test default term for custom taxonomy.
     971         *
     972         * @ticket 43517
     973         */
     974        function test_default_term_for_custom_taxonomy() {
     975
     976                wp_set_current_user( self::factory()->user->create( array( 'role' => 'editor' ) ) );
     977
     978                $tax = 'custom-tax';
     979
     980                // Create custom taxonomy to test with.
     981                register_taxonomy(
     982                        $tax,
     983                        'post',
     984                        array(
     985                                'hierarchical' => true,
     986                                'public'       => true,
     987                                'default_term' => array(
     988                                        'name' => 'Default category',
     989                                        'slug' => 'default-category',
     990                                ),
     991                        )
     992                );
     993
     994                // Add post.
     995                $post_id = wp_insert_post(
     996                        array(
     997                                'post_title' => 'Foo',
     998                                'post_type'  => 'post',
     999                        )
     1000                );
     1001
     1002                // Test default category.
     1003                $term = wp_get_post_terms( $post_id, $tax );
     1004                $this->assertSame( get_option( 'default_taxonomy_' . $tax ), $term[0]->term_id );
     1005
     1006                // Test default term deletion.
     1007                $this->assertSame( wp_delete_term( $term[0]->term_id, $tax ), 0 );
     1008
     1009                // Add custom post type.
     1010                register_post_type(
     1011                        'post-custom-tax',
     1012                        array(
     1013                                'taxonomies' => array( $tax ),
     1014                        )
     1015                );
     1016                $post_id = wp_insert_post(
     1017                        array(
     1018                                'post_title' => 'Foo',
     1019                                'post_type'  => 'post-custom-tax',
     1020                        )
     1021                );
     1022                $term    = wp_get_post_terms( $post_id, $tax );
     1023                $this->assertSame( get_option( 'default_taxonomy_' . $tax ), $term[0]->term_id );
     1024
     1025                unregister_taxonomy( $tax );
     1026                $this->assertSame( get_option( 'default_taxonomy_' . $tax ), false );
     1027        }
    9681028}