diff --git a/wp-includes/class-wp-xmlrpc-server.php b/wp-includes/class-wp-xmlrpc-server.php index 9b80f0dfe1..a71ddfd44a 100644 --- a/wp-includes/class-wp-xmlrpc-server.php +++ b/wp-includes/class-wp-xmlrpc-server.php @@ -403,6 +403,68 @@ class wp_xmlrpc_server extends IXR_Server { } } + /** + * Retrieve custom fields for a term. + * + * @since 4.9.0 + * + * @param int $post_id Post ID. + * @return array Array of custom fields, if they exist. + */ + public function get_term_custom_fields( $term_id ) { + $term_id = (int) $term_id; + + $custom_fields = array(); + + foreach ( (array) has_term_meta( $term_id ) as $meta ) { + + if ( ! current_user_can( 'edit_term_meta', $term_id ) ) { + continue; + } + + $custom_fields[] = array( + 'id' => $meta['meta_id'], + 'key' => $meta['meta_key'], + 'value' => $meta['meta_value'], + ); + } + + return $custom_fields; + } + + /** + * Set custom fields for a term. + * + * @since 4.9.0 + * + * @param int $post_id Post ID. + * @param array $fields Custom fields. + */ + public function set_term_custom_fields( $term_id, $fields ) { + $term_id = (int) $term_id; + + foreach ( (array) $fields as $meta ) { + if ( isset( $meta['id'] ) ) { + $meta['id'] = (int) $meta['id']; + $pmeta = get_metadata_by_mid( 'term', $meta['id'] ); + if ( isset( $meta['key'] ) ) { + $meta['key'] = wp_unslash( $meta['key'] ); + if ( $meta['key'] !== $pmeta->meta_key ) { + continue; + } + $meta['value'] = wp_unslash( $meta['value'] ); + if ( current_user_can( 'edit_term_meta', $term_id ) ) { + update_metadata_by_mid( 'term', $meta['id'], $meta['value'] ); + } + } elseif ( current_user_can( 'delete_term_meta', $term_id ) ) { + delete_metadata_by_mid( 'term', $meta['id'] ); + } + } elseif ( current_user_can( 'add_term_meta', $term_id ) ) { + add_term_meta( $term_id, $meta['key'], $meta['value'] ); + } + } + } + /** * Set up blog options property. * @@ -742,6 +804,9 @@ class wp_xmlrpc_server extends IXR_Server { // Count we are happy to return as an integer because people really shouldn't use terms that much. $_term['count'] = intval( $_term['count'] ); + // Get term meta. + $_term['custom_fields'] = $this->get_term_custom_fields( $_term['term_id'] ); + /** * Filters XML-RPC-prepared data for the given term. * @@ -1943,6 +2008,11 @@ class wp_xmlrpc_server extends IXR_Server { if ( ! $term ) return new IXR_Error( 500, __( 'Sorry, your term could not be created.' ) ); + // Add term meta. + if ( isset( $content_struct['custom_fields'] ) ) { + $this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] ); + } + return strval( $term['term_id'] ); } @@ -2042,6 +2112,11 @@ class wp_xmlrpc_server extends IXR_Server { if ( ! $term ) return new IXR_Error( 500, __( 'Sorry, editing the term failed.' ) ); + // Update term meta. + if ( isset( $content_struct['custom_fields'] ) ) { + $this->set_term_custom_fields( $term_id, $content_struct['custom_fields'] ); + } + return true; } diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php index f1c1bce307..0c4012242c 100644 --- a/wp-includes/taxonomy.php +++ b/wp-includes/taxonomy.php @@ -1240,6 +1240,27 @@ function update_termmeta_cache( $term_ids ) { return update_meta_cache( 'term', $term_ids ); } +/** + * Get all meta data, including meta IDs, for the given term ID. + * + * @since 4.9.0 + * + * @global wpdb $wpdb WordPress database abstraction object. + * + * @param int $term_id + * @return array|false + */ +function has_term_meta( $term_id ) { + // Bail if term meta table is not installed. + if ( get_option( 'db_version' ) < 34370 ) { + return false; + } + + global $wpdb; + + return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, term_id FROM $wpdb->termmeta WHERE term_id = %d ORDER BY meta_key,meta_id", $term_id ), ARRAY_A ); +} + /** * Check if Term exists. * diff --git a/wp-includes/version.php b/wp-includes/version.php index 812ad0f5cc..674a54dff3 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.9-alpha-40915'; +$wp_version = '4.9-alpha-40916'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.