Make WordPress Core

Opened 9 years ago

Closed 8 years ago

#28092 closed enhancement (fixed)

Ability to filter or remove error codes from WP_Error class

Reported by: adamcapriola's profile AdamCapriola Owned by: kovshenin's profile kovshenin
Milestone: 4.1 Priority: normal
Severity: normal Version: 2.1
Component: General Keywords: has-patch needs-testing needs-codex
Focuses: Cc:

Description

It would be very helpful if the WP_Error class would have a remove or adjusted add function. There is currently no way to filter or overwrite the error messages that come up. Specific messages can't even be targeted via CSS to hide them.

Here is an example of what could be added to the class:

function remove($code) {
	if ( array_key_exists( $code, $this->errors ) )
		unset($this->errors[$code]);
}

Alternatively (and preferentially), the add function could omit the ability to add multiple errors with the same "error code" so then they could simply be overwritten. (What is the reasoning for allowing multiple errors with the same error code anyway?)

function add($code, $message, $data = '') {
	$this->errors[$code] = $message;
	if ( ! empty($data) )
		$this->error_data[$code] = $data;
}

Finally, one other option would be to add maybe <span class="sanitized-error-code"> around the error messages. The messages could then be hidden by CSS if needed. This is probably the lesser of these ideas, though.

Attachments (2)

28092.diff (1.5 KB) - added by stephenharris 9 years ago.
28092.2.diff (3.1 KB) - added by kovshenin 8 years ago.

Download all attachments as: .zip

Change History (15)

#1 @johnbillion
9 years ago

  • Keywords reporter-feedback added
  • Version changed from 3.9 to 2.1

What use case do you have for this? Bear in mind that the WP_Error class is used for much more than just outputting errors as HTML.

#2 follow-up: @AdamCapriola
9 years ago

Here's something I'm working on. I am filtering the username validation and want to give a more specific error message to the registrant than "ERROR: This username is invalid because it uses illegal characters. Please enter a valid username." when the username is invalid. It would be nice if I could remove that error message since it becomes extraneous.

// Make sure username only contains letters, numbers, and underscores and is between 3 and 25 characters long
add_filter( 'validate_username', 'ac_validate_username', 10, 2 );

function ac_validate_username( $valid, $username ) {

	if ( preg_match( '/^[A-Za-z0-9_]{3,25}$/', $username ) )
		$valid = true;
	else
		$valid = false;

	return $valid;

}

// Give helpful error messages when registration fails
add_filter( 'registration_errors', 'ac_registration_errors', 10, 3 );

function ac_registration_errors( $errors, $sanitized_user_login, $user_email ) {

	// Unset 'user_login' error

	// Character issue
	if ( ! preg_match( '/^[A-Za-z0-9_]*$/', $_POST['user_login'] ) )
		$errors->add( 'user_login_characters', __( '<strong>ERROR</strong>: Usernames may contain only letters, numbers, and underscores.' ) );	

	// Length issue
	if ( ! preg_match( '/^.{3,25}$/', $_POST['user_login'] ) )
		$errors->add( 'user_login_length', __( '<strong>ERROR</strong>: Usernames must be between 3 and 25 characters long.' ) );		

	return $errors;

}

#3 in reply to: ↑ 2 @SergeyBiryukov
9 years ago

Replying to AdamCapriola:

I am filtering the username validation and want to give a more specific error message to the registrant than "ERROR: This username is invalid because it uses illegal characters. Please enter a valid username." when the username is invalid. It would be nice if I could remove that error message since it becomes extraneous.

You can just add unset( $errors->errors['invalid_username'] ) to your ac_registration_errors() function.

#4 @AdamCapriola
9 years ago

  • Resolution set to worksforme
  • Status changed from new to closed

Huh, I thought I tried something like that but I guess my syntax was off. That works!

#5 @SergeyBiryukov
9 years ago

  • Keywords reporter-feedback removed
  • Milestone Awaiting Review deleted

#6 @radiok
9 years ago

  • Component changed from Login and Registration to General
  • Resolution worksforme deleted
  • Status changed from closed to reopened

As of r28511, $errors is now private (#22234), r28521 added a setter to the WP_Error class (#27881) but the overall code to "unset" an error is now more cumbersome than ever.

unset( $errors->errors['empty_username'] );

Is now...

$temp = $errors->errors;
unset( $temp['empty_username'] );
$errors->errors = $temp;

All this would be simplified if we could just have a remove function within WP_Error.

Could this topic be revisited by a developer?

Last edited 9 years ago by radiok (previous) (diff)

#7 @nacin
9 years ago

  • Keywords needs-patch needs-unit-tests added
  • Milestone set to Future Release
  • Type changed from feature request to enhancement

Yes, there should be a WP_Error::remove( $code ). It should remove the code (and all messages for that code) and the corresponding error data, and it should have some basic unit tests.

@stephenharris
9 years ago

#8 @stephenharris
9 years ago

  • Keywords has-patch needs-testing needs-codex added; needs-patch needs-unit-tests removed

It passes the unit test I've added, however there are other unit tests which fail for me with a fresh checkout (I've not investigated why yet). Hence the 'needs testing' tag, just to be on the safe side.

#9 @SergeyBiryukov
9 years ago

  • Milestone changed from Future Release to 4.1

@kovshenin
8 years ago

#10 @kovshenin
8 years ago

In 28092.2.diff added some more tests and also moved them to general/errors.php.

#11 @nacin
8 years ago

  • Keywords commit added; needs-testing removed

Looks good.

#12 @nacin
8 years ago

  • Keywords needs-testing added; commit removed
  • Owner set to kovshenin
  • Status changed from reopened to assigned

#13 @kovshenin
8 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 29854:

New remove() method and some unit tests for the WP_Error class.

props stephenharris.
fixes #28092.

Note: See TracTickets for help on using tickets.