This commit is contained in:
2023-04-19 12:35:39 +08:00
parent a16bb3a19c
commit aa8fb228cc
12 changed files with 151 additions and 55 deletions
-18
View File
@@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Kiri\Router\Annotate;
#[\Attribute(\Attribute::TARGET_METHOD)]
class Aspect
{
/**
* @param string $aspect
*/
public function __construct(readonly public string $aspect)
{
}
}
+4 -3
View File
@@ -18,12 +18,11 @@ class Delete extends AbstractRequestMethod implements InjectRouteInterface
/** /**
* @param string $path * @param string $path
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
/** /**
* @param object $class * @param object $class
* @param string $method * @param string $method
@@ -34,7 +33,9 @@ class Delete extends AbstractRequestMethod implements InjectRouteInterface
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_DELETE, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_DELETE, $path, [$class, $method]);
} }
+5 -5
View File
@@ -14,28 +14,28 @@ class Get extends AbstractRequestMethod implements InjectRouteInterface
{ {
/** /**
* @param string $path * @param string $path
* @param string $version
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
/** /**
* @param object $class * @param object $class
* @param string $method * @param string $method
* @return void * @return void
* @throws ReflectionException * @throws ReflectionException
* @throws Exception * @throws Exception
* @throws ReflectionException
*/ */
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_GET, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_GET, $path, [$class, $method]);
} }
} }
+4 -3
View File
@@ -19,12 +19,11 @@ class Head extends AbstractRequestMethod implements InjectRouteInterface
/** /**
* @param string $path * @param string $path
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
/** /**
* @param object $class * @param object $class
* @param string $method * @param string $method
@@ -35,7 +34,9 @@ class Head extends AbstractRequestMethod implements InjectRouteInterface
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_HEAD, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_HEAD, $path, [$class, $method]);
} }
+4 -3
View File
@@ -19,12 +19,11 @@ class Options extends AbstractRequestMethod implements InjectRouteInterface
/** /**
* @param string $path * @param string $path
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
/** /**
* @param object $class * @param object $class
* @param string $method * @param string $method
@@ -35,7 +34,9 @@ class Options extends AbstractRequestMethod implements InjectRouteInterface
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_OPTIONS, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_OPTIONS, $path, [$class, $method]);
} }
+5 -4
View File
@@ -14,12 +14,11 @@ class Post extends AbstractRequestMethod implements InjectRouteInterface
{ {
/** /**
* @param string $path * @param string $path
* @param string $version
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
@@ -34,7 +33,9 @@ class Post extends AbstractRequestMethod implements InjectRouteInterface
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_POST, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_POST, $path, [$class, $method]);
} }
+4 -2
View File
@@ -19,7 +19,7 @@ class Put extends AbstractRequestMethod implements InjectRouteInterface
/** /**
* @param string $path * @param string $path
*/ */
public function __construct(readonly public string $path) public function __construct(readonly public string $path, readonly public string $version = 'v1')
{ {
} }
@@ -34,7 +34,9 @@ class Put extends AbstractRequestMethod implements InjectRouteInterface
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute(RequestMethod::REQUEST_PUT, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute(RequestMethod::REQUEST_PUT, $path, [$class, $method]);
} }
} }
+6 -3
View File
@@ -5,6 +5,7 @@ namespace Kiri\Router\Annotate;
use Kiri\Router\Constrict\RequestMethod; use Kiri\Router\Constrict\RequestMethod;
use Kiri\Router\Interface\InjectRouteInterface; use Kiri\Router\Interface\InjectRouteInterface;
use Kiri\Router\Router; use Kiri\Router\Router;
use ReflectionException;
#[\Attribute(\Attribute::TARGET_METHOD)] #[\Attribute(\Attribute::TARGET_METHOD)]
class Route extends AbstractRequestMethod implements InjectRouteInterface class Route extends AbstractRequestMethod implements InjectRouteInterface
@@ -15,7 +16,7 @@ class Route extends AbstractRequestMethod implements InjectRouteInterface
* @param string $path * @param string $path
* @param RequestMethod $method * @param RequestMethod $method
*/ */
public function __construct(readonly public string $path, readonly public RequestMethod $method) public function __construct(readonly public string $path, readonly public RequestMethod $method, readonly public string $version = 'v1')
{ {
} }
@@ -24,11 +25,13 @@ class Route extends AbstractRequestMethod implements InjectRouteInterface
* @param object $class * @param object $class
* @param string $method * @param string $method
* @return void * @return void
* @throws \ReflectionException * @throws ReflectionException
*/ */
public function dispatch(object $class, string $method): void public function dispatch(object $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
Router::addRoute($this->method, $this->path, [$class, $method]); $path = $this->version . '/' . ltrim($this->path, '/');
Router::addRoute([$this->method], $path, [$class, $method]);
} }
} }
+67
View File
@@ -0,0 +1,67 @@
<?php
namespace Kiri\Router\Aspect;
use Kiri\Di\Interface\InjectProxyInterface;
use PhpParser\ParserFactory;
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
class Aspect implements InjectProxyInterface
{
/**
* @param array|string $aspect
*/
public function __construct(readonly public array|string $aspect = [])
{
}
/**
* @param string $fileName
* @param object $class
* @param string $method
* @return void
*/
public function dispatch(string $fileName, object $class, string $method): void
{
// TODO: Implement dispatch() method.
try {
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$ast = $parser->parse(file_get_contents($fileName));
$cacheFile = storage('proxy_functions.php');
if (!file_exists($cacheFile)) {
file_put_contents($cacheFile, '<?php' . PHP_EOL);
}
$functionName = str_replace('\\', '_', $class::class) . '_' . $method;
$code = $this->generateClourse($functionName) . PHP_EOL;
file_put_contents($cacheFile, $code, FILE_APPEND);
} catch (\Throwable $throwable) {
die(throwable($throwable));
}
}
private function generateClourse($functionName): string
{
return <<<PHP
if (!function_exists($functionName)) {
/**
* @param mixed \$message
* @param string \$method
* @throws Exception
*/
function $functionName(mixed \$message, string \$method = 'app')
{
}
}
PHP;
}
}
+23 -3
View File
@@ -5,12 +5,13 @@ namespace Kiri\Router\Base;
use Kiri; use Kiri;
use Kiri\Router\Response;
use Kiri\Router\Request;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Kiri\Di\Inject\Service; use Kiri\Di\Inject\Service;
use Kiri\Di\Inject\Container;
use ReflectionException; use ReflectionException;
/** /**
@@ -24,14 +25,14 @@ abstract class Controller
/** /**
* @var Kiri\Router\Request * @var Request
*/ */
#[Service('request')] #[Service('request')]
public RequestInterface $request; public RequestInterface $request;
/** /**
* @var Kiri\Router\Response * @var Response
*/ */
#[Service('response')] #[Service('response')]
public ResponseInterface $response; public ResponseInterface $response;
@@ -67,4 +68,23 @@ abstract class Controller
} }
/**
* @param Request $request
* @return true
*/
public function beforeAction(RequestInterface $request): bool
{
return true;
}
/**
* @param Response $response
* @return void
*/
public function afterAction(ResponseInterface $response): void
{
}
} }
+28 -4
View File
@@ -4,6 +4,9 @@ declare(strict_types=1);
namespace Kiri\Router; namespace Kiri\Router;
use Closure; use Closure;
use Exception;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use ReflectionMethod; use ReflectionMethod;
@@ -32,12 +35,16 @@ class ControllerInterpreter
* @param Closure $method * @param Closure $method
* @return Handler * @return Handler
* @throws ReflectionException * @throws ReflectionException
* @throws Exception
*/ */
public function addRouteByClosure(Closure $method): Handler public function addRouteByClosure(Closure $method): Handler
{ {
$reflection = \Kiri::getDi()->getFunctionParams($method); $reflection = new \ReflectionFunction($method);
if ($reflection->getReturnType()->getName() !== 'Psr\Http\Message\ResponseInterface') {
return new Handler($method, $reflection); throw new Exception('Request Handler returns must implements on Psr\Http\Message\ResponseInterface');
}
$params = \Kiri::getDi()->resolveMethodParams($reflection);
return new Handler($method, $params);
} }
@@ -63,6 +70,7 @@ class ControllerInterpreter
* @param ReflectionClass $reflectionClass * @param ReflectionClass $reflectionClass
* @return Handler * @return Handler
* @throws ReflectionException * @throws ReflectionException
* @throws Exception
*/ */
public function resolveMethod(object $class, string|\ReflectionMethod $reflectionMethod, ReflectionClass $reflectionClass): Handler public function resolveMethod(object $class, string|\ReflectionMethod $reflectionMethod, ReflectionClass $reflectionClass): Handler
{ {
@@ -70,10 +78,26 @@ class ControllerInterpreter
$reflectionMethod = $reflectionClass->getMethod($reflectionMethod); $reflectionMethod = $reflectionClass->getMethod($reflectionMethod);
} }
if ($reflectionMethod->getReturnType()->getName() !== 'Psr\Http\Message\ResponseInterface') {
throw new Exception('Request Handler returns must implements on Psr\Http\Message\ResponseInterface');
}
$container = \Kiri::getDi(); $container = \Kiri::getDi();
$parameters = $container->getMethodParams($reflectionMethod); $parameters = $container->getMethodParams($reflectionMethod);
return new Handler([$class, $reflectionMethod->getName()], $parameters); $method = $reflectionMethod->getName();
$call = static function (RequestInterface $request) use ($class, $method, $parameters) {
/** @var ResponseInterface $response */
$response = \Kiri::service()->get('response');
if (!$class->beforeAction($request)) {
return $response->withStatus(500);
}
$response = call_user_func([$class, $method], $parameters);
$class->afterAction($response);
return $response;
};
return new Handler($call, \Kiri::service()->get('request'));
} }
} }
+1 -7
View File
@@ -62,13 +62,7 @@ class Handler implements RequestHandlerInterface
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface
{ {
// TODO: Implement handle() method. // TODO: Implement handle() method.
$result = call_user_func($this->handler, ...$this->parameter); return call_user_func($this->handler, ...$this->parameter);
if ($result instanceof ResponseInterface) {
return $result;
} else {
$response = \Kiri::getDi()->get(ResponseInterface::class);
return $response->rewrite();
}
} }
} }