WordPress.org

Make WordPress Core

Ticket #36514: 36514.4.diff

File 36514.4.diff, 7.2 KB (added by ZaneMatthew, 2 years ago)
  • src/wp-admin/includes/post.php

    diff --git src/wp-admin/includes/post.php src/wp-admin/includes/post.php
    index 1054f2b..2ccd2ab 100644
    function edit_post( $post_data = null ) { 
    328328        // Convert taxonomy input to term IDs, to avoid ambiguity.
    329329        if ( isset( $post_data['tax_input'] ) ) {
    330330                foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
    331                         // Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary.
    332                         if ( is_taxonomy_hierarchical( $taxonomy ) ) {
    333                                 continue;
    334                         }
     331                        $tax_object = get_taxonomy( $taxonomy );
    335332
    336                         /*
    337                          * Assume that a 'tax_input' string is a comma-separated list of term names.
    338                          * Some languages may use a character other than a comma as a delimiter, so we standardize on
    339                          * commas before parsing the list.
    340                          */
    341                         if ( ! is_array( $terms ) ) {
    342                                 $comma = _x( ',', 'tag delimiter' );
    343                                 if ( ',' !== $comma ) {
    344                                         $terms = str_replace( $comma, ',', $terms );
    345                                 }
    346                                 $terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
     333                        if ( $tax_object && isset( $tax_object->meta_box_sanitize_cb ) ) {
     334                                $post_data['tax_input'][ $taxonomy ] = call_user_func_array( $tax_object->meta_box_sanitize_cb, array( $taxonomy, $terms ) );
    347335                        }
    348 
    349                         $clean_terms = array();
    350                         foreach ( $terms as $term ) {
    351                                 // Empty terms are invalid input.
    352                                 if ( empty( $term ) ) {
    353                                         continue;
    354                                 }
    355 
    356                                 $_term = get_terms( $taxonomy, array(
    357                                         'name' => $term,
    358                                         'fields' => 'ids',
    359                                         'hide_empty' => false,
    360                                 ) );
    361 
    362                                 if ( ! empty( $_term ) ) {
    363                                         $clean_terms[] = intval( $_term[0] );
    364                                 } else {
    365                                         // No existing term was found, so pass the string. A new term will be created.
    366                                         $clean_terms[] = $term;
    367                                 }
    368                         }
    369 
    370                         $post_data['tax_input'][ $taxonomy ] = $clean_terms;
    371336                }
    372337        }
    373338
    function redirect_post($post_id = '') { 
    18551820        wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
    18561821        exit;
    18571822}
     1823
     1824/**
     1825 * Sanitizes POST values from a checkbox taxonomy metabox.
     1826 *
     1827 * @since 4.7.0
     1828 *
     1829 * @param mixed $terms Raw term data from the 'tax_input' field.
     1830 * @return array
     1831 */
     1832function taxonomy_meta_box_sanitize_cb_checkboxes( $taxonmy, $terms ) {
     1833        return array_map( 'intval', $terms );
     1834}
     1835
     1836/**
     1837 * Sanitizes POST values from an input taxonomy metabox.
     1838 *
     1839 * @since 4.7.0
     1840 *
     1841 * @param mixed $terms Raw term data from the 'tax_input' field.
     1842 * @return array
     1843 */
     1844function taxonomy_meta_box_sanitize_cb_input( $taxonomy, $terms ) {
     1845        /*
     1846         * Assume that a 'tax_input' string is a comma-separated list of term names.
     1847         * Some languages may use a character other than a comma as a delimiter, so we standardize on
     1848         * commas before parsing the list.
     1849         */
     1850        if ( ! is_array( $terms ) ) {
     1851                $comma = _x( ',', 'tag delimiter' );
     1852                if ( ',' !== $comma ) {
     1853                        $terms = str_replace( $comma, ',', $terms );
     1854                }
     1855                $terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
     1856        }
     1857
     1858        $clean_terms = array();
     1859        foreach ( $terms as $term ) {
     1860                // Empty terms are invalid input.
     1861                if ( empty( $term ) ) {
     1862                        continue;
     1863                }
     1864
     1865                $_term = get_terms( $taxonomy, array(
     1866                        'name' => $term,
     1867                        'fields' => 'ids',
     1868                        'hide_empty' => false,
     1869                ) );
     1870
     1871                if ( ! empty( $_term ) ) {
     1872                        $clean_terms[] = intval( $_term[0] );
     1873                } else {
     1874                        // No existing term was found, so pass the string. A new term will be created.
     1875                        $clean_terms[] = $term;
     1876                }
     1877        }
     1878
     1879        return $clean_terms;
     1880}
  • src/wp-includes/class-wp-taxonomy.php

    diff --git src/wp-includes/class-wp-taxonomy.php src/wp-includes/class-wp-taxonomy.php
    index 3a69b76..959fb77 100644
    final class WP_Taxonomy { 
    142142        public $meta_box_cb = null;
    143143
    144144        /**
     145         * The callback function for sanitizing taxonomy data saved from a meta box.
     146         *
     147         * @since 4.7.0
     148         * @access public
     149         * @var callable
     150         */
     151        public $meta_box_sanitize_cb = null;
     152
     153        /**
    145154         * An array of object types this taxonomy is registered for.
    146155         *
    147156         * @since 4.7.0
    final class WP_Taxonomy { 
    250259                        'show_in_quick_edit'    => null,
    251260                        'show_admin_column'     => false,
    252261                        'meta_box_cb'           => null,
     262                        'meta_box_sanitize_cb'  => null,
    253263                        'capabilities'          => array(),
    254264                        'rewrite'               => true,
    255265                        'query_var'             => $this->name,
    final class WP_Taxonomy { 
    335345
    336346                $args['name'] = $this->name;
    337347
     348                // Default meta box sanitization callback depends on the value of 'meta_box_cb'.
     349                if ( null === $args['meta_box_sanitize_cb'] ) {
     350                        switch ( $args['meta_box_cb'] ) {
     351                                case 'post_categories_meta_box' :
     352                                        $args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_checkboxes';
     353                                break;
     354
     355                                case 'post_tags_meta_box' :
     356                                default :
     357                                        $args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_input';
     358                                break;
     359                        }
     360                }
     361
    338362                foreach ( $args as $property_name => $property_value ) {
    339363                        $this->$property_name = $property_value;
    340364                }
  • src/wp-includes/taxonomy.php

    diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
    index a67d52a..cda775a 100644
    function is_taxonomy_hierarchical($taxonomy) { 
    338338 *                                                post_categories_meta_box() is used for hierarchical taxonomies, and
    339339 *                                                post_tags_meta_box() is used for non-hierarchical. If false, no meta
    340340 *                                                box is shown.
     341 *     @type callable      $meta_box_sanitize_cb  Callback function for sanitizing taxonomy data saved from a meta
     342 *                                                box. If no callback is defined, an appropriate one is determined
     343 *                                                based on the value of `$meta_box_cb`.
    341344 *     @type array         $capabilities {
    342345 *         Array of capabilities for this taxonomy.
    343346 *
  • tests/phpunit/tests/taxonomy.php

    diff --git tests/phpunit/tests/taxonomy.php tests/phpunit/tests/taxonomy.php
    index 9a4e8b2..b098d91 100644
    class Tests_Taxonomy extends WP_UnitTestCase { 
    721721
    722722                $this->assertSame( 'foo', $taxonomy->name );
    723723        }
     724
     725        /**
     726         * @ticket 36514
     727         */
     728        public function test_edit_post_hierarchical_taxonomy() {
     729
     730                $taxonomy_name = 'foo';
     731                $term_name     = 'bar';
     732
     733                register_taxonomy( $taxonomy_name, array( 'post' ), array(
     734                        'hierarchical' => false,
     735                        'meta_box_cb'  => 'post_categories_meta_box',
     736                ) );
     737                $post = self::factory()->post->create_and_get( array(
     738                        'post_type' => 'post',
     739                ) );
     740
     741                $term_id  = self::factory()->term->create_object( array(
     742                        'name'     => $term_name,
     743                        'taxonomy' => $taxonomy_name,
     744                ) );
     745
     746                wp_set_current_user( self::factory()->user->create( array( 'role' => 'editor' ) ) );
     747                $updated_post_id = edit_post( array(
     748                        'post_ID'   => $post->ID,
     749                        'post_type' => 'post',
     750                        'tax_input' => array(
     751                                $taxonomy_name => array(
     752                                        (string) $term_id // Cast term_id as string to match whats sent in WP Admin.
     753                                ),
     754                        ),
     755                ) );
     756
     757                $terms_obj = get_the_terms( $updated_post_id, $taxonomy_name );
     758                $problematic_term = current( wp_list_pluck( $terms_obj, 'name' ) );
     759
     760                $this->assertEquals( $problematic_term, $term_name );
     761        }
    724762}