Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
"autoload": {
"psr-4": {
"ApiClients\\Foundation\\Middleware\\": "src/"
}
},
"files": [
"src/bootstrap.php"
]
},
"autoload-dev": {
"psr-4": {
Expand Down
20 changes: 20 additions & 0 deletions src/Annotation/Early.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class Early implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::EARLY;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/First.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class First implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::FIRST;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/Last.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class Last implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::LAST;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/Late.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class Late implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::LATE;
}
}
2 changes: 1 addition & 1 deletion src/Annotation/Priority.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @Annotation
* @Target({"METHOD"})
*/
final class Priority
final class Priority implements PriorityInterface
{
/**
* @var int
Expand Down
11 changes: 11 additions & 0 deletions src/Annotation/PriorityInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

interface PriorityInterface
{
/**
* @return int
*/
public function priority(): int;
}
20 changes: 20 additions & 0 deletions src/Annotation/Second.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class Second implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::SECOND;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/SecondLast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class SecondLast implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::SECOND_LAST;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/Third.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class Third implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::THIRD;
}
}
20 changes: 20 additions & 0 deletions src/Annotation/ThirdLast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace ApiClients\Foundation\Middleware\Annotation;

use ApiClients\Foundation\Middleware\Priority as MiddlewarePriority;

/**
* @Annotation
* @Target({"METHOD"})
*/
final class ThirdLast implements PriorityInterface
{
/**
* @return int
*/
public function priority(): int
{
return MiddlewarePriority::THIRD_LAST;
}
}
13 changes: 7 additions & 6 deletions src/MiddlewareRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace ApiClients\Foundation\Middleware;

use ApiClients\Foundation\Middleware\Annotation\Priority as PriorityAnnotation;
use ApiClients\Foundation\Middleware\Annotation\PriorityInterface;
use Doctrine\Common\Annotations\AnnotationReader;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -132,12 +132,13 @@ protected function orderMiddlewares(string $method, MiddlewareInterface ...$midd
private function getPriority(string $method, MiddlewareInterface $middleware): int
{
$methodReflection = new ReflectionMethod($middleware, $method);
/** @var PriorityAnnotation $annotation */
$annotation = $this->annotationReader->getMethodAnnotation($methodReflection, PriorityAnnotation::class);
$annotations = $this->annotationReader->getMethodAnnotations($methodReflection);

foreach ($annotations as $annotation) {
if (!is_subclass_of($annotation, PriorityInterface::class)) {
continue;
}

if ($annotation !== null &&
get_class($annotation) === PriorityAnnotation::class
) {
return $annotation->priority();
}

Expand Down
8 changes: 7 additions & 1 deletion tests/MiddlewareRunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use ApiClients\Foundation\Middleware\MiddlewareInterface;
use ApiClients\Foundation\Middleware\MiddlewareRunner;
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\OneMiddleware;
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\ThreeMiddleware;
use ApiClients\Tests\Foundation\Middleware\TestMiddlewares\TwoMiddleware;
use ApiClients\Tools\TestUtilities\TestCase;
use Closure;
Expand Down Expand Up @@ -89,11 +90,13 @@ public function testAnnotations()

$middlewareOne = new OneMiddleware();
$middlewareTwo = new TwoMiddleware();
$middlewareThree = new ThreeMiddleware();

$args = [
$options,
$middlewareOne,
$middlewareTwo,
$middlewareThree,
];

$executioner = new MiddlewareRunner(...$args);
Expand All @@ -105,15 +108,18 @@ public function testAnnotations()
self::assertSame($exception, $throwable);
}

$calls = array_merge_recursive($middlewareOne->getCalls(), $middlewareTwo->getCalls());
$calls = array_merge_recursive($middlewareOne->getCalls(), $middlewareTwo->getCalls(), $middlewareThree->getCalls());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line exceeds 120 characters; contains 125 characters

ksort($calls);

self::assertSame([
ThreeMiddleware::class . ':pre',
TwoMiddleware::class . ':pre',
OneMiddleware::class . ':pre',
OneMiddleware::class . ':post',
TwoMiddleware::class . ':post',
ThreeMiddleware::class . ':post',
OneMiddleware::class . ':error',
ThreeMiddleware::class . ':error',
TwoMiddleware::class . ':error',
], array_values($calls));
}
Expand Down
81 changes: 81 additions & 0 deletions tests/TestMiddlewares/ThreeMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php declare(strict_types=1);

namespace ApiClients\Tests\Foundation\Middleware\TestMiddlewares;

use ApiClients\Foundation\Middleware\Annotation\Early;
use ApiClients\Foundation\Middleware\Annotation\First;
use ApiClients\Foundation\Middleware\Annotation\Late;
use ApiClients\Foundation\Middleware\DefaultPriorityTrait;
use ApiClients\Foundation\Middleware\MiddlewareInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use React\Promise\CancellablePromiseInterface;
use Throwable;
use function React\Promise\reject;
use function React\Promise\resolve;

class ThreeMiddleware implements MiddlewareInterface
{
use DefaultPriorityTrait;

private $calls = [];

/**
* @return array
*/
public function getCalls(): array
{
return $this->calls;
}

/**
* @param RequestInterface $request
* @param array $options
* @return CancellablePromiseInterface
* @First()
*/
public function pre(
RequestInterface $request,
array $options = [],
string $transactionId = null
): CancellablePromiseInterface {
usleep(100);
$this->calls[(string)microtime(true)] = __CLASS__ . ':pre';

return resolve($request);
}

/**
* @param ResponseInterface $response
* @param array $options
* @return CancellablePromiseInterface
* @Late()
*/
public function post(
ResponseInterface $response,
array $options = [],
string $transactionId = null
): CancellablePromiseInterface {
usleep(100);
$this->calls[(string)microtime(true)] = __CLASS__ . ':post';

return resolve($response);
}

/**
* @param Throwable $throwable
* @param array $options
* @return CancellablePromiseInterface
* @Early()
*/
public function error(
Throwable $throwable,
array $options = [],
string $transactionId = null
): CancellablePromiseInterface {
usleep(100);
$this->calls[(string)microtime(true)] = __CLASS__ . ':error';

return reject($throwable);
}
}