Completed
Pull Request — master (#8)
by Romain
04:20
created

Fcm::_checkDatas()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
namespace ker0x\Push\Adapter\Fcm;
3
4
use Cake\Core\Configure;
5
use Cake\Core\InstanceConfigTrait;
6
use Cake\Utility\Hash;
7
use ker0x\Push\Adapter\Fcm\Message\Data;
8
use ker0x\Push\Adapter\Fcm\Message\Exception\InvalidTokenException;
9
use ker0x\Push\Adapter\Fcm\Message\Notification;
10
use ker0x\Push\Adapter\Fcm\Message\Options;
11
use ker0x\Push\Adapter\InvalidAdapterException;
12
13
class Fcm
14
{
15
16
    use InstanceConfigTrait;
17
18
    /**
19
     * Array for devices's token
20
     *
21
     * @var array
22
     */
23
    protected $tokens = [];
24
25
    /**
26
     * Array for the notification
27
     *
28
     * @var array
29
     */
30
    protected $notification = [];
31
32
    /**
33
     * Array of data
34
     *
35
     * @var array
36
     */
37
    protected $data = [];
38
39
    /**
40
     * Array of request options
41
     *
42
     * @var array
43
     */
44
    protected $options = [];
45
46
    /**
47
     * Array of payload
48
     *
49
     * @var array
50
     */
51
    protected $payload = [];
52
53
    /**
54
     * Response of the request
55
     *
56
     * @var \Cake\Http\Client\Response
57
     */
58
    protected $response;
59
60
    /**
61
     * Default config
62
     *
63
     * @var array
64
     */
65
    protected $_defaultConfig = [
66
        'options' => [
67
            'collapse_key' => null,
68
            'priority' => 'normal',
69
            'dry_run' => false,
70
            'time_to_live' => 0,
71
            'restricted_package_name' => null,
72
        ],
73
        'http' => [],
74
    ];
75
76
    /**
77
     * FcmAdapter constructor.
78
     *
79
     * @throws \ker0x\Push\Adapter\InvalidAdapterException
80
     */
81
    public function __construct()
82
    {
83
        $config = Configure::read('Push.adapters.Fcm');
84
        $this->config($config);
85
86
        if ($this->config('api.key') === null) {
87
            throw InvalidAdapterException::noApiKey();
88
        }
89
    }
90
91
    /**
92
     * Getter for tokens.
93
     *
94
     * @return array
95
     */
96
    public function getTokens()
97
    {
98
        return $this->tokens;
99
    }
100
101
    /**
102
     * Setter for tokens.
103
     *
104
     * @param array $tokens Array of tokens.
105
     * @return $this
106
     */
107
    public function setTokens(array $tokens)
108
    {
109
        $this->_checkTokens($tokens);
110
        $this->tokens = $tokens;
111
112
        return $this;
113
    }
114
115
    /**
116
     * Getter for payload notification.
117
     *
118
     * @return array
119
     */
120
    public function getNotification()
121
    {
122
        return $this->notification;
123
    }
124
125
    /**
126
     * Setter for payload notification.
127
     *
128
     * Authorized keys for the notification are:
129
     *
130
     * - `title` Indicates notification title.
131
     * - `body` Indicates notification body text.
132
     * - `badge` Indicates the badge on the client app home icon. (iOS)
133
     * - `icon` Indicates notification icon. (Android)
134
     * - `sound` Indicates a sound to play when the device receives a notification.
135
     * - `tag` Indicates whether each notification results in a new entry in the
136
     *   notification drawer on Android. (Android)
137
     * - `color` Indicates color of the icon, expressed in #rrggbb format. (Android)
138
     * - `click_action` Indicates the action associated with a user click on the notification.
139
     * - `body_loc_key` Indicates the key to the body string for localization.
140
     * - `body_loc_args` Indicates the string value to replace format specifiers in the
141
     *   body string for localization.
142
     * - `title_loc_key` Indicates the key to the title string for localization.
143
     * - `title_loc_args` Indicates the string value to replace format specifiers in
144
     *   the title string for localization.
145
     *
146
     * @param array|\ker0x\Push\Adapter\Fcm\Message\NotificationBuilder $notification Array of keys for the notification
147
     * @return $this
148
     */
149
    public function setNotification($notification)
150
    {
151
        $this->notification = (new Notification($notification))->build();
152
153
        return $this;
154
    }
155
156
    /**
157
     * Getter for payload data.
158
     *
159
     * @return array
160
     */
161
    public function getData()
162
    {
163
        return $this->data;
164
    }
165
166
    /**
167
     * Setter for payload data.
168
     *
169
     * @param array $data Array of data for the push.
170
     * @return $this
171
     */
172
    public function setData($data)
173
    {
174
        $this->data = (new Data($data))->build();
175
176
        return $this;
177
    }
178
179
    /**
180
     * Getter for payload options
181
     *
182
     * @return array
183
     */
184
    public function getOptions()
185
    {
186
        return $this->options;
187
    }
188
189
    /**
190
     * Setter for payload options.
191
     *
192
     * Authorized keys for options's array are:
193
     *
194
     * - `collapse_key` This parameter identifies a group of messages.
195
     * - `priority` Sets the priority of the message.
196
     * - `content_available` When a notification or message is sent and
197
     *   this is set to true, an inactive client app is awoken.
198
     * - `time_to_live` This parameter specifies how long (in seconds)
199
     *   the message should be kept in FCM storage if the device is offline.
200
     * - `restricted_package_name` This parameter specifies the package name
201
     *   of the application where the registration tokens must match in order
202
     *   to receive the message.
203
     * - `dry_run` This parameter, when set to true, allows developers to test
204
     *   a request without actually sending a message.
205
     *
206
     * @param array|\ker0x\Push\Adapter\Fcm\Message\OptionsBuilder $options Options for the push
207
     * @return $this
208
     */
209
    public function setOptions($options)
210
    {
211
        $this->options = (new Options($options))->build();
212
213
        return $this;
214
    }
215
216
    /**
217
     * Getter for payload.
218
     *
219
     * @return array
220
     */
221
    public function getPayload()
222
    {
223
        $notification = $this->getNotification();
224
        if (!empty($notification)) {
225
            $this->payload['notification'] = $notification;
226
        }
227
228
        $data = $this->getData();
229
        if (!empty($data)) {
230
            $this->payload['data'] = $data;
231
        }
232
233
        return $this->payload;
234
    }
235
236
    /**
237
     * Check tokens's array.
238
     *
239
     * @param array $tokens An array of tokens.
240
     * @return void
241
     * @throws \ker0x\Push\Adapter\Fcm\Message\Exception\InvalidTokenException
242
     */
243
    private function _checkTokens($tokens)
244
    {
245
        if (empty($tokens) || count($tokens) > 1000) {
246
            throw new InvalidTokenException("Array must contain at least 1 and at most 1000 tokens.");
247
        }
248
    }
249
250
    /**
251
     * Build the message.
252
     *
253
     * @return string
254
     */
255
    protected function _getMessage()
256
    {
257
        $tokens = $this->getTokens();
258
        $message = (count($tokens) > 1) ? ['registration_ids' => $tokens] : ['to' => current($tokens)];
259
260
        $payload = $this->getPayload();
261
        if (!empty($payload)) {
262
            $message += $payload;
263
        }
264
265
        $options = $this->getOptions();
266
        if (!empty($options)) {
267
            $message += $options;
268
        }
269
270
        return json_encode($message);
271
    }
272
273
    /**
274
     * Return options for the HTTP request.
275
     *
276
     * @return array $options
277
     */
278
    protected function _getHttpOptions()
279
    {
280
        $options = Hash::merge($this->config('http'), [
281
            'type' => 'json',
282
            'headers' => [
283
                'Authorization' => 'key=' . $this->config('api.key'),
284
                'Content-Type' => 'application/json',
285
            ],
286
        ]);
287
288
        return $options;
289
    }
290
}
291