/**
* Connects a new Route.
*
* Routes are a way of connecting request URLs to objects in your application.
* At their core routes are a set or regular expressions that are used to
* match requests to destinations.
*
* Examples:
*
* ```
* $routes->connect('/:controller/:action/*');
* ```
*
* The first parameter will be used as a controller name while the second is
* used as the action name. The '/*' syntax makes this route greedy in that
* it will match requests like `/posts/index` as well as requests
* like `/posts/edit/1/foo/bar`.
*
* ```
* $routes->connect('/home-page', ['controller' => 'Pages', 'action' => 'display', 'home']);
* ```
*
* The above shows the use of route parameter defaults. And providing routing
* parameters for a static route.
*
* ```
* $routes->connect(
* '/:lang/:controller/:action/:id',
* [],
* ['id' => '[0-9]+', 'lang' => '[a-z]{3}']
* );
* ```
*
* Shows connecting a route with custom route parameters as well as
* providing patterns for those parameters. Patterns for routing parameters
* do not need capturing groups, as one will be added for each route params.
*
* $options offers several 'special' keys that have special meaning
* in the $options array.
*
* - `pass` is used to define which of the routed parameters should be shifted
* into the pass array. Adding a parameter to pass will remove it from the
* regular route array. Ex. `'pass' => ['slug']`.
* - `routeClass` is used to extend and change how individual routes parse requests
* and handle reverse routing, via a custom routing class.
* Ex. `'routeClass' => 'SlugRoute'`
* - `persist` is used to define which route parameters should be automatically
* included when generating new URLs. You can override persistent parameters
* by redefining them in a URL or remove them by setting the parameter to `false`.
* Ex. `'persist' => ['lang']`
* - `_name` is used to define a specific name for routes. This can be used to optimize
* reverse routing lookups. If undefined a name will be generated for each
* connected route.
* - `_ext` is an array of filename extensions that will be parsed out of the url if present.
* See {@link ScopedRouteCollection::extensions()}.
* - `_method` Only match requests with specific HTTP verbs.
*
* Example of using the `_method` condition:
*
* ```
* $routes->connect('/tasks', ['controller' => 'Tasks', 'action' => 'index', '_method' => 'GET']);
* ```
*
* The above route will only be matched for GET requests. POST requests will fail to match this route.
*
* @param string $route A string describing the template of the route
* @param array $defaults An array describing the default route parameters. These parameters will be used by default
* and can supply routing parameters that are not dynamic. See above.
* @param array $options An array matching the named elements in the route to regular expressions which that
* element should match. Also contains additional parameters such as which routed parameters should be
* shifted into the passed arguments, supplying patterns for routing parameters and supplying the name of a
* custom routing class.
* @return void
* @throws \InvalidArgumentException
* @throws \BadMethodCallException
*/
public function connect($route, array $defaults = [], array $options = [])
{
if (empty($options['action'])) {
$defaults += ['action' => 'index'];
}
if (empty($options['_ext'])) {
$options['_ext'] = $this->_extensions;
}
if (empty($options['routeClass'])) {
$options['routeClass'] = $this->_routeClass;
}
$route = $this->_makeRoute($route, $defaults, $options);
$this->_collection->add($route, $options);
}