Skip to content

Commit 418e55f

Browse files
Koldo Picazakpicaza
authored andcommitted
add missing pieces to run antidot with react php
1 parent 4a86b63 commit 418e55f

17 files changed

+679
-50
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
.phpunit.result.cache
1+
/.phpunit.result.cache
22
/composer.lock
33
/coverage
4+
/infection.log
45
/vendor

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
# Antidot Framework Tactician Adapter
1+
# Antidot React Framework
2+
23

composer.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"name": "antidot-fw/tactician",
3-
"description": "Tactician Command bus adapter for Antidot Framework.",
2+
"name": "antidot-fw/react-framework",
3+
"description": "Antidot React Framework",
44
"keywords": [
5-
"psr-11",
6-
"tacticican",
7-
"command-bus"
5+
"psr-15",
6+
"react-php",
7+
"antidot-framework"
88
],
99
"type": "library",
1010
"license": "BSD-2-Clause",
@@ -15,27 +15,28 @@
1515
],
1616
"require": {
1717
"php": "^7.4.3",
18-
"beberlei/assert": "^3.2",
19-
"enqueue/enqueue": "^0.10.1",
18+
"antidot-fw/framework": "^0.1.3",
2019
"psr/container": "^1.0.0",
21-
"psr/event-dispatcher": "^1.0"
20+
"ramsey/uuid": "^4.1",
21+
"react/http": "^1.2"
2222
},
2323
"require-dev": {
24-
"phpro/grumphp": "~0.17",
24+
"clue/block-react": "^1.4",
25+
"infection/infection": "^0.20",
26+
"phpro/grumphp": "^1.0.0",
2527
"phpunit/phpunit": "^8.0 || ^9.0",
26-
"infection/infection": "^0.17",
2728
"squizlabs/php_codesniffer": "^3.4",
2829
"symfony/var-dumper": "^5.1",
29-
"vimeo/psalm": "^3.14"
30+
"vimeo/psalm": "^4.4"
3031
},
3132
"autoload": {
3233
"psr-4": {
33-
"Antidot\\Tactician\\": "src"
34+
"Antidot\\React\\": "src"
3435
}
3536
},
3637
"autoload-dev": {
3738
"psr-4": {
38-
"AntidotTest\\Tactician\\": "test"
39+
"AntidotTest\\React\\": "test"
3940
}
4041
},
4142
"scripts": {
@@ -47,7 +48,7 @@
4748
],
4849
"cs-check": "phpcs src --colors",
4950
"cs-fix": "phpcbf src --colors",
50-
"infection": "infection",
51+
"infection": "XDEBUG_MODE=coverage infection",
5152
"psalm": "psalm",
5253
"test": "phpunit --colors=always"
5354
},

infection.log

Lines changed: 0 additions & 11 deletions
This file was deleted.

phpcs.xml.dist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<ruleset name="Anti.Framework DBAL adapter coding standard">
3-
<description>Anti.Framework DBAL adapter coding standard</description>
2+
<ruleset name="Antidot React Framework coding standard">
3+
<description>Antidot React Framework coding standard</description>
44

55
<!-- display progress -->
66
<arg value="p"/>

phpunit.xml.dist.bak

Lines changed: 0 additions & 17 deletions
This file was deleted.

psalm.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
66
xmlns="https://getpsalm.org/schema/config"
77
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
8+
autoloader="vendor/autoload.php"
89
>
910
<projectFiles>
1011
<directory name="src" />
@@ -33,7 +34,6 @@
3334
<MissingReturnType errorLevel="info" />
3435
<MissingPropertyType errorLevel="info" />
3536
<InvalidDocblock errorLevel="info" />
36-
<MisplacedRequiredParam errorLevel="info" />
3737

3838
<PropertyNotSetInConstructor errorLevel="info" />
3939
<MissingConstructor errorLevel="info" />
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
<?php
22

3-
namespace Antidot\Tactician\Container\Config;
3+
namespace Antidot\React\Container\Config;
4+
5+
use Antidot\Application\Http\Application;
6+
use Antidot\React\ReactApplicationFactory;
47

58
class ConfigProvider
69
{
710
public function __invoke(): array
811
{
9-
return [];
12+
return [
13+
'dependencies' => [
14+
'factories' => [
15+
Application::class => ReactApplicationFactory::class,
16+
],
17+
]
18+
];
1019
}
1120
}

