Completed
Pull Request — master (#63)
by
unknown
01:17
created

Request::addOption()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Pushok package.
5
 *
6
 * (c) Arthur Edamov <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Pushok;
13
14
/**
15
 * Class Request
16
 * @package Pushok
17
 *
18
 * @see http://bit.ly/communicating-with-apns
19
 */
20
class Request
21
{
22
    const APNS_DEVELOPMENT_SERVER = 'https://api.development.push.apple.com';
23
    const APNS_PRODUCTION_SERVER = 'https://api.push.apple.com';
24
    const APNS_PORT = 443;
25
    const APNS_PATH_SCHEMA = '/3/device/{token}';
26
27
    const HEADER_APNS_ID = 'apns-id';
28
    const HEADER_APNS_EXPIRATION = 'apns-expiration';
29
    const HEADER_APNS_PRIORITY = 'apns-priority';
30
    const HEADER_APNS_TOPIC = 'apns-topic';
31
    const HEADER_APNS_COLLAPSE_ID = 'apns-collapse-id';
32
33
    /**
34
     * Request headers.
35
     *
36
     * @var array
37
     */
38
    private $headers = [];
39
40
    /**
41
     * Request uri.
42
     *
43
     * @var string
44
     */
45
    private $uri;
46
47
    /**
48
     * Request body.
49
     *
50
     * @var string
51
     */
52
    private $body;
53
54
    /**
55
     * Curl options.
56
     *
57
     * @var array
58
     */
59
    private $options;
60
61
    public function __construct(Notification $notification, $isProductionEnv)
62
    {
63
        $this->uri = $isProductionEnv ? $this->getProductionUrl($notification) : $this->getSandboxUrl($notification);
64
        $this->body = $notification->getPayload()->toJson();
65
66
        if (!defined('CURL_HTTP_VERSION_2')) {
67
            define('CURL_HTTP_VERSION_2', 3);
68
        }
69
70
        $this->options = [
71
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2,
72
            CURLOPT_URL => $this->uri,
73
            CURLOPT_PORT => self::APNS_PORT,
74
            CURLOPT_POST => true,
75
            CURLOPT_POSTFIELDS => $notification->getPayload()->toJson(),
76
            CURLOPT_RETURNTRANSFER => true,
77
            CURLOPT_TIMEOUT => 10,
78
            CURLOPT_HEADER => true,
79
        ];
80
81
        $this->prepareApnsHeaders($notification);
82
    }
83
84
    /**
85
     * Add request header.
86
     *
87
     * @param string $key
88
     * @param $value
89
     */
90
    public function addHeader(string $key, $value)
91
    {
92
        $this->headers[$key] = $value;
93
    }
94
95
    /**
96
     * Add request headers.
97
     *
98
     * @param array $headers
99
     */
100
    public function addHeaders(array $headers)
101
    {
102
        $this->headers = array_merge($this->headers, $headers);
103
    }
104
105
    /**
106
     * Get request headers.
107
     *
108
     * @return array
109
     */
110
    public function getHeaders(): array
111
    {
112
        return $this->headers;
113
    }
114
115
    /**
116
     * Add request option.
117
     *
118
     * @param string $key
119
     * @param $value
120
     */
121
    public function addOption(string $key, $value)
122
    {
123
        $this->options[$key] = $value;
124
    }
125
126
    /**
127
     * Add request options.
128
     *
129
     * @param array $options
130
     */
131
    public function addOptions(array $options)
132
    {
133
        $this->options = array_merge($this->options, $options);
134
    }
135
136
    /**
137
     * Get request options.
138
     *
139
     * @return array
140
     */
141
    public function getOptions(): array
142
    {
143
        return $this->options;
144
    }
145
146
    /**
147
     * Get decorated request headers.
148
     *
149
     * @return array
150
     */
151
    public function getDecoratedHeaders(): array
152
    {
153
        $decoratedHeaders = [];
154
        foreach ($this->headers as $name => $value) {
155
            $decoratedHeaders[] = $name . ': ' . $value;
156
        }
157
        return $decoratedHeaders;
158
    }
159
160
    /**
161
     * Get request uri.
162
     *
163
     * @return string
164
     */
165
    public function getUri(): string
166
    {
167
        return $this->uri;
168
    }
169
170
    /**
171
     * Get request body.
172
     *
173
     * @return string
174
     */
175
    public function getBody(): string
176
    {
177
        return $this->body;
178
    }
179
180
    /**
181
     * Get Url for APNs production server.
182
     *
183
     * @param Notification $notification
184
     * @return string
185
     */
186
    private function getProductionUrl(Notification $notification)
187
    {
188
        return self::APNS_PRODUCTION_SERVER . $this->getUrlPath($notification);
189
    }
190
191
    /**
192
     * Get Url for APNs sandbox server.
193
     *
194
     * @param Notification $notification
195
     * @return string
196
     */
197
    private function getSandboxUrl(Notification $notification)
198
    {
199
        return self::APNS_DEVELOPMENT_SERVER . $this->getUrlPath($notification);
200
    }
201
202
    /**
203
     * Get Url path.
204
     *
205
     * @param Notification $notification
206
     * @return mixed
207
     */
208
    private function getUrlPath(Notification $notification)
209
    {
210
        return str_replace("{token}", $notification->getDeviceToken(), self::APNS_PATH_SCHEMA);
211
    }
212
213
    /**
214
     * Prepare APNs headers before sending request.
215
     *
216
     * @param Notification $notification
217
     */
218
    private function prepareApnsHeaders(Notification $notification)
219
    {
220
        if (!empty($notification->getId())) {
221
            $this->headers[self::HEADER_APNS_ID] =  $notification->getId();
222
        }
223
224
        if ($notification->getExpirationAt() instanceof \DateTime) {
225
            $this->headers[self::HEADER_APNS_EXPIRATION] = $notification->getExpirationAt()->getTimestamp();
226
        }
227
228
        if (is_int($notification->getPriority())) {
229
            $this->headers[self::HEADER_APNS_PRIORITY] =  $notification->getPriority();
230
        }
231
232
        if (!empty($notification->getCollapseId())) {
233
            $this->headers[self::HEADER_APNS_COLLAPSE_ID ] = $notification->getCollapseId();
234
        }
235
    }
236
}
237