Skip to content

Commit

Permalink
Merge pull request #77 from utopia-php/feat-multiple-aliases
Browse files Browse the repository at this point in the history
Add support for multiple aliases
  • Loading branch information
TorstenDittmann authored Oct 31, 2022
2 parents 847cfd4 + 37637cb commit 97f64aa
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 61 deletions.
71 changes: 40 additions & 31 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,10 @@ public function getResource(string $name, bool $fresh = false): mixed
throw new Exception('Failed to find resource: "' . $name . '"');
}

$this->resources[$name] = \call_user_func_array(self::$resourcesCallbacks[$name]['callback'],
$this->getResources(self::$resourcesCallbacks[$name]['injections']));
$this->resources[$name] = \call_user_func_array(
self::$resourcesCallbacks[$name]['callback'],
$this->getResources(self::$resourcesCallbacks[$name]['injections'])
);
}

self::$resourcesCallbacks[$name]['reset'] = false;
Expand Down Expand Up @@ -431,7 +433,7 @@ public function setRoute(Route $route): static
*/
public static function addRoute(string $method, string $url): Route
{
if(!array_key_exists($method, self::$routes)) {
if (!array_key_exists($method, self::$routes)) {
throw new Exception("Invalid Request Method");
}
$route = new Route($method, $url);
Expand Down Expand Up @@ -467,7 +469,7 @@ public function match(Request $request, bool $fresh = false): ?Route
}

foreach (self::$routes[$method] as $routeUrl => $route) {
/* @var $route Route */
/** @var Route $route */

// convert urls like '/users/:uid/posts/:pid' to regular expression
$regex = '@' . \preg_replace('@:[^/]+@', '([^/]+)', $routeUrl) . '@';
Expand All @@ -480,10 +482,10 @@ public function match(Request $request, bool $fresh = false): ?Route
\array_shift($this->matches);
$this->route = $route;

if($routeUrl == $route->getAliasPath()) {
$this->route->setIsAlias(true);
if (isset($route->getAliases()[$routeUrl])) {
$this->route->setAliasPath($routeUrl);
} else {
$this->route->setIsAlias(false);
$this->route->setAliasPath(null);
}

break;
Expand Down Expand Up @@ -522,7 +524,7 @@ public function execute(Route $route, Request $request): static

if ($route->getHook()) {
foreach (self::$init as $hook) { // Global init hooks
if(in_array('*', $hook->getGroups())) {
if (in_array('*', $hook->getGroups())) {
$arguments = $this->getArguments($hook, $values, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
Expand All @@ -531,7 +533,7 @@ public function execute(Route $route, Request $request): static

foreach ($groups as $group) {
foreach (self::$init as $hook) { // Group init hooks
if(in_array($group, $hook->getGroups())) {
if (in_array($group, $hook->getGroups())) {
$arguments = $this->getArguments($hook, $values, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
Expand All @@ -541,7 +543,7 @@ public function execute(Route $route, Request $request): static
$arguments = $this->getArguments($route, $values, $request->getParams());

// Call the callback with the matched positions as params
if($route->getIsActive()){
if ($route->getIsActive()) {
\call_user_func_array($route->getAction(), $arguments);
}

Expand All @@ -550,7 +552,7 @@ public function execute(Route $route, Request $request): static
foreach ($groups as $group) {
foreach (self::$shutdown as $hook) { // Group shutdown hooks
/** @var Hook $hook */
if(in_array($group, $hook->getGroups())) {
if (in_array($group, $hook->getGroups())) {
$arguments = $this->getArguments($hook, $values, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
Expand All @@ -560,7 +562,7 @@ public function execute(Route $route, Request $request): static
if ($route->getHook()) {
foreach (self::$shutdown as $hook) { // Group shutdown hooks
/** @var Hook $hook */
if(in_array('*', $hook->getGroups())) {
if (in_array('*', $hook->getGroups())) {
$arguments = $this->getArguments($hook, $values, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
Expand All @@ -570,7 +572,7 @@ public function execute(Route $route, Request $request): static
foreach ($groups as $group) {
foreach (self::$errors as $error) { // Group error hooks
/** @var Hook $error */
if(in_array($group, $error->getGroups())) {
if (in_array($group, $error->getGroups())) {
self::setResource('error', fn () => $e);
try {
$arguments = $this->getArguments($error, $values, $request->getParams());
Expand All @@ -584,8 +586,8 @@ public function execute(Route $route, Request $request): static

foreach (self::$errors as $error) { // Global error hooks
/** @var Hook $error */
if(in_array('*', $error->getGroups())) {
self::setResource('error', fn() => $e);
if (in_array('*', $error->getGroups())) {
self::setResource('error', fn () => $e);
try {
$arguments = $this->getArguments($error, $values, $request->getParams());
\call_user_func_array($error->getAction(), $arguments);
Expand Down Expand Up @@ -615,9 +617,9 @@ protected function getArguments(Hook $hook, array $values, array $requestParams)
$arg = (isset($requestParams[$key])) ? $requestParams[$key] : $param['default'];
$value = (isset($values[$key])) ? $values[$key] : $arg;

if($hook instanceof Route) {
if($hook->getIsAlias() && isset($hook->getAliasParams()[$key])) {
$value = $hook->getAliasParams()[$key];
if ($hook instanceof Route) {
if ($hook->getIsAlias() && isset($hook->getAliasParams($hook->getAliasPath())[$key])) {
$value = $hook->getAliasParams($hook->getAliasPath())[$key];
}
}

Expand Down Expand Up @@ -646,11 +648,11 @@ protected function getArguments(Hook $hook, array $values, array $requestParams)
*/
public function run(Request $request, Response $response): static
{
self::setResource('request', function() use ($request) {
self::setResource('request', function () use ($request) {
return $request;
});

self::setResource('response', function() use ($response) {
self::setResource('response', function () use ($response) {
return $response;
});

Expand All @@ -663,8 +665,9 @@ public function run(Request $request, Response $response): static
if (!self::$sorted) {
foreach (self::$routes as $method => $list) { //adding route alias in $routes
foreach ($list as $key => $route) {
if($route->getAliasPath()) {
self::$routes[$method][$route->getAliasPath()] = $route;
/** @var Route $route */
foreach (array_keys($route->getAliases()) as $path) {
self::$routes[$method][$path] = $route;
}
}
}
Expand All @@ -676,7 +679,7 @@ public function run(Request $request, Response $response): static
\uksort(self::$routes[$method], function (string $a, string $b) {
$result = \count(\explode('/', $b)) - \count(\explode('/', $a));

if($result === 0) {
if ($result === 0) {
return \substr_count($a, ':') - \substr_count($b, ':');
}

Expand All @@ -703,23 +706,23 @@ public function run(Request $request, Response $response): static
foreach ($groups as $group) {
foreach (self::$options as $option) { // Group options hooks
/** @var Hook $option */
if(in_array($group, $option->getGroups())) {
if (in_array($group, $option->getGroups())) {
\call_user_func_array($option->getAction(), $this->getArguments($option, [], $request->getParams()));
}
}
}

foreach (self::$options as $option) { // Global options hooks
/** @var Hook $option */
if(in_array('*', $option->getGroups())) {
if (in_array('*', $option->getGroups())) {
\call_user_func_array($option->getAction(), $this->getArguments($option, [], $request->getParams()));
}
}
} catch (\Throwable $e) {
foreach (self::$errors as $error) { // Global error hooks
/** @var Hook $error */
if(in_array('*', $error->getGroups())) {
self::setResource('error', function() use ($e) {
if (in_array('*', $error->getGroups())) {
self::setResource('error', function () use ($e) {
return $e;
});
\call_user_func_array($error->getAction(), $this->getArguments($error, [], $request->getParams()));
Expand All @@ -728,8 +731,8 @@ public function run(Request $request, Response $response): static
}
} else {
foreach (self::$errors as $error) { // Global error hooks
if(in_array('*', $error->getGroups())) {
self::setResource('error', function() {
if (in_array('*', $error->getGroups())) {
self::setResource('error', function () {
return new Exception('Not Found', 404);
});
\call_user_func_array($error->getAction(), $this->getArguments($error, [], $request->getParams()));
Expand Down Expand Up @@ -768,7 +771,7 @@ protected function validate(string $key, array $param, mixed $value): void
}

if (!$validator->isValid($value)) {
throw new Exception('Invalid ' .$key . ': ' . $validator->getDescription(), 400);
throw new Exception('Invalid ' . $key . ': ' . $validator->getDescription(), 400);
}
} elseif (!$param['optional']) {
throw new Exception('Param "' . $key . '" is not optional.', 400);
Expand All @@ -787,6 +790,12 @@ public static function reset(): void
self::$shutdown = [];
self::$options = [];
self::$sorted = false;
self::$routes = [
self::REQUEST_METHOD_GET => [],
self::REQUEST_METHOD_POST => [],
self::REQUEST_METHOD_PUT => [],
self::REQUEST_METHOD_PATCH => [],
self::REQUEST_METHOD_DELETE => [],
];
}

}
65 changes: 55 additions & 10 deletions src/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ class Route extends Hook
/**
* Alias path
*
* @var string
* @var null|string
*/
protected string $aliasPath = '';
protected ?string $aliasPath = null;

/**
* Alias Params
* Array of aliases where key is the path and value is an array of params
*
* @var array
*/
protected array $aliasParams = [];
protected array $aliases = [];

/**
* Is Alias Route?
Expand Down Expand Up @@ -73,7 +73,8 @@ public function __construct(string $method, string $path)
$this->path($path);
$this->method = $method;
$this->order = self::$counter;
$this->action = function (): void {};
$this->action = function (): void {
};
}

/**
Expand All @@ -98,8 +99,7 @@ public function path(string $path): static
*/
public function alias(string $path, array $params = []): static
{
$this->aliasPath = $path;
$this->aliasParams = $params;
$this->aliases[$path] = $params;

return $this;
}
Expand Down Expand Up @@ -172,24 +172,69 @@ public function getPath(): string
return $this->path;
}

/**
* Get Aliases
*
* Returns an array where the keys are paths and values are params
*
* @return array
*/
public function getAliases(): array
{
return $this->aliases;
}

/**
* Get Alias path
*
* For backwards compatibility, returns the first alias path
*
* @return string
*/
public function getAliasPath(): string
{
return $this->aliasPath;
if ($this->aliasPath !== null) {
return $this->aliasPath;
}

$paths = array_keys($this->aliases);
if (count($paths) === 0) {
return '';
}
return $paths[0];
}

/**
* Set Alias path
*
* For backwards compatibility, returns the first alias path
*
* @return void
*/
public function setAliasPath(?string $path): void
{
$this->aliasPath = $path;
$this->setIsAlias($path !== null);
}

/**
* Get Alias Params
*
* For backwards compatibility, returns the first alias params if no path passed
*
* @return array
*/
public function getAliasParams(): array
public function getAliasParams(string $path = null): array
{
return $this->aliasParams;
if ($path === null) {
$params = array_values($this->aliases);
if (count($params) === 0) {
return [];
}
return $params[0];
}

return $this->aliases[$path];
}

/**
Expand Down
Loading

0 comments on commit 97f64aa

Please sign in to comment.