Changeset 50150
- Timestamp:
- 02/02/2021 05:26:06 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r50065 r50150 3183 3183 return $endpoint_args; 3184 3184 } 3185 3186 3187 /** 3188 * Converts an error to a response object. 3189 * 3190 * This iterates over all error codes and messages to change it into a flat 3191 * array. This enables simpler client behaviour, as it is represented as a 3192 * list in JSON rather than an object/map. 3193 * 3194 * @since 5.7.0 3195 * 3196 * @param WP_Error $error WP_Error instance. 3197 * 3198 * @return WP_REST_Response List of associative arrays with code and message keys. 3199 */ 3200 function rest_convert_error_to_response( $error ) { 3201 $status = array_reduce( 3202 $error->get_all_error_data(), 3203 function ( $status, $error_data ) { 3204 return is_array( $error_data ) && isset( $error_data['status'] ) ? $error_data['status'] : $status; 3205 }, 3206 500 3207 ); 3208 3209 $errors = array(); 3210 3211 foreach ( (array) $error->errors as $code => $messages ) { 3212 $all_data = $error->get_all_error_data( $code ); 3213 $last_data = array_pop( $all_data ); 3214 3215 foreach ( (array) $messages as $message ) { 3216 $formatted = array( 3217 'code' => $code, 3218 'message' => $message, 3219 'data' => $last_data, 3220 ); 3221 3222 if ( $all_data ) { 3223 $formatted['additional_data'] = $all_data; 3224 } 3225 3226 $errors[] = $formatted; 3227 } 3228 } 3229 3230 $data = $errors[0]; 3231 if ( count( $errors ) > 1 ) { 3232 // Remove the primary error. 3233 array_shift( $errors ); 3234 $data['additional_errors'] = $errors; 3235 } 3236 3237 return new WP_REST_Response( $data, $status ); 3238 } -
trunk/src/wp-includes/rest-api/class-wp-rest-request.php
r49955 r50150 803 803 $order = $this->get_parameter_order(); 804 804 805 $invalid_params = array(); 805 $invalid_params = array(); 806 $invalid_details = array(); 806 807 807 808 foreach ( $order as $type ) { … … 826 827 } 827 828 829 /** @var mixed|WP_Error $sanitized_value */ 828 830 $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); 829 831 830 832 if ( is_wp_error( $sanitized_value ) ) { 831 $invalid_params[ $key ] = $sanitized_value->get_error_message(); 833 $invalid_params[ $key ] = implode( ' ', $sanitized_value->get_error_messages() ); 834 $invalid_details[ $key ] = rest_convert_error_to_response( $sanitized_value )->get_data(); 832 835 } else { 833 836 $this->params[ $type ][ $key ] = $sanitized_value; … … 842 845 sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), 843 846 array( 844 'status' => 400, 845 'params' => $invalid_params, 847 'status' => 400, 848 'params' => $invalid_params, 849 'details' => $invalid_details, 846 850 ) 847 851 ); … … 895 899 * This is done after required checking as required checking is cheaper. 896 900 */ 897 $invalid_params = array(); 901 $invalid_params = array(); 902 $invalid_details = array(); 898 903 899 904 foreach ( $args as $key => $arg ) { … … 902 907 903 908 if ( null !== $param && ! empty( $arg['validate_callback'] ) ) { 909 /** @var bool|\WP_Error $valid_check */ 904 910 $valid_check = call_user_func( $arg['validate_callback'], $param, $this, $key ); 905 911 … … 909 915 910 916 if ( is_wp_error( $valid_check ) ) { 911 $invalid_params[ $key ] = $valid_check->get_error_message(); 917 $invalid_params[ $key ] = implode( ' ', $valid_check->get_error_messages() ); 918 $invalid_details[ $key ] = rest_convert_error_to_response( $valid_check )->get_data(); 912 919 } 913 920 } … … 920 927 sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), 921 928 array( 922 'status' => 400, 923 'params' => $invalid_params, 929 'status' => 400, 930 'params' => $invalid_params, 931 'details' => $invalid_details, 924 932 ) 925 933 ); -
trunk/src/wp-includes/rest-api/class-wp-rest-server.php
r49955 r50150 197 197 * 198 198 * @since 4.4.0 199 * @since 5.7.0 Converted to a wrapper of {@see rest_convert_error_to_response()}. 199 200 * 200 201 * @param WP_Error $error WP_Error instance. … … 202 203 */ 203 204 protected function error_to_response( $error ) { 204 $error_data = $error->get_error_data(); 205 206 if ( is_array( $error_data ) && isset( $error_data['status'] ) ) { 207 $status = $error_data['status']; 208 } else { 209 $status = 500; 210 } 211 212 $errors = array(); 213 214 foreach ( (array) $error->errors as $code => $messages ) { 215 foreach ( (array) $messages as $message ) { 216 $errors[] = array( 217 'code' => $code, 218 'message' => $message, 219 'data' => $error->get_error_data( $code ), 220 ); 221 } 222 } 223 224 $data = $errors[0]; 225 if ( count( $errors ) > 1 ) { 226 // Remove the primary error. 227 array_shift( $errors ); 228 $data['additional_errors'] = $errors; 229 } 230 231 $response = new WP_REST_Response( $data, $status ); 232 233 return $response; 205 return rest_convert_error_to_response( $error ); 234 206 } 235 207 -
trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php
r50124 r50150 456 456 $request->set_param( 'context', 'edit' ); 457 457 $response = rest_get_server()->dispatch( $request ); 458 $data = $response->get_data(); 459 $this->assertCount( 3, $data ); 460 $this->assertSame( 'rest_invalid_param', $data['code'] ); 458 $this->assertErrorResponse( 'rest_invalid_param', $response ); 461 459 } 462 460 -
trunk/tests/phpunit/tests/rest-api/rest-request.php
r49547 r50150 463 463 } 464 464 465 /** 466 * @ticket 46191 467 */ 468 public function test_sanitize_params_error_multiple_messages() { 469 $this->request->set_url_params( 470 array( 471 'failparam' => '123', 472 ) 473 ); 474 $this->request->set_attributes( 475 array( 476 'args' => array( 477 'failparam' => array( 478 'sanitize_callback' => function () { 479 $error = new WP_Error( 'invalid', 'Invalid.' ); 480 $error->add( 'invalid', 'Super Invalid.' ); 481 $error->add( 'broken', 'Broken.' ); 482 483 return $error; 484 }, 485 ), 486 ), 487 ) 488 ); 489 490 $valid = $this->request->sanitize_params(); 491 $this->assertWPError( $valid ); 492 $data = $valid->get_error_data(); 493 494 $this->assertInternalType( 'array', $data ); 495 $this->assertArrayHasKey( 'params', $data ); 496 $this->assertArrayHasKey( 'failparam', $data['params'] ); 497 $this->assertEquals( 'Invalid. Super Invalid. Broken.', $data['params']['failparam'] ); 498 } 499 500 /** 501 * @ticket 46191 502 */ 503 public function test_sanitize_params_provides_detailed_errors() { 504 $this->request->set_url_params( 505 array( 506 'failparam' => '123', 507 ) 508 ); 509 $this->request->set_attributes( 510 array( 511 'args' => array( 512 'failparam' => array( 513 'sanitize_callback' => function () { 514 return new WP_Error( 'invalid', 'Invalid.', 'mydata' ); 515 }, 516 ), 517 ), 518 ) 519 ); 520 521 $valid = $this->request->sanitize_params(); 522 $this->assertWPError( $valid ); 523 524 $data = $valid->get_error_data(); 525 $this->assertArrayHasKey( 'details', $data ); 526 $this->assertArrayHasKey( 'failparam', $data['details'] ); 527 $this->assertEquals( 528 array( 529 'code' => 'invalid', 530 'message' => 'Invalid.', 531 'data' => 'mydata', 532 ), 533 $data['details']['failparam'] 534 ); 535 } 536 465 537 public function test_sanitize_params_with_null_callback() { 466 538 $this->request->set_url_params( … … 651 723 $this->assertSame( array( 'someinteger', 'someotherparams' ), array_keys( $error_data['params'] ) ); 652 724 $this->assertSame( 'This is not valid!', $error_data['params']['someotherparams'] ); 725 } 726 727 728 /** 729 * @ticket 46191 730 */ 731 public function test_invalid_params_error_multiple_messages() { 732 $this->request->set_url_params( 733 array( 734 'failparam' => '123', 735 ) 736 ); 737 $this->request->set_attributes( 738 array( 739 'args' => array( 740 'failparam' => array( 741 'validate_callback' => function () { 742 $error = new WP_Error( 'invalid', 'Invalid.' ); 743 $error->add( 'invalid', 'Super Invalid.' ); 744 $error->add( 'broken', 'Broken.' ); 745 746 return $error; 747 }, 748 ), 749 ), 750 ) 751 ); 752 753 $valid = $this->request->has_valid_params(); 754 $this->assertWPError( $valid ); 755 $data = $valid->get_error_data(); 756 757 $this->assertInternalType( 'array', $data ); 758 $this->assertArrayHasKey( 'params', $data ); 759 $this->assertArrayHasKey( 'failparam', $data['params'] ); 760 $this->assertEquals( 'Invalid. Super Invalid. Broken.', $data['params']['failparam'] ); 761 } 762 763 /** 764 * @ticket 46191 765 */ 766 public function test_invalid_params_provides_detailed_errors() { 767 $this->request->set_url_params( 768 array( 769 'failparam' => '123', 770 ) 771 ); 772 $this->request->set_attributes( 773 array( 774 'args' => array( 775 'failparam' => array( 776 'validate_callback' => function () { 777 return new WP_Error( 'invalid', 'Invalid.', 'mydata' ); 778 }, 779 ), 780 ), 781 ) 782 ); 783 784 $valid = $this->request->has_valid_params(); 785 $this->assertWPError( $valid ); 786 787 $data = $valid->get_error_data(); 788 $this->assertArrayHasKey( 'details', $data ); 789 $this->assertArrayHasKey( 'failparam', $data['details'] ); 790 $this->assertEquals( 791 array( 792 'code' => 'invalid', 793 'message' => 'Invalid.', 794 'data' => 'mydata', 795 ), 796 $data['details']['failparam'] 797 ); 653 798 } 654 799 -
trunk/tests/phpunit/tests/rest-api/rest-server.php
r49925 r50150 408 408 $error = new WP_Error( $code, $message ); 409 409 410 $response = rest_ get_server()->error_to_response( $error );410 $response = rest_convert_error_to_response( $error ); 411 411 $this->assertInstanceOf( 'WP_REST_Response', $response ); 412 412 … … 425 425 $error = new WP_Error( $code, $message, array( 'status' => 400 ) ); 426 426 427 $response = rest_ get_server()->error_to_response( $error );427 $response = rest_convert_error_to_response( $error ); 428 428 $this->assertInstanceOf( 'WP_REST_Response', $response ); 429 429 … … 444 444 $error->add( $code2, $message2, array( 'status' => 403 ) ); 445 445 446 $response = rest_ get_server()->error_to_response( $error );446 $response = rest_convert_error_to_response( $error ); 447 447 $this->assertInstanceOf( 'WP_REST_Response', $response ); 448 448 … … 455 455 $this->assertSame( $message2, $error->errors[ $code2 ][0] ); 456 456 $this->assertSame( array( 'status' => 403 ), $error->error_data[ $code2 ] ); 457 } 458 459 /** 460 * @ticket 46191 461 */ 462 public function test_error_to_response_with_additional_data() { 463 $error = new WP_Error( 'test', 'test', array( 'status' => 400 ) ); 464 $error->add_data( 'more_data' ); 465 466 $response = rest_convert_error_to_response( $error ); 467 $this->assertSame( 400, $response->get_status() ); 468 $this->assertEquals( 'more_data', $response->get_data()['data'] ); 469 $this->assertEquals( array( array( 'status' => 400 ) ), $response->get_data()['additional_data'] ); 457 470 } 458 471
Note: See TracChangeset
for help on using the changeset viewer.