WordPress.org

Make WordPress Core

Changeset 49115


Ignore:
Timestamp:
10/09/2020 10:20:50 PM (5 months ago)
Author:
johnbillion
Message:

General: Introduce the ability to merge multiple WP_Error objects into one another, and to store more than one item of data for an error.

This allows multiple errors to be instantiated independently but collected into one without having to manually combine their properties.

Props rmccue, dlh, TimothyBlynJacobs

Fixes #38777

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-error.php

    r49022 r49115  
    22/**
    33 * WordPress Error API.
    4  *
    5  * Contains the WP_Error class and the is_wp_error() function.
    64 *
    75 * @package WordPress
     
    2826
    2927    /**
    30      * Stores the list of data for error codes.
     28     * Stores the most-recently added data for each error code.
    3129     *
    3230     * @since 2.1.0
     
    3634
    3735    /**
    38      * Initialize the error.
     36     * Stores previously added data added for error codes, oldest-to-newest by code.
     37     *
     38     * @since 5.6.0
     39     * @var array[]
     40     */
     41    protected $additional_data = array();
     42
     43    /**
     44     * Initializes the error.
    3945     *
    4046     * If `$code` is empty, the other parameters will be ignored.
     
    6167
    6268    /**
    63      * Retrieve all error codes.
     69     * Retrieves all error codes.
    6470     *
    6571     * @since 2.1.0
     
    7682
    7783    /**
    78      * Retrieve first error code available.
     84     * Retrieves the first error code available.
    7985     *
    8086     * @since 2.1.0
     
    9399
    94100    /**
    95      * Retrieve all error messages or error messages matching code.
     101     * Retrieves all error messages, or the error messages for the given error code.
    96102     *
    97103     * @since 2.1.0
    98104     *
    99105     * @param string|int $code Optional. Retrieve messages matching code, if exists.
    100      * @return array Error strings on success, or empty array on failure (if using code parameter).
     106     * @return array Error strings on success, or empty array if there are none.
    101107     */
    102108    public function get_error_messages( $code = '' ) {
     
    119125
    120126    /**
    121      * Get single error message.
     127     * Gets a single error message.
    122128     *
    123129     * This will get the first message available for the code. If no code is
     
    127133     *
    128134     * @param string|int $code Optional. Error code to retrieve message.
    129      * @return string
     135     * @return string The error message.
    130136     */
    131137    public function get_error_message( $code = '' ) {
     
    141147
    142148    /**
    143      * Retrieve error data for error code.
     149     * Retrieves the most-recently added error data for an error code.
    144150     *
    145151     * @since 2.1.0
     
    159165
    160166    /**
    161      * Verify if the instance contains errors.
     167     * Verifies if the instance contains errors.
    162168     *
    163169     * @since 5.1.0
    164170     *
    165      * @return bool
     171     * @return bool If the instance contains errors.
    166172     */
    167173    public function has_errors() {
     
    202208
    203209    /**
    204      * Add data for error code.
    205      *
    206      * The error code can only contain one error data.
    207      *
    208      * @since 2.1.0
     210     * Adds data to an error with the given code.
     211     *
     212     * @since 2.1.0
     213     * @since 5.6.0 Errors can now contain more than one item of error data. {@see WP_Error::$additional_data}.
    209214     *
    210215     * @param mixed      $data Error data.
     
    216221        }
    217222
     223        if ( isset( $this->error_data[ $code ] ) ) {
     224            $this->additional_data[ $code ][] = $this->error_data[ $code ];
     225        }
     226
    218227        $this->error_data[ $code ] = $data;
     228    }
     229
     230    /**
     231     * Retrieves all error data for an error code in the order in which the data was added.
     232     *
     233     * @since 5.6.0
     234     *
     235     * @param string|int $code Error code.
     236     * @return mixed[] Array of error data, if it exists.
     237     */
     238    public function get_all_error_data( $code = '' ) {
     239        if ( empty( $code ) ) {
     240            $code = $this->get_error_code();
     241        }
     242
     243        $data = array();
     244
     245        if ( isset( $this->additional_data[ $code ] ) ) {
     246            $data = $this->additional_data[ $code ];
     247        }
     248
     249        if ( isset( $this->error_data[ $code ] ) ) {
     250            $data[] = $this->error_data[ $code ];
     251        }
     252
     253        return $data;
    219254    }
    220255
     
    232267        unset( $this->errors[ $code ] );
    233268        unset( $this->error_data[ $code ] );
     269        unset( $this->additional_data[ $code ] );
     270    }
     271
     272    /**
     273     * Merges the errors in the given error object into this one.
     274     *
     275     * @since 5.6.0
     276     *
     277     * @param WP_Error $error Error object to merge.
     278     */
     279    public function merge_from( WP_Error $error ) {
     280        static::copy_errors( $error, $this );
     281    }
     282
     283    /**
     284     * Exports the errors in this object into the given one.
     285     *
     286     * @since 5.6.0
     287     *
     288     * @param WP_Error $error Error object to export into.
     289     */
     290    public function export_to( WP_Error $error ) {
     291        static::copy_errors( $this, $error );
     292    }
     293
     294    /**
     295     * Copies errors from one WP_Error instance to another.
     296     *
     297     * @since 5.6.0
     298     *
     299     * @param WP_Error $from From.
     300     * @param WP_Error $to   To.
     301     */
     302    protected static function copy_errors( WP_Error $from, WP_Error $to ) {
     303        foreach ( $from->get_error_codes() as $code ) {
     304            foreach ( $from->get_error_messages( $code ) as $error_message ) {
     305                $to->add( $code, $error_message );
     306            }
     307
     308            foreach ( $from->get_all_error_data( $code ) as $data ) {
     309                $to->add_data( $data, $code );
     310            }
     311        }
    234312    }
    235313}
  • trunk/tests/phpunit/tests/general/wpError.php

    r48940 r49115  
    377377
    378378    /**
     379     * @covers ::get_all_error_data
     380     */
     381    public function test_get_all_error_data_with_code_and_no_errors_should_evaluate_as_empty_array() {
     382        $this->assertSame( array(), $this->wp_error->get_all_error_data( 'code' ) );
     383    }
     384
     385    /**
     386     * @covers ::get_all_error_data
     387     */
     388    public function test_get_all_error_data_with_code_and_one_error_with_no_data_should_evaluate_as_empty_array() {
     389        $this->wp_error->add( 'code', 'message' );
     390
     391        $this->assertSame( array(), $this->wp_error->get_all_error_data( 'code' ) );
     392    }
     393
     394    /**
     395     * @covers ::get_all_error_data
     396     */
     397    public function test_get_all_error_data_with_code_and_one_error_with_data_should_return_that_data() {
     398        $expected = array( 'data-key' => 'data-value' );
     399        $this->wp_error->add( 'code', 'message', $expected );
     400
     401        $actual = $this->wp_error->get_all_error_data( 'code' );
     402        $this->assertCount( 1, $actual );
     403        $this->assertSameSetsWithIndex( $expected, $actual[0] );
     404    }
     405
     406    /**
     407     * @covers ::get_all_error_data
     408     */
     409    public function test_get_all_error_data_with_code_and_multiple_errors_same_code_should_return_all_data() {
     410        $this->wp_error->add( 'code', 'message', 'data' );
     411        $this->wp_error->add( 'code', 'message2', 'data2' );
     412        $this->wp_error->add( 'code2', 'message3', 'data3' );
     413
     414        $this->assertSame( array( 'data', 'data2' ), $this->wp_error->get_all_error_data( 'code' ) );
     415    }
     416
     417    /**
     418     * @covers ::get_all_error_data
     419     */
     420    public function test_get_all_error_data_should_handle_manipulation_of_error_data_property() {
     421        $this->wp_error->add_data( 'data1', 'code' );
     422        $this->wp_error->add_data( 'data2', 'code' );
     423
     424        $this->wp_error->error_data['code'] = 'dataX';
     425
     426        $this->assertSame( 'dataX', $this->wp_error->get_error_data( 'code' ) );
     427        $this->assertSame( array( 'data1', 'dataX' ), $this->wp_error->get_all_error_data( 'code' ) );
     428    }
     429
     430    /**
    379431     * @covers ::has_errors
    380432     */
     
    713765    public function test_remove_should_remove_the_error_data_associated_with_the_given_code() {
    714766        $this->wp_error->add( 'code', 'message', 'data' );
     767        $this->wp_error->add( 'code', 'message', 'data2' );
    715768
    716769        $this->wp_error->remove( 'code' );
    717770
    718771        $this->assertEmpty( $this->wp_error->error_data );
    719     }
    720 
     772        $this->assertEmpty( $this->wp_error->get_error_data( 'code' ) );
     773        $this->assertEmpty( $this->wp_error->get_all_error_data( 'code' ) );
     774    }
     775
     776    /**
     777     * @covers ::merge_from()
     778     */
     779    public function test_merge_from_should_copy_other_error_into_instance() {
     780        $this->wp_error->add( 'code1', 'message1', 'data1' );
     781
     782        $other = new WP_Error( 'code1', 'message2', 'data2' );
     783        $other->add( 'code2', 'message3' );
     784        $this->wp_error->merge_from( $other );
     785
     786        $this->assertSame( array( 'message1', 'message2' ), $this->wp_error->get_error_messages( 'code1' ) );
     787        $this->assertSame( 'data2', $this->wp_error->get_error_data( 'code1' ) );
     788        $this->assertSame( array( 'data1', 'data2' ), $this->wp_error->get_all_error_data( 'code1' ) );
     789        $this->assertSame( 'message3', $this->wp_error->get_error_message( 'code2' ) );
     790    }
     791
     792    /**
     793     * @covers ::merge_from()
     794     */
     795    public function test_merge_from_with_no_errors_should_not_add_to_instance() {
     796        $other = new WP_Error();
     797
     798        $this->wp_error->merge_from( $other );
     799
     800        $this->assertFalse( $this->wp_error->has_errors() );
     801    }
     802
     803    /**
     804     * @covers ::export_to()
     805     */
     806    public function test_export_to_should_copy_instance_into_other_error() {
     807        $other = new WP_Error();
     808        $other->add( 'code1', 'message1', 'data1' );
     809
     810        $this->wp_error->add( 'code1', 'message2', 'data2' );
     811        $this->wp_error->add( 'code2', 'message3' );
     812
     813        $this->wp_error->export_to( $other );
     814
     815        $this->assertSame( array( 'message1', 'message2' ), $other->get_error_messages( 'code1' ) );
     816        $this->assertSame( 'data2', $other->get_error_data( 'code1' ) );
     817        $this->assertSame( array( 'data1', 'data2' ), $other->get_all_error_data( 'code1' ) );
     818        $this->assertSame( 'message3', $other->get_error_message( 'code2' ) );
     819    }
     820
     821    /**
     822     * @covers ::export_to()
     823     */
     824    public function test_export_to_with_no_errors_should_not_add_to_other_error() {
     825        $other = new WP_Error();
     826
     827        $this->wp_error->export_to( $other );
     828
     829        $this->assertFalse( $other->has_errors() );
     830    }
    721831}
Note: See TracChangeset for help on using the changeset viewer.