Skip to content

Commit 90df819

Browse files
authored
Merge pull request #11 from php-api-clients/shorthand-priority-annotations
Shorthand priority annotations
2 parents 0237cb6 + 2340f5d commit 90df819

15 files changed

+282
-9
lines changed

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
"autoload": {
3232
"psr-4": {
3333
"ApiClients\\Foundation\\Middleware\\": "src/"
34-
}
34+
},
35+
"files": [
36+
"src/bootstrap.php"
37+
]
3538
},
3639
"autoload-dev": {
3740
"psr-4": {

src/Annotation/Early.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class Early implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::EARLY;
19+
}
20+
}

src/Annotation/First.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class First implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::FIRST;
19+
}
20+
}

src/Annotation/Last.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class Last implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::LAST;
19+
}
20+
}

src/Annotation/Late.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class Late implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::LATE;
19+
}
20+
}

src/Annotation/Priority.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @Annotation
77
* @Target({"METHOD"})
88
*/
9-
final class Priority
9+
final class Priority implements PriorityInterface
1010
{
1111
/**
1212
* @var int

src/Annotation/PriorityInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
interface PriorityInterface
6+
{
7+
/**
8+
* @return int
9+
*/
10+
public function priority(): int;
11+
}

src/Annotation/Second.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class Second implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::SECOND;
19+
}
20+
}

src/Annotation/SecondLast.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class SecondLast implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::SECOND_LAST;
19+
}
20+
}

src/Annotation/Third.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class Third implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::THIRD;
19+
}
20+
}

src/Annotation/ThirdLast.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Foundation\Middleware\Annotation;
4+
5+
use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;
6+
7+
/**
8+
* @Annotation
9+
* @Target({"METHOD"})
10+
*/
11+
final class ThirdLast implements PriorityInterface
12+
{
13+
/**
14+
* @return int
15+
*/
16+
public function priority(): int
17+
{
18+
return MiddlewarePriority::THIRD_LAST;
19+
}
20+
}

src/MiddlewareRunner.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace ApiClients\Foundation\Middleware;
44

