Passed
Push — master ( 438ce3...2f1783 )
by Vitaliy
02:06
created

HttpProtocol   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 11
dl 0
loc 117
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A send() 0 10 2
A closeConnection() 0 4 1
B doSend() 0 24 2
1
<?php
2
3
declare(strict_types = 1);
4
5
/*
6
 * This file is part of the AppleApnPush package
7
 *
8
 * (c) Vitaliy Zhuk <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code
12
 */
13
14
namespace Apple\ApnPush\Protocol;
15
16
use Apple\ApnPush\Encoder\PayloadEncoderInterface;
17
use Apple\ApnPush\Exception\SendNotification\SendNotificationException;
18
use Apple\ApnPush\Model\Notification;
19
use Apple\ApnPush\Model\Receiver;
20
use Apple\ApnPush\Protocol\Http\Authenticator\AuthenticatorInterface;
21
use Apple\ApnPush\Protocol\Http\ExceptionFactory\ExceptionFactoryInterface;
22
use Apple\ApnPush\Protocol\Http\Request;
23
use Apple\ApnPush\Protocol\Http\Sender\Exception\HttpSenderException;
24
use Apple\ApnPush\Protocol\Http\Sender\HttpSenderInterface;
25
use Apple\ApnPush\Protocol\Http\UriFactory\UriFactoryInterface;
26
use Apple\ApnPush\Protocol\Http\Visitor\HttpProtocolVisitorInterface;
27
28
/**
29
 * Implement HTTP protocol for send push notification
30
 */
31
class HttpProtocol implements ProtocolInterface
32
{
33
    /**
34
     * @var AuthenticatorInterface
35
     */
36
    private $authenticator;
37
38
    /**
39
     * @var HttpSenderInterface
40
     */
41
    private $httpSender;
42
43
    /**
44
     * @var PayloadEncoderInterface
45
     */
46
    private $payloadEncoder;
47
48
    /**
49
     * @var UriFactoryInterface
50
     */
51
    private $uriFactory;
52
53
    /**
54
     * @var HttpProtocolVisitorInterface
55
     */
56
    private $visitor;
57
58
    /**
59
     * @var ExceptionFactoryInterface
60
     */
61
    private $exceptionFactory;
62
63
    /**
64
     * Constructor.
65
     *
66
     * @param AuthenticatorInterface       $authenticator
67
     * @param HttpSenderInterface          $httpSender
68
     * @param PayloadEncoderInterface      $payloadEncoder
69
     * @param UriFactoryInterface          $uriFactory
70
     * @param HttpProtocolVisitorInterface $visitor
71
     * @param ExceptionFactoryInterface    $exceptionFactory
72
     */
73
    public function __construct(
74
        AuthenticatorInterface $authenticator,
75
        HttpSenderInterface $httpSender,
76
        PayloadEncoderInterface $payloadEncoder,
77
        UriFactoryInterface $uriFactory,
78
        HttpProtocolVisitorInterface $visitor,
79
        ExceptionFactoryInterface $exceptionFactory
80
    ) {
81
        $this->authenticator = $authenticator;
82
        $this->httpSender = $httpSender;
83
        $this->payloadEncoder = $payloadEncoder;
84
        $this->uriFactory = $uriFactory;
85
        $this->visitor = $visitor;
86
        $this->exceptionFactory = $exceptionFactory;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     *
92
     * @throws HttpSenderException
93
     */
94
    public function send(Receiver $receiver, Notification $notification, bool $sandbox): void
95
    {
96
        try {
97
            $this->doSend($receiver, $notification, $sandbox);
98
        } catch (HttpSenderException $e) {
99
            $this->httpSender->close();
100
101
            throw $e;
102
        }
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function closeConnection(): void
109
    {
110
        $this->httpSender->close();
111
    }
112
113
    /**
114
     * Inner send process
115
     *
116
     * @param Receiver     $receiver
117
     * @param Notification $notification
118
     * @param bool         $sandbox
119
     *
120
     * @throws SendNotificationException
121
     * @throws HttpSenderException
122
     */
123
    private function doSend(Receiver $receiver, Notification $notification, bool $sandbox): void
124
    {
125
        $payloadEncoded = $this->payloadEncoder->encode($notification->getPayload());
126
        $uri = $this->uriFactory->create($receiver->getToken(), $sandbox);
127
128
        $request = new Request($uri, $payloadEncoded);
129
130
        $headers = [
131
            'content-type' => 'application/json',
132
            'accept'       => 'application/json',
133
            'apns-topic'   => $receiver->getTopic(),
134
        ];
135
136
        $request = $request->withHeaders($headers);
137
        $request = $this->authenticator->authenticate($request);
138
139
        $request = $this->visitor->visit($notification, $request);
140
141
        $response = $this->httpSender->send($request);
142
143
        if ($response->getStatusCode() !== 200) {
144
            throw $this->exceptionFactory->create($response);
145
        }
146
    }
147
}
148