diff --git a/composer.json b/composer.json index 945e88c..c83d3bb 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ }, "autoload": { "psr-4": { - "Ray\\Query\\": "src/" + "Ray\\Query\\": ["src/", "src-deprecated"] } }, "autoload-dev": { diff --git a/demo/2-alias-query.php b/demo/2-query-annotation.php similarity index 100% rename from demo/2-alias-query.php rename to demo/2-query-annotation.php diff --git a/demo/Todo.php b/demo/Todo.php index 013b4d9..3df2c48 100644 --- a/demo/Todo.php +++ b/demo/Todo.php @@ -4,19 +4,19 @@ namespace Ray\Query; -use Ray\Query\Annotation\AliasQuery; +use Ray\Query\Annotation\Query; class Todo { /** - * @AliasQuery("todo_item_by_id") + * @Query("todo_item_by_id") */ public function get(string $id) { } /** - * @AliasQuery(id="todo_insert?id={uuid}", templated=true) + * @Query(id="todo_insert?id={uuid}", templated=true) */ public function create(string $uuid, string $title) { diff --git a/demo/run.php b/demo/run.php index f722a17..84a705d 100644 --- a/demo/run.php +++ b/demo/run.php @@ -4,4 +4,4 @@ passthru('php ' . __DIR__ . '/0-manual-injection.php'); passthru('php ' . __DIR__ . '/1-constructor-injection.php'); -passthru('php ' . __DIR__ . '/2-alias-query.php'); +passthru('php ' . __DIR__ . '/2-query-annotation.php'); diff --git a/src/Annotation/AliasQuery.php b/src-deprecated/AliasQuery.php similarity index 92% rename from src/Annotation/AliasQuery.php rename to src-deprecated/AliasQuery.php index c064fd8..34520bb 100644 --- a/src/Annotation/AliasQuery.php +++ b/src-deprecated/AliasQuery.php @@ -9,6 +9,8 @@ * * @Annotation * @Target("METHOD") + * + * @deprecated use MapQuery instead */ final class AliasQuery { diff --git a/src/SqlAliasInterceptor.php b/src-deprecated/SqlAliasInterceptor.php similarity index 97% rename from src/SqlAliasInterceptor.php rename to src-deprecated/SqlAliasInterceptor.php index a46b8fb..8132ce8 100644 --- a/src/SqlAliasInterceptor.php +++ b/src-deprecated/SqlAliasInterceptor.php @@ -11,6 +11,9 @@ use Ray\Di\InjectorInterface; use Ray\Query\Annotation\AliasQuery; +/** + * @deprecated use MapQueryInterceptor instead + */ class SqlAliasInterceptor implements MethodInterceptor { /** diff --git a/src/Annotation/Query.php b/src/Annotation/Query.php new file mode 100644 index 0000000..f372ba0 --- /dev/null +++ b/src/Annotation/Query.php @@ -0,0 +1,35 @@ +injector = $injector; + } + + public function invoke(MethodInvocation $invocation) + { + /** @var ReflectionMethod $method */ + $method = $invocation->getMethod(); + /** @var Query $query */ + $query = $method->getAnnotation(Query::class); + $namedArguments = (array) $invocation->getNamedArguments(); + list($queryId, $params) = $query->templated ? $this->templated($query, $namedArguments) : [$query->id, $namedArguments]; + $interface = $query->type === 'row' ? RowInterface::class : RowListInterface::class; + $query = $this->injector->getInstance($interface, $queryId); + if ($query instanceof QueryInterface) { + return $this->getQueryResult($invocation, $query, $params); + } + + return $invocation->proceed(); + } + + private function getQueryResult(MethodInvocation $invocation, QueryInterface $query, array $param) + { + $result = $query($param); + $object = $invocation->getThis(); + if ($object instanceof ResourceObject) { + return $this->returnRo($object, $invocation, $result); + } + + return $result; + } + + private function returnRo(ResourceObject $ro, MethodInvocation $invocation, $result) : ResourceObject + { + if (! $result) { + return $this->return404($ro); + } + $ro->body = $result; + + return $invocation->proceed(); + } + + private function return404(ResourceObject $ro) : ResourceObject + { + $ro->code = 404; + $ro->body = []; + + return $ro; + } + + private function templated(Query $query, array $namedArguments) : array + { + $url = parse_url(uri_template($query->id, $namedArguments)); + if (! $url) { + throw new \InvalidArgumentException($query->id); + } + $queryId = $url['path']; + isset($url['query']) ? parse_str($url['query'], $params) : $params = $namedArguments; + + return [$queryId, $params + $namedArguments]; + } +} diff --git a/src/SqlQueryModule.php b/src/SqlQueryModule.php index 872b584..57cf5d4 100644 --- a/src/SqlQueryModule.php +++ b/src/SqlQueryModule.php @@ -5,7 +5,7 @@ namespace Ray\Query; use Ray\Di\AbstractModule; -use Ray\Query\Annotation\AliasQuery; +use Ray\Query\Annotation\Query; class SqlQueryModule extends AbstractModule { @@ -48,8 +48,13 @@ protected function configure() } $this->bindInterceptor( $this->matcher->any(), - $this->matcher->annotatedWith(AliasQuery::class), - [SqlAliasInterceptor::class] + $this->matcher->annotatedWith(Query::class), + [QueryInterceptor::class] + ); + $this->bindInterceptor( + $this->matcher->any(), + $this->matcher->annotatedWith(Query::class), + [QueryInterceptor::class] ); } diff --git a/tests/Fake/FakeAlias.php b/tests/Fake/FakeAlias.php index fc4b4a8..836f20b 100644 --- a/tests/Fake/FakeAlias.php +++ b/tests/Fake/FakeAlias.php @@ -8,12 +8,12 @@ */ namespace Ray\Query; -use Ray\Query\Annotation\AliasQuery; +use Ray\Query\Annotation\Query; class FakeAlias { /** - * @AliasQuery("todo_item_by_id", type="row") + * @Query("todo_item_by_id", type="row") */ public function get(string $id) { diff --git a/tests/Fake/FakeAliasNamed.php b/tests/Fake/FakeAliasNamed.php index 2483831..d9a5fed 100644 --- a/tests/Fake/FakeAliasNamed.php +++ b/tests/Fake/FakeAliasNamed.php @@ -8,12 +8,12 @@ */ namespace Ray\Query; -use Ray\Query\Annotation\AliasQuery; +use Ray\Query\Annotation\Query; class FakeAliasNamed { /** - * @AliasQuery(id="todo_item_by_id?id={a}", templated=true, type="row") + * @Query(id="todo_item_by_id?id={a}", templated=true, type="row") */ public function get(string $a) {