29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-27 07:33:41 +00:00
cms/libraries/src/Router/ApiRouter.php

162 lines
4.3 KiB
PHP
Raw Normal View History

2019-03-07 18:16:06 +00:00
<?php
/**
* Joomla! Content Management System
*
2019-03-09 10:20:38 +00:00
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
2019-03-07 18:16:06 +00:00
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\CMS\Router;
defined('_JEXEC') or die;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Router\Exception\RouteNotFoundException;
use Joomla\Router\Router;
use Joomla\Router\Route;
/**
* Joomla! API Router class
*
2019-03-09 10:20:38 +00:00
* @since 4.0.0
2019-03-07 18:16:06 +00:00
*/
class ApiRouter extends Router
{
/**
* The application object
*
* @type CMSApplicationInterface
2019-03-09 10:20:38 +00:00
* @since 4.0.0
2019-03-07 18:16:06 +00:00
*/
protected $app;
/**
* Constructor.
*
* @param CMSApplicationInterface $app The application object
* @param array $maps An optional array of route maps
*
* @since 1.0
*/
public function __construct(CMSApplicationInterface $app, array $maps = [])
{
$this->app = $app;
parent::__construct($maps);
}
/**
* Creates routes map for CRUD
*
* @param string $baseName The base name of the component.
* @param string $controller The name of the controller that contains CRUD functions.
* @param array $defaults An array of default values that are used when the URL is matched.
* @param bool $publicGets Allow the public to make GET requests.
*
* @return void
*
2019-03-09 10:20:38 +00:00
* @since 4.0.0
2019-03-07 18:16:06 +00:00
*/
public function createCRUDRoutes($baseName, $controller, $defaults = array(), $publicGets = false)
{
$getDefaults = array_merge(array('public' => $publicGets), $defaults);
$routes = array(
new Route(['GET'], $baseName, $controller . '.displayList', [], $getDefaults),
new Route(['GET'], $baseName . '/:id', $controller . '.displayItem', ['id' => '(\d+)'], $getDefaults),
new Route(['POST'], $baseName, $controller . '.add', [], $defaults),
new Route(['PUT'], $baseName . '/:id', $controller . '.edit', ['id' => '(\d+)'], $defaults),
new Route(['DELETE'], $baseName . '/:id', $controller . '.delete', ['id' => '(\d+)'], $defaults),
);
$this->addRoutes($routes);
}
/**
* Parse the given route and return the name of a controller mapped to the given route.
*
* @param string $method Request method to match. One of GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE or PATCH
*
* @return array An array containing the controller and the matched variables.
*
2019-03-09 10:20:38 +00:00
* @since 4.0.0
2019-03-07 18:16:06 +00:00
* @throws \InvalidArgumentException
*/
public function parseApiRoute($method = 'GET')
{
$method = strtoupper($method);
$validMethods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "PATCH"];
if (!in_array($method, $validMethods))
{
throw new \InvalidArgumentException(sprintf('%s is not a valid HTTP method.', $method));
}
// Get the path from the route and remove and leading or trailing slash.
$uri = \JUri::getInstance();
$path = urldecode($uri->getPath());
/**
* In some environments (e.g. CLI we can't form a valid base URL). In this case we catch the exception thrown
* by URI and set an empty base URI for further work.
* TODO: This should probably be handled better
*/
try
{
$baseUri = \JUri::base(true);
}
catch (\RuntimeException $e)
{
$baseUri = '';
}
// Remove the base URI path.
$path = substr_replace($path, '', 0, strlen($baseUri));
if (!$this->app->get('sef_rewrite'))
{
// Transform the route
if ($path === 'index.php')
{
$path = '';
}
else
{
$path = str_replace('index.php/', '', $path);
}
}
$query = \JUri::getInstance()->getQuery(true);
// Iterate through all of the known routes looking for a match.
foreach ($this->routes as $route)
{
if (in_array($method, $route->getMethods()))
{
if (preg_match($route->getRegex(), ltrim($path, '/'), $matches))
{
// If we have gotten this far then we have a positive match.
$vars = $route->getDefaults();
foreach ($route->getRouteVariables() as $i => $var)
{
$vars[$var] = $matches[$i + 1];
}
$controller = preg_split("/[.]+/", $route->getController());
$vars = array_merge($vars, $query);
return [
'controller' => $controller[0],
'task' => $controller[1],
'vars' => $vars
];
}
}
}
throw new RouteNotFoundException(sprintf('Unable to handle request for route `%s`.', $path));
}
}