mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-04-01 03:04:34 +00:00
REST API: Support meta registration for specific object subtypes.
Introduce an `object_subtype` argument to the args array for `register_meta()` which can be used to limit meta registration to a single subtype (e.g. a custom post type or taxonomy, vs all posts or taxonomies). Introduce `register_post_meta()` and `register_term_meta()` wrapper methods for `register_meta` to provide a convenient interface for the common case of registering meta for a specific taxonomy or post type. These methods work the way plugin developers have often expected `register_meta` to function, and should be used in place of direct `register_meta` where possible. Props flixos90, tharsheblows, spacedmonkey. Fixes #38323. git-svn-id: https://develop.svn.wordpress.org/trunk@43378 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -3,10 +3,24 @@
|
||||
* @group meta
|
||||
*/
|
||||
class Tests_Meta_Register_Meta extends WP_UnitTestCase {
|
||||
|
||||
protected static $post_id;
|
||||
protected static $term_id;
|
||||
protected static $comment_id;
|
||||
protected static $user_id;
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::$post_id = $factory->post->create();
|
||||
self::$post_id = $factory->post->create( array( 'post_type' => 'page' ) );
|
||||
self::$term_id = $factory->term->create( array( 'taxonomy' => 'category' ) );
|
||||
self::$comment_id = $factory->comment->create();
|
||||
self::$user_id = $factory->user->create();
|
||||
}
|
||||
|
||||
public static function wpTearDownAfterClass() {
|
||||
wp_delete_post( self::$post_id, true );
|
||||
wp_delete_term( self::$term_id, 'category' );
|
||||
wp_delete_comment( self::$comment_id, true );
|
||||
self::delete_user( self::$user_id );
|
||||
}
|
||||
|
||||
public function _old_sanitize_meta_cb( $meta_value, $meta_key, $meta_type ) {
|
||||
@@ -74,18 +88,20 @@ class Tests_Meta_Register_Meta extends WP_UnitTestCase {
|
||||
|
||||
$expected = array(
|
||||
'post' => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
'' => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertEquals( $actual, $expected );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
public function test_register_meta_with_term_object_type_populates_wp_meta_keys() {
|
||||
@@ -96,18 +112,20 @@ class Tests_Meta_Register_Meta extends WP_UnitTestCase {
|
||||
|
||||
$expected = array(
|
||||
'term' => array(
|
||||
'category_icon' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
'' => array(
|
||||
'category_icon' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertEquals( $actual, $expected );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
public function test_register_meta_with_deprecated_sanitize_callback_does_not_populate_wp_meta_keys() {
|
||||
@@ -148,13 +166,15 @@ class Tests_Meta_Register_Meta extends WP_UnitTestCase {
|
||||
|
||||
$expected = array(
|
||||
'post' => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
'' => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -301,4 +321,190 @@ class Tests_Meta_Register_Meta extends WP_UnitTestCase {
|
||||
|
||||
$this->assertEmpty( $meta );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_register_meta_with_subtype_populates_wp_meta_keys( $type, $subtype ) {
|
||||
global $wp_meta_keys;
|
||||
|
||||
register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
|
||||
|
||||
$expected = array(
|
||||
$type => array(
|
||||
$subtype => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = $wp_meta_keys;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$wp_meta_keys = array();
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_unregister_meta_with_subtype_unpopulates_wp_meta_keys( $type, $subtype ) {
|
||||
global $wp_meta_keys;
|
||||
|
||||
register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
|
||||
unregister_meta_key( $type, 'flight_number', $subtype );
|
||||
|
||||
$actual = $wp_meta_keys;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$wp_meta_keys = array();
|
||||
|
||||
$this->assertEmpty( $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_unregister_meta_without_subtype_keeps_subtype_meta_key( $type, $subtype ) {
|
||||
global $wp_meta_keys;
|
||||
|
||||
register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
|
||||
|
||||
// Unregister meta key without subtype.
|
||||
unregister_meta_key( $type, 'flight_number' );
|
||||
|
||||
$expected = array(
|
||||
$type => array(
|
||||
$subtype => array(
|
||||
'flight_number' => array(
|
||||
'type' => 'string',
|
||||
'description' => '',
|
||||
'single' => false,
|
||||
'sanitize_callback' => null,
|
||||
'auth_callback' => '__return_true',
|
||||
'show_in_rest' => false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = $wp_meta_keys;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$wp_meta_keys = array();
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_get_registered_meta_keys_with_subtype( $type, $subtype ) {
|
||||
register_meta( $type, 'registered_key1', array( 'object_subtype' => $subtype ) );
|
||||
register_meta( $type, 'registered_key2', array( 'object_subtype' => $subtype ) );
|
||||
|
||||
$meta_keys = get_registered_meta_keys( $type, $subtype );
|
||||
|
||||
$this->assertArrayHasKey( 'registered_key1', $meta_keys );
|
||||
$this->assertArrayHasKey( 'registered_key2', $meta_keys );
|
||||
$this->assertEmpty( get_registered_meta_keys( $type ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_get_registered_metadata_with_subtype( $type, $subtype ) {
|
||||
register_meta( $type, 'registered_key1', array() );
|
||||
|
||||
// This will override the above registration for objects of $subtype.
|
||||
register_meta( $type, 'registered_key1', array(
|
||||
'object_subtype' => $subtype,
|
||||
'single' => true,
|
||||
) );
|
||||
|
||||
// For testing with $single => false.
|
||||
register_meta( $type, 'registered_key2', array(
|
||||
'object_subtype' => $subtype,
|
||||
) );
|
||||
|
||||
// Register another meta key for a different subtype.
|
||||
register_meta( $type, 'registered_key3', array(
|
||||
'object_subtype' => 'other_subtype',
|
||||
) );
|
||||
|
||||
$object_property_name = $type . '_id';
|
||||
$object_id = self::$$object_property_name;
|
||||
|
||||
add_metadata( $type, $object_id, 'registered_key1', 'value1' );
|
||||
add_metadata( $type, $object_id, 'registered_key2', 'value2' );
|
||||
add_metadata( $type, $object_id, 'registered_key3', 'value3' );
|
||||
|
||||
$meta = get_registered_metadata( $type, $object_id );
|
||||
|
||||
$key1 = get_registered_metadata( $type, $object_id, 'registered_key1' );
|
||||
$key2 = get_registered_metadata( $type, $object_id, 'registered_key2' );
|
||||
$key3 = get_registered_metadata( $type, $object_id, 'registered_key3' );
|
||||
|
||||
$this->assertSame( array( 'registered_key1', 'registered_key2' ), array_keys( $meta ) );
|
||||
$this->assertSame( 'value1', $meta['registered_key1'][0] );
|
||||
$this->assertSame( 'value2', $meta['registered_key2'][0] );
|
||||
|
||||
$this->assertSame( 'value1', $key1 );
|
||||
$this->assertSame( array( 'value2' ), $key2 );
|
||||
$this->assertFalse( $key3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_types_and_subtypes
|
||||
*/
|
||||
public function test_get_object_subtype( $type, $expected_subtype ) {
|
||||
$object_property_name = $type . '_id';
|
||||
$object_id = self::$$object_property_name;
|
||||
|
||||
$this->assertSame( $expected_subtype, get_object_subtype( $type, $object_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
*/
|
||||
public function test_get_object_subtype_custom() {
|
||||
add_filter( 'get_object_subtype_customtype', array( $this, 'filter_get_object_subtype_for_customtype' ), 10, 2 );
|
||||
|
||||
$subtype_for_3 = get_object_subtype( 'customtype', 3 );
|
||||
$subtype_for_4 = get_object_subtype( 'customtype', 4 );
|
||||
|
||||
$this->assertSame( 'odd', $subtype_for_3 );
|
||||
$this->assertSame( 'even', $subtype_for_4 );
|
||||
}
|
||||
|
||||
public function filter_get_object_subtype_for_customtype( $subtype, $object_id ) {
|
||||
if ( $object_id % 2 === 1 ) {
|
||||
return 'odd';
|
||||
}
|
||||
|
||||
return 'even';
|
||||
}
|
||||
|
||||
public function data_get_types_and_subtypes() {
|
||||
return array(
|
||||
array( 'post', 'page' ),
|
||||
array( 'term', 'category' ),
|
||||
array( 'comment', 'comment' ),
|
||||
array( 'user', 'user' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
*/
|
||||
class Tests_Post_Meta extends WP_UnitTestCase {
|
||||
|
||||
private $last_register_meta_call = array(
|
||||
'object_type' => '',
|
||||
'meta_key' => '',
|
||||
'args' => array(),
|
||||
);
|
||||
|
||||
protected static $author;
|
||||
protected static $post_id;
|
||||
protected static $post_id_2;
|
||||
@@ -238,4 +244,65 @@ class Tests_Post_Meta extends WP_UnitTestCase {
|
||||
$this->assertEquals( $funky_meta, get_post_meta( self::$post_id, 'test_funky_post_meta', true ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_register_post_meta
|
||||
*/
|
||||
public function test_register_post_meta( $post_type, $meta_key, $args ) {
|
||||
add_filter( 'register_meta_args', array( $this, 'filter_register_meta_args_set_last_register_meta_call' ), 10, 4 );
|
||||
|
||||
register_post_meta( $post_type, $meta_key, $args );
|
||||
|
||||
$args['object_subtype'] = $post_type;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$GLOBALS['wp_meta_keys'] = array();
|
||||
|
||||
$this->assertEquals( 'post', $this->last_register_meta_call['object_type'] );
|
||||
$this->assertEquals( $meta_key, $this->last_register_meta_call['meta_key'] );
|
||||
$this->assertEquals( $args, $this->last_register_meta_call['args'] );
|
||||
}
|
||||
|
||||
public function data_register_post_meta() {
|
||||
return array(
|
||||
array( 'post', 'registered_key1', array( 'single' => true ) ),
|
||||
array( 'page', 'registered_key2', array() ),
|
||||
array( '', 'registered_key3', array( 'sanitize_callback' => 'absint' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
public function filter_register_meta_args_set_last_register_meta_call( $args, $defaults, $object_type, $meta_key ) {
|
||||
$this->last_register_meta_call['object_type'] = $object_type;
|
||||
$this->last_register_meta_call['meta_key'] = $meta_key;
|
||||
$this->last_register_meta_call['args'] = $args;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_unregister_post_meta
|
||||
*/
|
||||
public function test_unregister_post_meta( $post_type, $meta_key ) {
|
||||
global $wp_meta_keys;
|
||||
|
||||
register_post_meta( $post_type, $meta_key, array() );
|
||||
unregister_post_meta( $post_type, $meta_key );
|
||||
|
||||
$actual = $wp_meta_keys;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$wp_meta_keys = array();
|
||||
|
||||
$this->assertEmpty( $actual );
|
||||
}
|
||||
|
||||
public function data_unregister_post_meta() {
|
||||
return array(
|
||||
array( 'post', 'registered_key1' ),
|
||||
array( 'page', 'registered_key2' ),
|
||||
array( '', 'registered_key3' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,25 @@
|
||||
class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
protected static $wp_meta_keys_saved;
|
||||
protected static $post_id;
|
||||
protected static $cpt_post_id;
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
register_post_type( 'cpt', array(
|
||||
'show_in_rest' => true,
|
||||
'supports' => array( 'custom-fields' ),
|
||||
) );
|
||||
|
||||
self::$wp_meta_keys_saved = isset( $GLOBALS['wp_meta_keys'] ) ? $GLOBALS['wp_meta_keys'] : array();
|
||||
self::$post_id = $factory->post->create();
|
||||
self::$cpt_post_id = $factory->post->create( array( 'post_type' => 'cpt' ) );
|
||||
}
|
||||
|
||||
public static function wpTearDownAfterClass() {
|
||||
$GLOBALS['wp_meta_keys'] = self::$wp_meta_keys_saved;
|
||||
wp_delete_post( self::$post_id, true );
|
||||
wp_delete_post( self::$cpt_post_id, true );
|
||||
|
||||
unregister_post_type( 'cpt' );
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
@@ -120,6 +130,28 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
)
|
||||
);
|
||||
|
||||
register_post_type( 'cpt', array(
|
||||
'show_in_rest' => true,
|
||||
'supports' => array( 'custom-fields' ),
|
||||
) );
|
||||
|
||||
register_post_meta( 'cpt', 'test_cpt_single', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
) );
|
||||
|
||||
register_post_meta( 'cpt', 'test_cpt_multi', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => false,
|
||||
) );
|
||||
|
||||
// Register 'test_single' on subtype to override for bad auth.
|
||||
register_post_meta( 'cpt', 'test_single', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'auth_callback' => '__return_false',
|
||||
) );
|
||||
|
||||
/** @var WP_REST_Server $wp_rest_server */
|
||||
global $wp_rest_server;
|
||||
$wp_rest_server = new Spy_REST_Server;
|
||||
@@ -1047,6 +1079,126 @@ class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
$this->assertArrayNotHasKey( 'test_no_type', $meta_schema );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_subtype_meta_value
|
||||
*/
|
||||
public function test_get_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type ) {
|
||||
$post_id = self::$post_id;
|
||||
$endpoint = 'posts';
|
||||
if ( 'cpt' === $post_type ) {
|
||||
$post_id = self::$cpt_post_id;
|
||||
$endpoint = 'cpt';
|
||||
}
|
||||
|
||||
$meta_value = 'testvalue';
|
||||
|
||||
add_post_meta( $post_id, $meta_key, $meta_value );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertArrayHasKey( 'meta', $data );
|
||||
$this->assertInternalType( 'array', $data['meta'] );
|
||||
|
||||
if ( $in_post_type ) {
|
||||
$expected_value = $meta_value;
|
||||
if ( ! $single ) {
|
||||
$expected_value = array( $expected_value );
|
||||
}
|
||||
|
||||
$this->assertArrayHasKey( $meta_key, $data['meta'] );
|
||||
$this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
|
||||
} else {
|
||||
$this->assertArrayNotHasKey( $meta_key, $data['meta'] );
|
||||
}
|
||||
}
|
||||
|
||||
public function data_get_subtype_meta_value() {
|
||||
return array(
|
||||
array( 'cpt', 'test_cpt_single', true, true ),
|
||||
array( 'cpt', 'test_cpt_multi', false, true ),
|
||||
array( 'cpt', 'test_single', true, true ),
|
||||
array( 'cpt', 'test_multi', false, true ),
|
||||
array( 'post', 'test_cpt_single', true, false ),
|
||||
array( 'post', 'test_cpt_multi', false, false ),
|
||||
array( 'post', 'test_single', true, true ),
|
||||
array( 'post', 'test_multi', false, true ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_set_subtype_meta_value
|
||||
*/
|
||||
public function test_set_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type, $can_write ) {
|
||||
$post_id = self::$post_id;
|
||||
$endpoint = 'posts';
|
||||
if ( 'cpt' === $post_type ) {
|
||||
$post_id = self::$cpt_post_id;
|
||||
$endpoint = 'cpt';
|
||||
}
|
||||
|
||||
$meta_value = 'value_to_set';
|
||||
|
||||
$this->grant_write_permission();
|
||||
|
||||
$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
|
||||
$request->set_body_params( array(
|
||||
'meta' => array(
|
||||
$meta_key => $meta_value,
|
||||
),
|
||||
) );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
if ( ! $can_write ) {
|
||||
$this->assertEquals( 403, $response->get_status() );
|
||||
$this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$data = $response->get_data();
|
||||
$this->assertArrayHasKey( 'meta', $data );
|
||||
$this->assertInternalType( 'array', $data['meta'] );
|
||||
|
||||
if ( $in_post_type ) {
|
||||
$expected_value = $meta_value;
|
||||
if ( ! $single ) {
|
||||
$expected_value = array( $expected_value );
|
||||
}
|
||||
|
||||
$this->assertEquals( $expected_value, get_post_meta( $post_id, $meta_key, $single ) );
|
||||
$this->assertArrayHasKey( $meta_key, $data['meta'] );
|
||||
$this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
|
||||
} else {
|
||||
$this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
|
||||
$this->assertArrayNotHasKey( $meta_key, $data['meta'] );
|
||||
}
|
||||
}
|
||||
|
||||
public function data_set_subtype_meta_value() {
|
||||
$data = $this->data_get_subtype_meta_value();
|
||||
|
||||
foreach ( $data as $index => $dataset ) {
|
||||
$can_write = true;
|
||||
|
||||
// This combination is not writable because of an auth callback of '__return_false'.
|
||||
if ( 'cpt' === $dataset[0] && 'test_single' === $dataset[1] ) {
|
||||
$can_write = false;
|
||||
}
|
||||
|
||||
$data[ $index ][] = $can_write;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used to disable an insert query which
|
||||
* will trigger a wpdb error for testing purposes.
|
||||
|
||||
@@ -12,15 +12,24 @@
|
||||
class WP_Test_REST_Term_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
protected static $wp_meta_keys_saved;
|
||||
protected static $category_id;
|
||||
protected static $customtax_term_id;
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
register_taxonomy( 'customtax', 'post', array(
|
||||
'show_in_rest' => true,
|
||||
) );
|
||||
|
||||
self::$wp_meta_keys_saved = isset( $GLOBALS['wp_meta_keys'] ) ? $GLOBALS['wp_meta_keys'] : array();
|
||||
self::$category_id = $factory->category->create();
|
||||
self::$customtax_term_id = $factory->term->create( array( 'taxonomy' => 'customtax' ) );
|
||||
}
|
||||
|
||||
public static function wpTearDownAfterClass() {
|
||||
$GLOBALS['wp_meta_keys'] = self::$wp_meta_keys_saved;
|
||||
wp_delete_term( self::$category_id, 'category' );
|
||||
wp_delete_term( self::$customtax_term_id, 'customtax' );
|
||||
|
||||
unregister_taxonomy( 'customtax' );
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
@@ -120,6 +129,27 @@ class WP_Test_REST_Term_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
)
|
||||
);
|
||||
|
||||
register_taxonomy( 'customtax', 'post', array(
|
||||
'show_in_rest' => true,
|
||||
) );
|
||||
|
||||
register_term_meta( 'customtax', 'test_customtax_single', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
) );
|
||||
|
||||
register_term_meta( 'customtax', 'test_customtax_multi', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => false,
|
||||
) );
|
||||
|
||||
// Register 'test_single' on subtype to override for bad auth.
|
||||
register_term_meta( 'customtax', 'test_single', array(
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'auth_callback' => '__return_false',
|
||||
) );
|
||||
|
||||
/** @var WP_REST_Server $wp_rest_server */
|
||||
global $wp_rest_server;
|
||||
$wp_rest_server = new Spy_REST_Server;
|
||||
@@ -1047,6 +1077,126 @@ class WP_Test_REST_Term_Meta_Fields extends WP_Test_REST_TestCase {
|
||||
$this->assertArrayNotHasKey( 'test_no_type', $meta_schema );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_get_subtype_meta_value
|
||||
*/
|
||||
public function test_get_subtype_meta_value( $taxonomy, $meta_key, $single, $in_taxonomy ) {
|
||||
$term_id = self::$category_id;
|
||||
$endpoint = 'categories';
|
||||
if ( 'customtax' === $taxonomy ) {
|
||||
$term_id = self::$customtax_term_id;
|
||||
$endpoint = 'customtax';
|
||||
}
|
||||
|
||||
$meta_value = 'testvalue';
|
||||
|
||||
add_term_meta( $term_id, $meta_key, $meta_value );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/%s/%d', $endpoint, $term_id ) );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertArrayHasKey( 'meta', $data );
|
||||
$this->assertInternalType( 'array', $data['meta'] );
|
||||
|
||||
if ( $in_taxonomy ) {
|
||||
$expected_value = $meta_value;
|
||||
if ( ! $single ) {
|
||||
$expected_value = array( $expected_value );
|
||||
}
|
||||
|
||||
$this->assertArrayHasKey( $meta_key, $data['meta'] );
|
||||
$this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
|
||||
} else {
|
||||
$this->assertArrayNotHasKey( $meta_key, $data['meta'] );
|
||||
}
|
||||
}
|
||||
|
||||
public function data_get_subtype_meta_value() {
|
||||
return array(
|
||||
array( 'customtax', 'test_customtax_single', true, true ),
|
||||
array( 'customtax', 'test_customtax_multi', false, true ),
|
||||
array( 'customtax', 'test_single', true, true ),
|
||||
array( 'customtax', 'test_multi', false, true ),
|
||||
array( 'category', 'test_customtax_single', true, false ),
|
||||
array( 'category', 'test_customtax_multi', false, false ),
|
||||
array( 'category', 'test_single', true, true ),
|
||||
array( 'category', 'test_multi', false, true ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_set_subtype_meta_value
|
||||
*/
|
||||
public function test_set_subtype_meta_value( $taxonomy, $meta_key, $single, $in_taxonomy, $can_write ) {
|
||||
$term_id = self::$category_id;
|
||||
$endpoint = 'categories';
|
||||
if ( 'customtax' === $taxonomy ) {
|
||||
$term_id = self::$customtax_term_id;
|
||||
$endpoint = 'customtax';
|
||||
}
|
||||
|
||||
$meta_value = 'value_to_set';
|
||||
|
||||
$this->grant_write_permission();
|
||||
|
||||
$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/%s/%d', $endpoint, $term_id ) );
|
||||
$request->set_body_params( array(
|
||||
'meta' => array(
|
||||
$meta_key => $meta_value,
|
||||
),
|
||||
) );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
if ( ! $can_write ) {
|
||||
$this->assertEquals( 403, $response->get_status() );
|
||||
$this->assertEmpty( get_term_meta( $term_id, $meta_key, $single ) );
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$data = $response->get_data();
|
||||
$this->assertArrayHasKey( 'meta', $data );
|
||||
$this->assertInternalType( 'array', $data['meta'] );
|
||||
|
||||
if ( $in_taxonomy ) {
|
||||
$expected_value = $meta_value;
|
||||
if ( ! $single ) {
|
||||
$expected_value = array( $expected_value );
|
||||
}
|
||||
|
||||
$this->assertEquals( $expected_value, get_term_meta( $term_id, $meta_key, $single ) );
|
||||
$this->assertArrayHasKey( $meta_key, $data['meta'] );
|
||||
$this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
|
||||
} else {
|
||||
$this->assertEmpty( get_term_meta( $term_id, $meta_key, $single ) );
|
||||
$this->assertArrayNotHasKey( $meta_key, $data['meta'] );
|
||||
}
|
||||
}
|
||||
|
||||
public function data_set_subtype_meta_value() {
|
||||
$data = $this->data_get_subtype_meta_value();
|
||||
|
||||
foreach ( $data as $index => $dataset ) {
|
||||
$can_write = true;
|
||||
|
||||
// This combination is not writable because of an auth callback of '__return_false'.
|
||||
if ( 'customtax' === $dataset[0] && 'test_single' === $dataset[1] ) {
|
||||
$can_write = false;
|
||||
}
|
||||
|
||||
$data[ $index ][] = $can_write;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used to disable an insert query which
|
||||
* will trigger a wpdb error for testing purposes.
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
* @ticket 10142
|
||||
*/
|
||||
class Tests_Term_Meta extends WP_UnitTestCase {
|
||||
|
||||
private $last_register_meta_call = array(
|
||||
'object_type' => '',
|
||||
'meta_key' => '',
|
||||
'args' => array(),
|
||||
);
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
register_taxonomy( 'wptests_tax', 'post' );
|
||||
@@ -463,4 +470,65 @@ class Tests_Term_Meta extends WP_UnitTestCase {
|
||||
public static function set_cache_results( $q ) {
|
||||
$q->set( 'cache_results', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_register_term_meta
|
||||
*/
|
||||
public function test_register_term_meta( $taxonomy, $meta_key, $args ) {
|
||||
add_filter( 'register_meta_args', array( $this, 'filter_register_meta_args_set_last_register_meta_call' ), 10, 4 );
|
||||
|
||||
register_term_meta( $taxonomy, $meta_key, $args );
|
||||
|
||||
$args['object_subtype'] = $taxonomy;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$GLOBALS['wp_meta_keys'] = array();
|
||||
|
||||
$this->assertEquals( 'term', $this->last_register_meta_call['object_type'] );
|
||||
$this->assertEquals( $meta_key, $this->last_register_meta_call['meta_key'] );
|
||||
$this->assertEquals( $args, $this->last_register_meta_call['args'] );
|
||||
}
|
||||
|
||||
public function data_register_term_meta() {
|
||||
return array(
|
||||
array( 'wptests_tax', 'registered_key1', array( 'single' => true ) ),
|
||||
array( 'category', 'registered_key2', array() ),
|
||||
array( '', 'registered_key3', array( 'sanitize_callback' => 'absint' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
public function filter_register_meta_args_set_last_register_meta_call( $args, $defaults, $object_type, $meta_key ) {
|
||||
$this->last_register_meta_call['object_type'] = $object_type;
|
||||
$this->last_register_meta_call['meta_key'] = $meta_key;
|
||||
$this->last_register_meta_call['args'] = $args;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 38323
|
||||
* @dataProvider data_unregister_term_meta
|
||||
*/
|
||||
public function test_unregister_term_meta( $taxonomy, $meta_key ) {
|
||||
global $wp_meta_keys;
|
||||
|
||||
register_term_meta( $taxonomy, $meta_key, array() );
|
||||
unregister_term_meta( $taxonomy, $meta_key );
|
||||
|
||||
$actual = $wp_meta_keys;
|
||||
|
||||
// Reset global so subsequent data tests do not get polluted.
|
||||
$wp_meta_keys = array();
|
||||
|
||||
$this->assertEmpty( $actual );
|
||||
}
|
||||
|
||||
public function data_unregister_term_meta() {
|
||||
return array(
|
||||
array( 'wptests_tax', 'registered_key1' ),
|
||||
array( 'category', 'registered_key2' ),
|
||||
array( '', 'registered_key3' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user