Passed
Pull Request — master (#17)
by BENOIT
02:04
created

SubscriptionsController   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 53
rs 10
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 36 2
A matchRequest() 0 3 1
A __construct() 0 4 1
1
<?php
2
3
namespace BenTools\MercurePHP\Controller;
4
5
use BenTools\MercurePHP\Hub\Hub;
6
use BenTools\MercurePHP\Security\Authenticator;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use React\Http\Message\Response;
11
use React\Stream\ThroughStream;
12
13
use function BenTools\MercurePHP\nullify;
14
15
final class SubscriptionsController extends AbstractController
16
{
17
    private const PATH = '/.well-known/mercure/subscriptions';
18
    private Hub $hub;
19
    private Authenticator $authenticator;
20
21
    public function __construct(Hub $hub, Authenticator $authenticator)
22
    {
23
        $this->hub = $hub;
24
        $this->authenticator = $authenticator;
25
    }
26
27
    public function __invoke(ServerRequestInterface $request): ResponseInterface
28
    {
29
        if (!\in_array($request->getMethod(), ['GET', 'HEAD', 'OPTIONS'])) {
30
            return new Response(405);
31
        }
32
33
        $path = $request->getUri()->getPath();
34
        $filters = \explode('/', \trim(\strtr($path, [self::PATH => '']), '/'), 2);
35
        $subscriber = nullify($filters[0]);
36
        $topic = nullify($filters[1] ?? null);
37
38
        $stream = new ThroughStream();
39
        $this->hub->hook(
40
            function () use ($stream, $path, $subscriber, $topic) {
41
                $this->hub->getActiveSubscriptions($subscriber, $topic)
42
                    ->then(
43
                        function (iterable $subscriptions) use ($stream, $path) {
44
                            $result = [
45
                                '@context' => 'https://mercure.rocks/',
46
                                'id' => $path,
47
                                'type' => 'Subscriptions',
48
                                'subscriptions' => \iterable_to_array($subscriptions),
49
                            ];
50
                            $stream->write(\json_encode($result, \JSON_THROW_ON_ERROR));
51
                            $stream->end();
52
                            $stream->close();
53
                        }
54
                    );
55
            }
56
        );
57
58
        $headers = [
59
            'Content-Type' => 'application/ld+json',
60
        ];
61
62
        return new Response(200, $headers, $stream);
63
    }
64
65
    public function matchRequest(RequestInterface $request): bool
66
    {
67
        return 0 === \strpos($request->getUri()->getPath(), self::PATH);
68
    }
69
}
70