How to modify only part of a function through the filter

The filter in questions filters an array, populated as follows:

$result = array(
        'user_name'  => $user_name,
        'user_email' => $user_email,
        'errors'     => $errors,
);

The error message is contained within the WP_Error object stored with the key errors.

The WP_Error object (see codex) store no, one or more errors in a private 2-D array indexed by error code. Each error code can have multiple error messages assigned to it.

Unfortunately you can only add errors, you cannot remove them, their messages or even change them, (see trac ticket – if you’re lucky I might submit a patch 😉 ).

The only (hacky) solution is to create a new WP_Error object from the given one, omitting the error message you want to change.

Health warnings

  • We are comparing human-readable strings, this could quite possibly change with no announcement. This is a hack after all.
  • Similarly the error code may change, without announcement. :/
  • Having observed BP’s code, even with a patch for the track ticket mentioned above, you still can’t target just the error message you want without using the human-readable string – all errors use the same code!

With that in mind,

function wpse161688_modifity_errors( $result ){

     $original_error = $result['errors'];
     $new_error      = new WP_Error();

     foreach( $original_error->get_error_codes() as $code ){
          foreach(  $original_error->get_error_messages( $code ) as $message ){  
                if( $code != 'user_name' || $message != __( 'Usernames can contain only letters, numbers, ., -, and @', 'buddypress' ) ){
                     $new_error->add( $code, $message );
                }else{
                     //This is the (code,message) pair we want to target...
                     $message="... change message here ... ";
                     $new_error->add( $code, $message );
                }
          }
     }

     $result['errors'] = $new_error;

     return $result;
}
add_filter( 'wpmu_validate_user_signup', 'wpse161688_modifity_errors' );

Please note that this is completely untested.