Skip to content
Permalink
Browse files

REST API: Introduce date_floating property on status endpoint respons…

…e objects.

Expose a date_floating property on all status objects to permit clients (including the block editor) to make correct decisions about date handling for posts of varying status.

Props mnelson4, earnjam, kadamwhite, jnylen0, nerrad, pento.
See #39953.



git-svn-id: https://develop.svn.wordpress.org/trunk@46252 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information...
kadamwhite committed Sep 23, 2019
1 parent f2b03e2 commit 42e5e4d5d57c2db6022db5b392b02d6049d53de6
@@ -337,14 +337,15 @@ function create_initial_post_types() {
register_post_status(
'draft',
array(
'label' => _x( 'Draft', 'post status' ),
'protected' => true,
'_builtin' => true, /* internal use only. */
'label' => _x( 'Draft', 'post status' ),
'protected' => true,
'_builtin' => true, /* internal use only. */
/* translators: %s: Number of draft posts. */
'label_count' => _n_noop(
'label_count' => _n_noop(
'Draft <span class="count">(%s)</span>',
'Drafts <span class="count">(%s)</span>'
),
'date_floating' => true,
)
);
@@ -394,9 +395,10 @@ function create_initial_post_types() {
register_post_status(
'auto-draft',
array(
'label' => 'auto-draft',
'internal' => true,
'_builtin' => true, /* internal use only. */
'label' => 'auto-draft',
'internal' => true,
'_builtin' => true, /* internal use only. */
'date_floating' => true,
)
);
@@ -1018,6 +1020,8 @@ function _wp_privacy_statuses() {
* the top of the edit listings,
* e.g. All (12) | Published (9) | My Custom Status (2)
* Default is value of $internal.
* @type bool $date_floating Whether the post has a floating creation date.
* Default to false.
* }
* @return object
*/
@@ -1041,6 +1045,7 @@ function register_post_status( $post_status, $args = array() ) {
'publicly_queryable' => null,
'show_in_admin_status_list' => null,
'show_in_admin_all_list' => null,
'date_floating' => null,
);
$args = wp_parse_args( $args, $defaults );
$args = (object) $args;
@@ -1085,6 +1090,10 @@ function register_post_status( $post_status, $args = array() ) {
$args->show_in_admin_status_list = ! $args->internal;
}
if ( null === $args->date_floating ) {
$args->date_floating = false;
}
if ( false === $args->label ) {
$args->label = $post_status;
}
@@ -234,6 +234,10 @@ public function prepare_item_for_response( $status, $request ) {
$data['slug'] = $status->name;
}
if ( in_array( 'date_floating', $fields, true ) ) {
$data['date_floating'] = $status->date_floating;
}
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
@@ -277,48 +281,54 @@ public function get_item_schema() {
'title' => 'status',
'type' => 'object',
'properties' => array(
'name' => array(
'name' => array(
'description' => __( 'The title for the status.' ),
'type' => 'string',
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
'private' => array(
'private' => array(
'description' => __( 'Whether posts with this status should be private.' ),
'type' => 'boolean',
'context' => array( 'edit' ),
'readonly' => true,
),
'protected' => array(
'protected' => array(
'description' => __( 'Whether posts with this status should be protected.' ),
'type' => 'boolean',
'context' => array( 'edit' ),
'readonly' => true,
),
'public' => array(
'public' => array(
'description' => __( 'Whether posts of this status should be shown in the front end of the site.' ),
'type' => 'boolean',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'queryable' => array(
'queryable' => array(
'description' => __( 'Whether posts with this status should be publicly-queryable.' ),
'type' => 'boolean',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'show_in_list' => array(
'show_in_list' => array(
'description' => __( 'Whether to include posts in the edit listing for their post type.' ),
'type' => 'boolean',
'context' => array( 'edit' ),
'readonly' => true,
),
'slug' => array(
'slug' => array(
'description' => __( 'An alphanumeric identifier for the status.' ),
'type' => 'string',
'context' => array( 'embed', 'view', 'edit' ),
'readonly' => true,
),
'date_floating' => array(
'description' => __( 'Whether posts of this status may have floating published dates.' ),
'type' => 'boolean',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
),
);
@@ -1021,16 +1021,18 @@ protected function prepare_item_for_database( $request ) {
// Post date.
if ( ! empty( $schema['properties']['date'] ) && ! empty( $request['date'] ) ) {
$date_data = rest_get_date_with_gmt( $request['date'] );
$current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date : false;
$date_data = rest_get_date_with_gmt( $request['date'] );
if ( ! empty( $date_data ) ) {
if ( ! empty( $date_data ) && $current_date !== $date_data[0] ) {
list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data;
$prepared_post->edit_date = true;
}
} elseif ( ! empty( $schema['properties']['date_gmt'] ) && ! empty( $request['date_gmt'] ) ) {
$date_data = rest_get_date_with_gmt( $request['date_gmt'], true );
$current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date_gmt : false;
$date_data = rest_get_date_with_gmt( $request['date_gmt'], true );
if ( ! empty( $date_data ) ) {
if ( ! empty( $date_data ) && $current_date !== $date_data[1] ) {
list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data;
$prepared_post->edit_date = true;
}
@@ -153,14 +153,15 @@ public function test_get_item_schema() {
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$properties = $data['schema']['properties'];
$this->assertEquals( 7, count( $properties ) );
$this->assertEquals( 8, count( $properties ) );
$this->assertArrayHasKey( 'name', $properties );
$this->assertArrayHasKey( 'private', $properties );
$this->assertArrayHasKey( 'protected', $properties );
$this->assertArrayHasKey( 'public', $properties );
$this->assertArrayHasKey( 'queryable', $properties );
$this->assertArrayHasKey( 'show_in_list', $properties );
$this->assertArrayHasKey( 'slug', $properties );
$this->assertArrayhasKey( 'date_floating', $properties );
}
public function test_get_additional_field_registration() {
@@ -217,6 +218,7 @@ protected function check_post_status_obj( $status_obj, $data, $links ) {
),
array_keys( $links )
);
$this->assertEquals( $status_obj->date_floating, $data['date_floating'] );
}
protected function check_post_status_object_response( $response ) {
@@ -4413,6 +4413,119 @@ public function test_generated_permalink_template_generated_slug_for_posts() {
}
public function test_putting_same_publish_date_does_not_remove_floating_date() {
wp_set_current_user( self::$superadmin_id );
$time = date( 'Y-m-d H:i:s' );
$post = self::factory()->post->create_and_get(
array(
'post_status' => 'draft',
'post_date' => $time,
)
);
$this->assertEquals( '0000-00-00 00:00:00', $post->post_date_gmt );
$get = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post->ID}" );
$get->set_query_params( array( 'context' => 'edit' ) );
$get = rest_get_server()->dispatch( $get );
$get_body = $get->get_data();
$put = new WP_REST_Request( 'PUT', "/wp/v2/posts/{$post->ID}" );
$put->set_body_params( $get_body );
$response = rest_get_server()->dispatch( $put );
$body = $response->get_data();
$this->assertEquals( $get_body['date'], $body['date'] );
$this->assertEquals( $get_body['date_gmt'], $body['date_gmt'] );
$this->assertEquals( '0000-00-00 00:00:00', get_post( $post->ID )->post_date_gmt );
}
public function test_putting_different_publish_date_removes_floating_date() {
wp_set_current_user( self::$superadmin_id );
$time = date( 'Y-m-d H:i:s' );
$new_time = date( 'Y-m-d H:i:s', strtotime( '+1 week' ) );
$post = self::factory()->post->create_and_get(
array(
'post_status' => 'draft',
'post_date' => $time,
)
);
$this->assertEquals( '0000-00-00 00:00:00', $post->post_date_gmt );
$get = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post->ID}" );
$get->set_query_params( array( 'context' => 'edit' ) );
$get = rest_get_server()->dispatch( $get );
$get_body = $get->get_data();
$put = new WP_REST_Request( 'PUT', "/wp/v2/posts/{$post->ID}" );
$put->set_body_params(
array_merge(
$get_body,
array(
'date' => mysql_to_rfc3339( $new_time ),
)
)
);
$response = rest_get_server()->dispatch( $put );
$body = $response->get_data();
$this->assertEquals( mysql_to_rfc3339( $new_time ), $body['date'] );
$this->assertNotEquals( '0000-00-00 00:00:00', get_post( $post->ID )->post_date_gmt );
}
public function test_publishing_post_with_same_date_removes_floating_date() {
wp_set_current_user( self::$superadmin_id );
$time = date( 'Y-m-d H:i:s' );
$post = self::factory()->post->create_and_get(
array(
'post_status' => 'draft',
'post_date' => $time,
)
);
$this->assertEquals( '0000-00-00 00:00:00', $post->post_date_gmt );
$get = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post->ID}" );
$get->set_query_params( array( 'context' => 'edit' ) );
$get = rest_get_server()->dispatch( $get );
$get_body = $get->get_data();
$put = new WP_REST_Request( 'PUT', "/wp/v2/posts/{$post->ID}" );
$put->set_body_params(
array_merge(
$get_body,
array(
'status' => 'publish',
)
)
);
$response = rest_get_server()->dispatch( $put );
$body = $response->get_data();
$this->assertEquals( $get_body['date'], $body['date'] );
$this->assertEquals( $get_body['date_gmt'], $body['date_gmt'] );
$this->assertNotEquals( '0000-00-00 00:00:00', get_post( $post->ID )->post_date_gmt );
}
public function tearDown() {
_unregister_post_type( 'private-post' );
_unregister_post_type( 'youseeme' );
@@ -7392,6 +7392,7 @@ mockedApiResponse.StatusesCollection = {
"public": true,
"queryable": true,
"slug": "publish",
"date_floating": false,
"_links": {
"archives": [
{
@@ -7405,6 +7406,7 @@ mockedApiResponse.StatusesCollection = {
"public": false,
"queryable": false,
"slug": "future",
"date_floating": false,
"_links": {
"archives": [
{
@@ -7418,6 +7420,7 @@ mockedApiResponse.StatusesCollection = {
"public": false,
"queryable": false,
"slug": "draft",
"date_floating": true,
"_links": {
"archives": [
{
@@ -7431,6 +7434,7 @@ mockedApiResponse.StatusesCollection = {
"public": false,
"queryable": false,
"slug": "pending",
"date_floating": false,
"_links": {
"archives": [
{
@@ -7444,6 +7448,7 @@ mockedApiResponse.StatusesCollection = {
"public": false,
"queryable": false,
"slug": "private",
"date_floating": false,
"_links": {
"archives": [
{
@@ -7457,6 +7462,7 @@ mockedApiResponse.StatusesCollection = {
"public": false,
"queryable": false,
"slug": "trash",
"date_floating": false,
"_links": {
"archives": [
{
@@ -7471,7 +7477,8 @@ mockedApiResponse.StatusModel = {
"name": "Published",
"public": true,
"queryable": true,
"slug": "publish"
"slug": "publish",
"date_floating": false
};

mockedApiResponse.TaxonomiesCollection = {

0 comments on commit 42e5e4d

Please sign in to comment.
You can’t perform that action at this time.