src/MiddlewarePipeline.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Antidot\React;
6+
7+
use Antidot\Application\Http\Handler\NextHandler;
8+
use Antidot\Application\Http\Middleware\Pipeline;
9+
use Psr\Http\Message\ResponseInterface;
10+
use Psr\Http\Message\ServerRequestInterface;
11+
use Psr\Http\Server\MiddlewareInterface;
12+
use Psr\Http\Server\RequestHandlerInterface;
13+
use Ramsey\Uuid\Uuid;
14+
use SplQueue;
15+
use Throwable;
16+
use function React\Promise\reject;
17+
use function React\Promise\resolve;
18+
19+
class MiddlewarePipeline implements Pipeline
20+
{
21+
/** @var array<SplQueue> */
22+
public array $concurrentPipelines;
23+
/** @var array<MiddlewareInterface> */
24+
private array $middlewareCollection;
25+
26+
/**
27+
* @param array<MiddlewareInterface> $middlewareCollection
28+
* @param array<SplQueue> $concurrentPipelines
29+
*/
30+
public function __construct(
31+
array $middlewareCollection = [],
32+
array $concurrentPipelines = []
33+
) {
34+
$this->concurrentPipelines = $concurrentPipelines;
35+
$this->middlewareCollection = $middlewareCollection;
36+
}
37+
38+
public function pipe(MiddlewareInterface $middleware): void
39+
{
40+
$this->middlewareCollection[] = $middleware;
41+
}
42+
43+
public function handle(ServerRequestInterface $request): ResponseInterface
44+
{
45+
/** @var string $requestId */
46+
$requestId = $request->getAttribute('request_id');
47+
$this->setCurrentPipeline($requestId);
48+
49+
return new PromiseResponse(resolve($request)->then(
50+
function (ServerRequestInterface $request) {
51+
/** @var string $requestId */
52+
$requestId = $request->getAttribute('request_id');
53+
try {
54+
/** @var MiddlewareInterface $middleware */
55+
$middleware = $this->concurrentPipelines[$requestId]->dequeue();
56+
57+
$response = $middleware->process($request, $this);
58+
unset($this->concurrentPipelines[$requestId]);
59+
60+
return resolve($response);
61+
} catch (Throwable $exception) {
62+
unset($this->concurrentPipelines[$requestId]);
63+
64+
return reject($exception);
65+
}
66+
}
67+
));
68+
}
69+
70+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
71+
{
72+
/** @var ?string $requestId */
73+
$requestId = $request->getAttribute('request_id');
74+
if (!$requestId) {
75+
$requestId = Uuid::uuid4()->toString();
76+
$request = $request->withAttribute('request_id', $requestId);
77+
}
78+
$this->setCurrentPipeline($requestId);
79+
80+
return new PromiseResponse(resolve($request)
81+
->then(function (ServerRequestInterface $request) use ($handler) {
82+
/** @var string $requestId */
83+
$requestId = $request->getAttribute('request_id');
84+
try {
85+
/** @var SplQueue<MiddlewareInterface> $queue */
86+
$queue = $this->concurrentPipelines[$requestId];
87+
$next = new NextHandler($queue, $handler);
88+
89+
return resolve($next->handle($request));
90+
} catch (Throwable $exception) {
91+
unset($this->concurrentPipelines[$requestId]);
92+
93+
return reject($exception);
94+
}
95+
}));
96+
}
97+
98+
private function setCurrentPipeline(string $requestId): void
99+
{
100+
if (empty($this->concurrentPipelines[$requestId])) {
101+
$queue = new SplQueue();
102+
foreach ($this->middlewareCollection as $middlewareName) {
103+
$queue->enqueue($middlewareName);
104+
}
105+
$this->concurrentPipelines[$requestId] = $queue;
106+
}
107+
}
108+
}

src/PromiseResponse.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Antidot\React;
6+
7+
use Psr\Http\Message\ResponseInterface;
8+
use React\Promise\PromiseInterface;
9+
use RingCentral\Psr7\Response;
10+
use Throwable;
11+
12+
class PromiseResponse extends Response implements PromiseInterface
13+
{
14+
private PromiseInterface $promise;
15+
protected $stream;
16+
17+
/**
18+
* @param PromiseInterface $promise
19+
* @param mixed $body
20+
* @param int $status
21+
* @param array $headers
22+
*/
23+
public function __construct(
24+
PromiseInterface $promise,
25+
$body = null,
26+
int $status = 200,
27+
array $headers = []
28+
) {
29+
parent::__construct($status, $headers, $body);
30+
$this->promise = $promise;
31+
}
32+
33+
final public function then(
34+
callable $onFulfilled = null,
35+
callable $onRejected = null,
36+
callable $onProgress = null
37+
): PromiseInterface {
38+
return $this->promise->then($onFulfilled, $onRejected, $onProgress);
39+
}
40+
}

0 commit comments

Comments
 (0)