so wordpress' core isn't really up to date with email allowances of unicode domains. Even simple special characters like the german umlauts (äÄöÖüÜß) aren't allowed in the domain part of the name.

So I've been thinking to add a filter to the is_email function with high priority and simply return the result. But it doesn't seem to function as I've intended to. Here's what I've tried:

// Code written in my themes functions.php
function kk_email_validation_override( $email )
    $pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9äÄüÜöÖß]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9äÄüÜöÖß]*)|(?:(?:xn--)[a-z0-9äÄüÜöÖß]+))(?:-+[a-z0-9äÄüÜöÖß]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD';

    if (preg_match($pattern, $email)) {
        return trim(strtolower($email));

    return false;
add_filter('is_email', 'kk_email_validation_override', 99, 4);

For some reason though, the original wordpress' is_email() is still being called. Am I applying my filter wrong or what else am I missing to not go down the filter chain of wordpress' filtering?

Thanks in advance!


1 Answer 1


is_email is a native WP function. As you can see here (https://core.trac.wordpress.org/browser/tags/5.0.3/src/wp-includes/formatting.php#L2886) it allows you to modify it with filter is_email.

So yes - anytime the function is_email will be called, it will run, and at the end it will run your filters allowing you to modify the result.

But... The filter should take 3 params:

$is_email (bool) Whether the email address has passed the is_email() checks. Default false.

$email (string) The email address being checked.

$context (string) Context under which the email was tested.

function my_email_validation( $is_email, $email, $context )
    if ( <MY CONDITION> ) {  // check if it is an email
        return true;

    return false;
add_filter( 'is_email', 'my_email_validation', 99, 3 );

So your code doesn't work, because you use this filter incorrectly (you register it as it should take 4 params and your filter function takes only one, and so on).

  • OK, so most importantly, filters are only run after the core functionality did run itself. That's bad for my use-case as it's therefore impossible to modify the ruleset for email domains at wordpress itself. Basically I can ADD rules that wordpress doesn't detect but I cannot remove false-detections from wordpress. Thank you for this specific clarification!
    – Sam
    Jan 28, 2019 at 11:05
  • Filters are run when apply_filters is run. If given core function uses filter to allow you to override its result, then you can override it. In this case, all results of that functions are passed to filters, so you can override it and return true even if core function was going to return false. But you have to implement the filter function correctly. Jan 28, 2019 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.