StreamAdapter::promise()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * This file is part of GitterApi package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Gitter\Adapters;
11
12
use Clue\React\Buzz\Browser;
13
use Gitter\Client;
14
use Gitter\Route;
15
use Gitter\Support\JsonStream;
16
use Gitter\Support\Observer;
17
use Psr\Http\Message\ResponseInterface;
18
use React\EventLoop\ExtEventLoop;
19
use React\EventLoop\LibEventLoop;
20
use React\EventLoop\LibEvLoop;
21
use React\EventLoop\LoopInterface;
22
use React\EventLoop\StreamSelectLoop;
23
use React\Promise\Promise;
24
use React\Stream\ReadableStreamInterface;
25
26
/**
27
 * Class HttpAdapter
28
 * @package Gitter\Adapters
29
 */
30
class StreamAdapter extends AbstractClient implements StreamAdapterInterface
31
{
32
    /**
33
     * @var Browser
34
     */
35
    private $browser;
36
37
    /**
38
     * @var ExtEventLoop|LibEventLoop|LibEvLoop|StreamSelectLoop
39
     */
40
    private $loop;
41
42
    /**
43
     * @var Client
44
     */
45
    private $client;
46
47
    /**
48
     * HttpAdapter constructor.
49
     * @param Client $client
50
     * @param LoopInterface $loop
51
     */
52
    public function __construct(Client $client, LoopInterface $loop)
53
    {
54
        $this->client = $client;
55
        $this->loop = $loop;
0 ignored issues
show
Documentation Bug introduced by
It seems like $loop of type object<React\EventLoop\LoopInterface> is incompatible with the declared type object<React\EventLoop\E...tLoop\StreamSelectLoop> of property $loop.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
56
        $this->browser = new Browser($loop);
57
    }
58
59
    /**
60
     * @return LoopInterface
61
     */
62
    public function getEventLoop(): LoopInterface
63
    {
64
        return $this->loop;
65
    }
66
67
    /**
68
     * @param Route $route
69
     * @return Observer
70
     * @throws \InvalidArgumentException
71
     */
72
    public function request(Route $route): Observer
73
    {
74
        $observer = new Observer();
75
76
        $this->promise($route)->then(function (ResponseInterface $response) use ($observer) {
77
            $this->onConnect($response, $observer);
78
        });
79
80
        return $observer;
81
    }
82
83
    /**
84
     * @param Route $route
85
     * @return Promise
86
     * @throws \InvalidArgumentException
87
     */
88
    private function promise(Route $route): Promise
89
    {
90
        list($method, $uri) = [$route->method(), $route->build()];
91
92
        // Log request
93
        $this->debugLog($this->client, ' -> ' . $method . ' ' . $uri);
94
95
        return $this->browser
96
            ->withOptions(['streaming' => true])
97
            ->{strtolower($method)}($route->build(), $this->buildHeaders($this->client));
98
    }
99
100
    /**
101
     * @param ResponseInterface $response
102
     * @param Observer $observer
103
     */
104
    private function onConnect(ResponseInterface $response, Observer $observer)
105
    {
106
        $json = new JsonStream();
107
108
        // Log response
109
        $this->debugLog($this->client, ' <- ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase());
110
111
        /* @var $body ReadableStreamInterface */
112
        $body = $response->getBody();
113
114
        $body->on('data', function ($chunk) use ($json, $observer) {
115
            // Log response chunk
116
            $this->debugLog($this->client, '   <- ' . $chunk);
117
118
            $json->push($chunk, function ($object) use ($observer) {
119
                $observer->fire($object);
120
            });
121
        });
122
    }
123
}
124