ReactPHPWebhook::init()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 16
nc 1
nop 0
dl 0
loc 23
rs 9.7333
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zanzara\UpdateMode;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use React\EventLoop\LoopInterface;
10
use React\Http\Message\Response;
11
use React\Http\Server;
12
use Zanzara\Config;
13
use Zanzara\Context;
14
use Zanzara\Telegram\Telegram;
15
use Zanzara\Telegram\Type\Update;
16
use Zanzara\Telegram\Type\Webhook\WebhookInfo;
17
use Zanzara\Zanzara;
18
use Zanzara\ZanzaraLogger;
19
use Zanzara\ZanzaraMapper;
20
21
/**
22
 *
23
 */
24
class ReactPHPWebhook extends BaseWebhook
25
{
26
27
    /**
28
     * @var Server
29
     */
30
    private $server;
31
32
    public function __construct(ContainerInterface $container, Zanzara $zanzara, Telegram $telegram, Config $config,
33
                                ZanzaraLogger $logger, LoopInterface $loop, ZanzaraMapper $zanzaraMapper)
34
    {
35
        parent::__construct($container, $zanzara, $telegram, $config, $logger, $loop, $zanzaraMapper);
36
        $this->init();
37
    }
38
39
    private function init()
40
    {
41
        $processingUpdate = null;
42
        $server = new Server($this->loop, function (ServerRequestInterface $request) use (&$processingUpdate) {
43
            $token = $this->resolveTokenFromPath($request->getUri()->getPath());
44
            if (!$this->isWebhookAuthorized($token)) {
45
                $this->logger->errorNotAuthorized();
46
                return new Response(403, [], $this->logger->getNotAuthorizedMessage());
47
            }
48
            $json = (string)$request->getBody();
49
            /** @var Update $processingUpdate */
50
            $processingUpdate = $this->zanzaraMapper->mapJson($json, Update::class);
51
            $this->processUpdate($processingUpdate);
52
            return new Response();
53
        });
54
        $server->on('error', function ($e) use (&$processingUpdate) {
55
            $this->logger->errorUpdate($e, $processingUpdate);
56
            $errorHandler = $this->config->getErrorHandler();
57
            if ($errorHandler) {
58
                $errorHandler($e, new Context($processingUpdate, $this->container));
59
            }
60
        });
61
        $this->setServer($server);
62
    }
63
64
    /**
65
     * @inheritDoc
66
     */
67
    public function run()
68
    {
69
        $this->telegram->getWebhookInfo()->then(
70
            function (WebhookInfo $webhookInfo) {
71
                if (!$webhookInfo->getUrl()) {
72
                    $message = "Your bot doesn't have a webhook set, please set one before running Zanzara in webhook" .
73
                        " mode. See https://github.com/badfarm/zanzara/wiki#set-webhook";
74
                    $this->logger->error($message);
75
                    return;
76
                }
77
                $this->startListening();
78
            }
79
        );
80
    }
81
82
    private function startListening()
83
    {
84
        $socket = new \React\Socket\Server($this->config->getServerUri(), $this->loop, $this->config->getServerContext());
85
        $this->server->listen($socket);
86
        $this->logger->logIsListening();
87
    }
88
89
    /**
90
     * @return Server
91
     */
92
    public function getServer(): Server
93
    {
94
        return $this->server;
95
    }
96
97
    /**
98
     * @param Server $server
99
     */
100
    public function setServer(Server $server): void
101
    {
102
        $this->server = $server;
103
    }
104
105
}
106