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. git-svn-id: https://develop.svn.wordpress.org/trunk@31359 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
8f02177c40
commit
fb4048fcdd
@ -314,6 +314,47 @@ function edit_post( $post_data = null ) {
|
||||
$post_data = apply_filters( 'attachment_fields_to_save', $post_data, $attachment_data );
|
||||
}
|
||||
|
||||
// Convert taxonomy input to term IDs, to avoid ambiguity.
|
||||
if ( isset( $post_data['tax_input'] ) ) {
|
||||
foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
|
||||
// Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary.
|
||||
if ( is_taxonomy_hierarchical( $taxonomy ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that a 'tax_input' string is a comma-separated list of term names.
|
||||
* Some languages may use a character other than a comma as a delimiter, so we standardize on
|
||||
* commas before parsing the list.
|
||||
*/
|
||||
if ( ! is_array( $terms ) ) {
|
||||
$comma = _x( ',', 'tag delimiter' );
|
||||
if ( ',' !== $comma ) {
|
||||
$terms = str_replace( $comma, ',', $terms );
|
||||
}
|
||||
$terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
|
||||
}
|
||||
|
||||
$clean_terms = array();
|
||||
foreach ( $terms as $term ) {
|
||||
$_term = get_terms( $taxonomy, array(
|
||||
'name' => $term,
|
||||
'fields' => 'ids',
|
||||
'hide_empty' => false,
|
||||
) );
|
||||
|
||||
if ( ! empty( $_term ) ) {
|
||||
$clean_terms[] = intval( $_term[0] );
|
||||
} else {
|
||||
// No existing term was found, so pass the string. A new term will be created.
|
||||
$clean_terms[] = $term;
|
||||
}
|
||||
}
|
||||
|
||||
$post_data['tax_input'][ $taxonomy ] = $clean_terms;
|
||||
}
|
||||
}
|
||||
|
||||
add_meta( $post_ID );
|
||||
|
||||
update_post_meta( $post_ID, '_edit_last', get_current_user_id() );
|
||||
|
@ -136,6 +136,45 @@ class Tests_Admin_includesPost extends WP_UnitTestCase {
|
||||
$this->assertEquals( 'draft', get_post( $post->ID )->post_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 30615
|
||||
*/
|
||||
public function test_edit_post_should_parse_tax_input_by_name_rather_than_slug_for_nonhierarchical_taxonomies() {
|
||||
$u = $this->factory->user->create( array( 'role' => 'editor' ) );
|
||||
wp_set_current_user( $u );
|
||||
|
||||
register_taxonomy( 'wptests_tax', array( 'post' ) );
|
||||
$t1 = $this->factory->term->create( array(
|
||||
'taxonomy' => 'wptests_tax',
|
||||
'name' => 'foo',
|
||||
'slug' => 'bar',
|
||||
) );
|
||||
$t2 = $this->factory->term->create( array(
|
||||
'taxonomy' => 'wptests_tax',
|
||||
'name' => 'bar',
|
||||
'slug' => 'foo',
|
||||
) );
|
||||
|
||||
$p = $this->factory->post->create();
|
||||
|
||||
$post_data = array(
|
||||
'post_ID' => $p,
|
||||
'tax_input' => array(
|
||||
'wptests_tax' => 'foo,baz',
|
||||
),
|
||||
);
|
||||
|
||||
edit_post( $post_data );
|
||||
|
||||
$found = wp_get_post_terms( $p, 'wptests_tax' );
|
||||
|
||||
// Should contain the term with the name 'foo', not the slug.
|
||||
$this->assertContains( $t1, wp_list_pluck( $found, 'term_id' ) );
|
||||
|
||||
// The 'baz' tag should have been created.
|
||||
$this->assertContains( 'baz', wp_list_pluck( $found, 'name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 27792
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user