| 3247 | /** |
| 3248 | * Format MySQL date string as RFC. |
| 3249 | * |
| 3250 | * @param string $date Date string (YYYY-MM-DD HH:MM:SS). |
| 3251 | * @param int $seconds_offset Number of seconds to add/subtract from the date. |
| 3252 | * @return string Date formatted as RFC. |
| 3253 | */ |
| 3254 | protected function format_gmt_date_as_rfc( $date_str, $seconds_offset = 0 ) { |
| 3255 | $timestamp = mysql2date( 'U', $date_str ); |
| 3256 | $timestamp += $seconds_offset; |
| 3257 | return str_replace( '+0000', 'GMT', gmdate( 'r', $timestamp ) ); |
| 3258 | } |
| 3259 | |
| 3260 | /** |
| 3261 | * Test If-Unmodified-Since request header when updating posts. |
| 3262 | * |
| 3263 | * @covers WP_REST_Posts_Controller::update_item_permissions_check() |
| 3264 | * @ticket 47676 |
| 3265 | */ |
| 3266 | public function test_update_item_with_if_unmodified_since_precondition() { |
| 3267 | wp_set_current_user( self::$editor_id ); |
| 3268 | |
| 3269 | // Test updating post with If-Unmodified-Since header matching the post_modified_gmt. |
| 3270 | $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); |
| 3271 | $request->add_header( 'content-type', 'application/json' ); |
| 3272 | $title1 = 'Same as last modified'; |
| 3273 | $request->set_body( wp_json_encode( $this->set_post_data( array( 'title' => $title1 ) ) ) ); |
| 3274 | $request->set_header( |
| 3275 | 'If-Unmodified-Since', |
| 3276 | $this->format_gmt_date_as_rfc( get_post( self::$post_id )->post_modified_gmt ) |
| 3277 | ); |
| 3278 | $response = rest_get_server()->dispatch( $request ); |
| 3279 | $this->assertSame( 200, $response->get_status() ); |
| 3280 | $new_data = $response->get_data(); |
| 3281 | $this->assertSame( $title1, $new_data['title']['raw'] ); |
| 3282 | $this->assertSame( $title1, get_post( self::$post_id )->post_title ); |
| 3283 | |
| 3284 | // Test updating post with If-Unmodified-Since header being in the future of post_modified_gmt. |
| 3285 | $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); |
| 3286 | $request->add_header( 'content-type', 'application/json' ); |
| 3287 | $title2 = '1 second after last modified'; |
| 3288 | $request->set_body( wp_json_encode( $this->set_post_data( array( 'title' => $title2 ) ) ) ); |
| 3289 | $request->set_header( |
| 3290 | 'If-Unmodified-Since', |
| 3291 | $this->format_gmt_date_as_rfc( get_post( self::$post_id )->post_modified_gmt, 1 ) |
| 3292 | ); |
| 3293 | $response = rest_get_server()->dispatch( $request ); |
| 3294 | $this->assertSame( 200, $response->get_status() ); |
| 3295 | $new_data = $response->get_data(); |
| 3296 | $this->assertSame( $title2, $new_data['title']['raw'] ); |
| 3297 | $this->assertSame( $title2, get_post( self::$post_id )->post_title ); |
| 3298 | |
| 3299 | // Test updating post with If-Unmodified-Since header being in the past of post_modified_gmt, thus failing the precondition. |
| 3300 | $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); |
| 3301 | $request->add_header( 'content-type', 'application/json' ); |
| 3302 | $title3 = '1 second before last modified'; |
| 3303 | $request->set_body( wp_json_encode( $this->set_post_data( array( 'title' => $title3 ) ) ) ); |
| 3304 | $request->set_header( |
| 3305 | 'If-Unmodified-Since', |
| 3306 | $this->format_gmt_date_as_rfc( get_post( self::$post_id )->post_modified_gmt, -1 ) |
| 3307 | ); |
| 3308 | $response = rest_get_server()->dispatch( $request ); |
| 3309 | $this->assertSame( 412, $response->get_status() ); |
| 3310 | $this->assertSame( $title2, get_post( self::$post_id )->post_title, 'Expected third title to not update due to failed precondition.' ); |
| 3311 | } |
| 3312 | |