WordPress.org

Make WordPress Core

Changeset 31359


Ignore:
Timestamp:
02/06/2015 08:31:37 PM (4 years ago)
Author:
boonebgorges
Message:

Parse non-hierarchical tag input into term IDs before sending to wp_insert_post().

When editing a post, non-hierarchical taxonomy terms are sent as the
comma-separated list entered into the tax_input metabox. Passing these
values directly to wp_update_post() meant that they were interpreted as
term slugs rather than term names, causing mismatches when a typed string
matched the slug of one term and the name of a different term. We fix the
problem by preprocessing tax_input data sent from post.php, converting it to
unambiguous term_ids before saving.

Props boonebgorges, ArminBraun.
Fixes #30615.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/post.php

    r31323 r31359  
    313313        /** This filter is documented in wp-admin/includes/media.php */
    314314        $post_data = apply_filters( 'attachment_fields_to_save', $post_data, $attachment_data );
     315    }
     316
     317    // Convert taxonomy input to term IDs, to avoid ambiguity.
     318    if ( isset( $post_data['tax_input'] ) ) {
     319        foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
     320            // Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary.
     321            if ( is_taxonomy_hierarchical( $taxonomy ) ) {
     322                continue;
     323            }
     324
     325            /*
     326             * Assume that a 'tax_input' string is a comma-separated list of term names.
     327             * Some languages may use a character other than a comma as a delimiter, so we standardize on
     328             * commas before parsing the list.
     329             */
     330            if ( ! is_array( $terms ) ) {
     331                $comma = _x( ',', 'tag delimiter' );
     332                if ( ',' !== $comma ) {
     333                    $terms = str_replace( $comma, ',', $terms );
     334                }
     335                $terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
     336            }
     337
     338            $clean_terms = array();
     339            foreach ( $terms as $term ) {
     340                $_term = get_terms( $taxonomy, array(
     341                    'name' => $term,
     342                    'fields' => 'ids',
     343                    'hide_empty' => false,
     344                ) );
     345
     346                if ( ! empty( $_term ) ) {
     347                    $clean_terms[] = intval( $_term[0] );
     348                } else {
     349                    // No existing term was found, so pass the string. A new term will be created.
     350                    $clean_terms[] = $term;
     351                }
     352            }
     353
     354            $post_data['tax_input'][ $taxonomy ] = $clean_terms;
     355        }
    315356    }
    316357
  • trunk/tests/phpunit/tests/admin/includesPost.php

    r31323 r31359  
    138138
    139139    /**
     140     * @ticket 30615
     141     */
     142    public function test_edit_post_should_parse_tax_input_by_name_rather_than_slug_for_nonhierarchical_taxonomies() {
     143        $u = $this->factory->user->create( array( 'role' => 'editor' ) );
     144        wp_set_current_user( $u );
     145
     146        register_taxonomy( 'wptests_tax', array( 'post' ) );
     147        $t1 = $this->factory->term->create( array(
     148            'taxonomy' => 'wptests_tax',
     149            'name' => 'foo',
     150            'slug' => 'bar',
     151        ) );
     152        $t2 = $this->factory->term->create( array(
     153            'taxonomy' => 'wptests_tax',
     154            'name' => 'bar',
     155            'slug' => 'foo',
     156        ) );
     157
     158        $p = $this->factory->post->create();
     159
     160        $post_data = array(
     161            'post_ID' => $p,
     162            'tax_input' => array(
     163                'wptests_tax' => 'foo,baz',
     164            ),
     165        );
     166
     167        edit_post( $post_data );
     168
     169        $found = wp_get_post_terms( $p, 'wptests_tax' );
     170
     171        // Should contain the term with the name 'foo', not the slug.
     172        $this->assertContains( $t1, wp_list_pluck( $found, 'term_id' ) );
     173
     174        // The 'baz' tag should have been created.
     175        $this->assertContains( 'baz', wp_list_pluck( $found, 'name' ) );
     176    }
     177
     178    /**
    140179     * @ticket 27792
    141180     */
Note: See TracChangeset for help on using the changeset viewer.