-
Bug
-
Resolution: Fixed
-
Blocker
-
4.5
Slim/FastRoute support the idea of an unlimited capture, for example:
// Greedy variant.
|
/path/to/{somevalue:.*}
|
// Non-greedy variant.
|
/path/to/{somevalue:.*?}
|
This will match
URL | Value of somevalue |
---|---|
/path/to | null |
/path/to/location | location |
/path/to/location/about | location/about |
In these cases the path_parameter has an is_required() method which checks whether the parameter is required in the path pattern for the route, however it is not aware of the unlimited captures. We also need to update the specification to be aware of these placeholders (or rather strip them out).
To add to this explanation, here's an excerpt from a discussion wtih David:
We support templates at location such as the following:
core/modal
|
core/notification
|
core/navbar
|
core/local/modal/alert
|
core/local/toast/notification
|
When we request those from the new API we use the URI:
/templates/{themename}/{component}/{identifier}
|
So those examples would be:
https://example.com/moodle/rest/api/v2/core/templates/boost/core/modal
|
https://example.com/moodle/rest/api/v2/core/templates/boost/core/notification
|
https://example.com/moodle/rest/api/v2/core/templates/boost/core/navbar
|
https://example.com/moodle/rest/api/v2/core/templates/boost/core/local/modal/alert
|
https://example.com/moodle/rest/api/v2/core/templates/boost/core/local/toast/notification
|
However, the way that the URI is passed that `
{identifier}` is internally (by Slim/FastRoute) turned into a regular expression that looks a bit like:
/([^/]*/?)$
|
That is look for a leading slash (`/`) followed by any character up to an optional slash and the end of the URI (`([^/]*/?)$`)).
So the first three of those work because the `identifier` components (`modal`, `notification`, and `navbar`) are the end of the URI.
But the last two have identifiers of:
local/modal/alert
|
local/toast/notification
|
They match the `local/` part, but then they have content after them, and the match fails.
What this change is doing is to switch to what FastRoute and Slim call an 'Unlimited capture'... that is that they keep capturing the identifier, including any other slashes and content to the end of the URI. We do that by usngn the `{identifier:.*}` or `{identifer:.*?}` notation.
So they'll match `local/modal/alert` and `local/toast/notification` as the identifiers.
The difference between the two notations is that the first one is 'greedy' and the second is 'non-greedy'. Basically that means that if we had another Route looking like:
|
/templates/{themename}/{component}/{identifier}
/DELETE
|
Then that route would match before the other variant.