5-
use ApiClients\Foundation\Middleware\Annotation\Priority as PriorityAnnotation;
5+
use ApiClients\Foundation\Middleware\Annotation\PriorityInterface;
66
use Doctrine\Common\Annotations\AnnotationReader;
77
use Psr\Http\Message\RequestInterface;
88
use Psr\Http\Message\ResponseInterface;
@@ -132,12 +132,13 @@ protected function orderMiddlewares(string $method, MiddlewareInterface ...$midd
132132
private function getPriority(string $method, MiddlewareInterface $middleware): int
133133
{
134134
$methodReflection = new ReflectionMethod($middleware, $method);
135-
/** @var PriorityAnnotation $annotation */
136-
$annotation = $this->annotationReader->getMethodAnnotation($methodReflection, PriorityAnnotation::class);
135+
$annotations = $this->annotationReader->getMethodAnnotations($methodReflection);
136+
137+
foreach ($annotations as $annotation) {
138+
if (!is_subclass_of($annotation, PriorityInterface::class)) {
139+
continue;
140+
}
137141

138-
if ($annotation !== null &&
139-
get_class($annotation) === PriorityAnnotation::class
140-
) {
141142
return $annotation->priority();
142143
}
143144

src/bootstrap.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types=1);
2+
3+
use Doctrine\Common\Annotations\AnnotationRegistry;
4+
5+
AnnotationRegistry::registerLoader(function (string $class) {
6+
return class_exists($class);
7+
});

tests/MiddlewareRunnerTest.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use ApiClients\Foundation\Middleware\MiddlewareInterface;
66
use ApiClients\Foundation\Middleware\MiddlewareRunner;
77
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\OneMiddleware;
8+
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\ThreeMiddleware;
89
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\TwoMiddleware;
910
use ApiClients\Tools\TestUtilities\TestCase;
1011
use Closure;
@@ -89,11 +90,13 @@ public function testAnnotations()
8990

9091
$middlewareOne = new OneMiddleware();
9192
$middlewareTwo = new TwoMiddleware();
93+
$middlewareThree = new ThreeMiddleware();
9294

9395
$args = [
9496
$options,
9597
$middlewareOne,
9698
$middlewareTwo,
99+
$middlewareThree,
97100
];
98101

99102
$executioner = new MiddlewareRunner(...$args);
@@ -105,15 +108,22 @@ public function testAnnotations()
105108
self::assertSame($exception, $throwable);
106109
}
107110

108-
$calls = array_merge_recursive($middlewareOne->getCalls(), $middlewareTwo->getCalls());
111+
$calls = array_merge_recursive(
112+
$middlewareOne->getCalls(),
113+
$middlewareTwo->getCalls(),
114+
$middlewareThree->getCalls()
115+
);
109116
ksort($calls);
110117

111118
self::assertSame([
119+
ThreeMiddleware::class . ':pre',
112120
TwoMiddleware::class . ':pre',
113121
OneMiddleware::class . ':pre',
114122
OneMiddleware::class . ':post',
115123
TwoMiddleware::class . ':post',
124+
ThreeMiddleware::class . ':post',
116125
OneMiddleware::class . ':error',
126+
ThreeMiddleware::class . ':error',
117127
TwoMiddleware::class . ':error',
118128
], array_values($calls));
119129
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Tests\Foundation\Middleware\TestMiddlewares;
4+
5+
use ApiClients\Foundation\Middleware\Annotation\Early;
6+
use ApiClients\Foundation\Middleware\Annotation\First;
7+
use ApiClients\Foundation\Middleware\Annotation\Late;
8+
use ApiClients\Foundation\Middleware\DefaultPriorityTrait;
9+
use ApiClients\Foundation\Middleware\MiddlewareInterface;
10+
use Psr\Http\Message\RequestInterface;
11+
use Psr\Http\Message\ResponseInterface;
12+
use React\Promise\CancellablePromiseInterface;
13+
use Throwable;
14+
use function React\Promise\reject;
15+
use function React\Promise\resolve;
16+
17+
class ThreeMiddleware implements MiddlewareInterface
18+
{
19+
use DefaultPriorityTrait;
20+
21+
private $calls = [];
22+
23+
/**
24+
* @return array
25+
*/
26+
public function getCalls(): array
27+
{
28+
return $this->calls;
29+
}
30+
31+
/**
32+
* @param RequestInterface $request
33+
* @param array $options
34+
* @return CancellablePromiseInterface
35+
* @First()
36+
*/
37+
public function pre(
38+
RequestInterface $request,
39+
array $options = [],
40+
string $transactionId = null
41+
): CancellablePromiseInterface {
42+
usleep(100);
43+
$this->calls[(string)microtime(true)] = __CLASS__ . ':pre';
44+
45+
return resolve($request);
46+
}
47+
48+
/**
49+
* @param ResponseInterface $response
50+
* @param array $options
51+
* @return CancellablePromiseInterface
52+
* @Late()
53+
*/
54+
public function post(
55+
ResponseInterface $response,
56+
array $options = [],
57+
string $transactionId = null
58+
): CancellablePromiseInterface {
59+
usleep(100);
60+
$this->calls[(string)microtime(true)] = __CLASS__ . ':post';
61+
62+
return resolve($response);
63+
}
64+
65+
/**
66+
* @param Throwable $throwable
67+
* @param array $options
68+
* @return CancellablePromiseInterface
69+
* @Early()
70+
*/
71+
public function error(
72+
Throwable $throwable,
73+
array $options = [],
74+
string $transactionId = null
75+
): CancellablePromiseInterface {
76+
usleep(100);
77+
$this->calls[(string)microtime(true)] = __CLASS__ . ':error';
78+
79+
return reject($throwable);
80+
}
81+
}

0 commit comments

Comments
 (0)