Completed
Push — master ( 613542...020c5c )
by Julián
03:39
created

GcmService::send()   D

Complexity

Conditions 9
Paths 29

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 43
rs 4.909
cc 9
eloc 25
nc 29
nop 1
1
<?php
2
/**
3
 * Push notification services abstraction (http://github.com/juliangut/tify)
4
 *
5
 * @link https://github.com/juliangut/tify for the canonical source repository
6
 *
7
 * @license https://github.com/juliangut/tify/blob/master/LICENSE
8
 */
9
10
namespace Jgut\Tify\Service;
11
12
use Jgut\Tify\Notification\AbstractNotification;
13
use Jgut\Tify\Notification\GcmNotification;
14
use Jgut\Tify\Result;
15
use Jgut\Tify\Service\Client\GcmClientBuilder;
16
use Jgut\Tify\Service\Message\GcmMessageBuilder;
17
use ZendService\Google\Exception\RuntimeException as GcmRuntimeException;
18
19
/**
20
 * Class GcmService
21
 */
22
class GcmService extends AbstractService implements SendInterface
23
{
24
    /**
25
     * Status codes mapping.
26
     *
27
     * @see https://developers.google.com/cloud-messaging/http-server-ref
28
     *
29
     * @var array
30
     */
31
    private static $statusCodes = [
32
        'MissingRegistration' => 'Missing Registration Token',
33
        'InvalidRegistration' => 'Invalid Registration Token',
34
        'NotRegistered' => 'Unregistered Recipient',
35
        'InvalidPackageName' => 'Invalid Package Name',
36
        'MismatchSenderId' => 'Mismatched Sender',
37
        'MessageTooBig' => 'Message Too Big',
38
        'InvalidDataKey' => 'Invalid Data Key',
39
        'InvalidTtl' => 'Invalid Time to Live',
40
        'Unavailable' => 'Timeout',
41
        'InternalServerError' => 'Internal Server Error',
42
        'RecipientMessageRateExceeded' => 'Recipient Message Rate Exceeded',
43
        'TopicsMessageRateExceeded' => 'Topics Message Rate Exceeded',
44
        'UnknownError' => 'Unknown Error',
45
    ];
46
47
    /**
48
     * @var \ZendService\Google\Gcm\Client
49
     */
50
    protected $pushClient;
51
52
    /**
53
     * {@inheritdoc}
54
     *
55
     * @throws \InvalidArgumentException
56
     */
57
    public function send(AbstractNotification $notification)
58
    {
59
        if (!$notification instanceof GcmNotification) {
60
            throw new \InvalidArgumentException('Notification must be an accepted GCM notification');
61
        }
62
63
        $service = $this->getPushService();
64
65
        $results = [];
66
67
        foreach (array_chunk($notification->getTokens(), 100) as $tokensRange) {
68
            $message = GcmMessageBuilder::build($tokensRange, $notification);
69
70
            $time = new \DateTime;
71
72
            try {
73
                $response = $service->send($message)->getResults();
74
75
                foreach ($tokensRange as $token) {
76
                    if (array_key_exists($token, $response) && !array_key_exists('error', $response[$token])) {
77
                        $result = new Result($token, $time);
78
                    } else {
79
                        $errorCode = array_key_exists($token, $response) ? $response[$token]['error'] : 'UnknownError';
80
81
                        $result = new Result(
82
                            $token,
83
                            $time,
84
                            Result::STATUS_ERROR,
85
                            self::$statusCodes[$errorCode]
86
                        );
87
                    }
88
89
                    $results[] = $result;
90
                }
91
            } catch (GcmRuntimeException $exception) {
92
                foreach ($tokensRange as $token) {
93
                    $results[] = new Result($token, $time, Result::STATUS_ERROR, $exception->getMessage());
94
                }
95
            }
96
        }
97
98
        $notification->setStatus(AbstractNotification::STATUS_SENT, $results);
99
    }
100
101
    /**
102
     * Get opened client.
103
     *
104
     * @return \ZendService\Google\Gcm\Client
105
     */
106
    protected function getPushService()
107
    {
108
        if ($this->pushClient === null) {
109
            $this->pushClient = GcmClientBuilder::buildPush($this->getParameter('api_key'));
110
        }
111
112
        return $this->pushClient;
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    protected function getDefinedParameters()
119
    {
120
        return ['api_key'];
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    protected function getRequiredParameters()
127
    {
128
        return ['api_key'];
129
    }
130
}
131