0

I am trying to register a custom endpoint, which will accept diacritic (accent) characters, so that I may search it in french.

This is what I have tried:

register_rest_route('events/v1', 'organizations/(?P<search>[a-zA-ZÀ-ž][\wÀ-ÿ]+)' array(
    'methods' => WP_REST_Server::READABLE,
    'callback' => 'get_event_organizations',
    'args' => [
        'search',
    ],
));)

The regex should work : https://regex101.com/r/aM6tV1/41

But the endpoint returns a rest_no_route / 404


EDIT

Thanks @Tim I was overcomplicating it!

register_rest_route('events/v1', 'organizations/(?P<search>[\w].+)' array(
    'methods' => WP_REST_Server::READABLE,
    'callback' => 'get_event_organizations',
    'args' => [
        'search',
    ],
));)

1 Answer 1

2

Looks to me like WordPress doesn't enable UTF-8 mode when it runs the regex.

https://github.com/WordPress/WordPress/blob/5.2.1/wp-includes/rest-api/class-wp-rest-server.php#L837

In PHP, matching multibyte characters requires the u flag. (The code above just adds the case-insensitive flag). So although some strings will still match (like "Département"), they're not matching as whole Unicode characters. For example the following pattern matches when it appears is shouldn't.

preg_match('@^[a-zA-ZÀ-ž][\\wÀ-ÿ]+$@i','£');
// returns 1

The "£" is matched, because it's made of two bytes (C2 A3). With UTF-8 mode enabled it doesn't match at the start of the string, because as a character (00A3) it's greater than "z" (007A) but less than "À" (00C0) in the first character range.

preg_match('@^[a-zA-ZÀ-ž]@iu','£');
// returns 0

So without seeing a specific input string that you're failing to match, this might explain why it's not working. Probably you don't need to be specifying such a specific pattern and can perhaps match any byte with .+ following a safely matched prefix.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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