/**
* Route the application.
*
* Routing is the process of examining the request environment to determine which
* component should receive the request. The component optional parameters
* are then set in the request object to be processed when the application is being
* dispatched.
*
* @return void
*
* @since 4.0.0
*/
protected function route()
{
$router = $this->getApiRouter();
// Trigger the onBeforeApiRoute event.
PluginHelper::importPlugin('webservices');
$this->triggerEvent('onBeforeApiRoute', array(&$router, $this));
$caught404 = false;
$method = $this->input->getMethod();
try {
$this->handlePreflight($method, $router);
$route = $router->parseApiRoute($method);
} catch (RouteNotFoundException $e) {
$caught404 = true;
}
/**
* Now we have an API perform content negotiation to ensure we have a valid header. Assume if the route doesn't
* tell us otherwise it uses the plain JSON API
*/
$priorities = array('application/vnd.api+json');
if (!$caught404 && \array_key_exists('format', $route['vars'])) {
$priorities = $route['vars']['format'];
}
$negotiator = new Negotiator();
try {
$mediaType = $negotiator->getBest($this->input->server->getString('HTTP_ACCEPT'), $priorities);
} catch (InvalidArgument $e) {
$mediaType = null;
}
// If we can't find a match bail with a 406 - Not Acceptable
if ($mediaType === null) {
throw new Exception\NotAcceptable('Could not match accept header', 406);
}
/** @var $mediaType Accept */
$format = $mediaType->getValue();
if (\array_key_exists($mediaType->getValue(), $this->formatMapper)) {
$format = $this->formatMapper[$mediaType->getValue()];
}
$this->input->set('format', $format);
if ($caught404) {
throw $e;
}
$this->input->set('option', $route['vars']['component']);
$this->input->set('controller', $route['controller']);
$this->input->set('task', $route['task']);
foreach ($route['vars'] as $key => $value) {
if ($key !== 'component') {
if ($this->input->getMethod() === 'POST') {
$this->input->post->set($key, $value);
} else {
$this->input->set($key, $value);
}
}
}
$this->triggerEvent('onAfterApiRoute', array($this));
if (!isset($route['vars']['public']) || $route['vars']['public'] === false) {
if (!$this->login(array('username' => ''), array('silent' => true, 'action' => 'core.login.api'))) {
throw new AuthenticationFailed();
}
}
}