GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( abcc73...fd1b65 )
by Alexander
02:20
created

Dispatcher   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 10
Bugs 3 Features 0
Metric Value
wmc 25
c 10
b 3
f 0
lcom 1
cbo 10
dl 0
loc 246
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A setLogger() 0 5 1
A setDevelopmentMode() 0 5 1
A getServiceCredentials() 0 4 1
A getConnection() 0 8 2
A initConnection() 0 8 1
A addResponse() 0 6 1
B dispatch() 0 34 6
B loadFeedback() 0 29 4
A createFeedbackConnection() 0 5 1
B sendNotifications() 0 28 6
1
<?php
2
3
/*
4
 * (c) Alexander Zhukov <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Zbox\UnifiedPush;
11
12
use Zbox\UnifiedPush\Message\MessageInterface,
13
    Zbox\UnifiedPush\Notification\NotificationBuilder;
14
use Zbox\UnifiedPush\NotificationService\NotificationServices,
15
    Zbox\UnifiedPush\NotificationService\ServiceClientInterface,
16
    Zbox\UnifiedPush\NotificationService\ServiceClientFactory;
17
use Zbox\UnifiedPush\Exception\InvalidRecipientException,
18
    Zbox\UnifiedPush\Exception\DispatchMessageException,
19
    Zbox\UnifiedPush\Exception\MalformedNotificationException,
20
    Zbox\UnifiedPush\Exception\ClientException,
21
    Zbox\UnifiedPush\Exception\RuntimeException;
22
use Psr\Log\LoggerAwareInterface,
23
    Psr\Log\LoggerInterface,
24
    Psr\Log\NullLogger;
25
26
/**
27
 * Class Dispatcher
28
 * @package Zbox\UnifiedPush
29
 */
30
class Dispatcher implements LoggerAwareInterface
31
{
32
    /**
33
     * @var Application
34
     */
35
    private $application;
36
37
    /**
38
     * @var NotificationBuilder
39
     */
40
    private $notificationBuilder;
41
42
    /**
43
     * @var array
44
     */
45
    private $connectionPool;
46
47
    /**
48
     * @var ServiceClientFactory
49
     */
50
    private $clientFactory;
51
52
    /**
53
     * @var \ArrayIterator
54
     */
55
    private $responseCollection;
56
57
    /**
58
     * @var LoggerInterface
59
     */
60
    private $logger;
61
62
    /**
63
     * @param Application $application
64
     * @param ServiceClientFactory $clientFactory
65
     * @param NotificationBuilder $notificationBuilder
66
     */
67
    public function __construct(
68
        Application $application,
69
        ServiceClientFactory $clientFactory,
70
        NotificationBuilder $notificationBuilder
71
    ){
72
        $this->application    = $application;
73
        $this->clientFactory  = $clientFactory;
74
        $this->notificationBuilder = $notificationBuilder;
75
76
        $this->setLogger(new NullLogger());
77
    }
78
79
    /**
80
     * @param LoggerInterface $logger
81
     * @return $this
82
     */
83
    public function setLogger(LoggerInterface $logger)
84
    {
85
        $this->logger = $logger;
86
        return $this;
87
    }
88
89
    /**
90
     * @param bool $isDevelopment
91
     * @return $this
92
     */
93
    public function setDevelopmentMode($isDevelopment)
94
    {
95
        $this->clientFactory->setDevelopmentMode($isDevelopment);
96
        return $this;
97
    }
98
99
    /**
100
     * Returns credentials for notification service
101
     *
102
     * @param string $serviceName
103
     * @return array
104
     */
105
    private function getServiceCredentials($serviceName)
106
    {
107
        return $this->application->getCredentialsByService($serviceName);
108
    }
109
110
    /**
111
     * Gets a service client connection by service name
112
     *
113
     * @param string $serviceName
114
     * @return ServiceClientInterface
115
     */
116
    public function getConnection($serviceName)
117
    {
118
        if (empty($this->connectionPool[$serviceName])) {
119
            $this->initConnection($serviceName);
120
        }
121
122
        return $this->connectionPool[$serviceName];
123
    }
124
125
    /**
126
     * Initialize service client connection by service name
127
     *
128
     * @param string $serviceName
129
     * @return $this
130
     */
131
    public function initConnection($serviceName)
132
    {
133
        $credentials  = $this->getServiceCredentials($serviceName);
134
        $connection   = $this->clientFactory->createServiceClient($serviceName, $credentials);
135
        $this->connectionPool[$serviceName] = $connection;
136
137
        return $this;
138
    }
139
140
    public function addResponse($response)
141
    {
142
        $this->responseCollection->append($response);
143
144
        return $this;
145
    }
146
147
    /**
148
     * Tries to dispatch all messages to notification service
149
     *
150
     * @return bool
151
     * @throws Zbox\UnifiedPush\Exception\ClientException
152
     * @throws Zbox\UnifiedPush\Exception\RuntimeException
153
     * @throws \Exception
154
     */
155
    public function dispatch()
156
    {
157
        $messages = $this->application->getMessagesIterator();
158
159
        try {
160
            while ($messages->valid()) {
161
                $message = $messages->current();
162
                if ($this->notificationBuilder->buildNotifications($message)) {
163
                    $messages->offsetUnset($message->getMessageIdentifier());
164
                }
165
                $messages->next();
166
            }
167
168
            $this->sendNotifications();
169
170
        } catch (ClientException $e) {
171
            $this->logger->error(
172
                sprintf("Client connection error: %s", $e->getMessage())
173
            );
174
            return;
175
176
        } catch (RuntimeException $e) {
177
            $this->logger->error(
178
                sprintf("Runtime error: %s", $e->getMessage())
179
            );
180
            return;
181
182
        } catch (\Exception $e) {
183
            $this->logger->error(
184
                sprintf("Error occurs: %s", $e->getMessage())
185
            );
186
            return;
187
        }
188
    }
189
190
    /**
191
     * Tries to connect and load feedback data
192
     *
193
     * @return $this
194
     * @throws RuntimeException
195
     * @throws \Exception
196
     */
197
    public function loadFeedback()
198
    {
199
        $serviceName = NotificationServices::APPLE_PUSH_NOTIFICATIONS_SERVICE;
200
201
        try {
202
            $this->logger->info(sprintf("Querying the feedback service '%s'", $serviceName));
203
204
            $connection = $this->createFeedbackConnection($serviceName);
205
            $invalidRecipients = $connection->sendRequest();
206
207
            while ($invalidRecipients->valid()) {
208
                $recipient = $invalidRecipients->current();
209
                $this->application->addInvalidRecipient($serviceName, $recipient);
210
                $invalidRecipients->next();
211
            }
212
213
        } catch (RuntimeException $e) {
214
            $this->logger->error(
215
                sprintf("Runtime error while acquiring feedback: %s", $e->getMessage())
216
            );
217
218
        } catch (\Exception $e) {
219
            $this->logger->error(
220
                sprintf("Error occurs while acquiring feedback: %s", $e->getMessage())
221
            );
222
        }
223
224
        return $this;
225
    }
226
227
    /**
228
     * Creates a feedback service connection
229
     *
230
     * @param string $serviceName
231
     * @return ServiceClientInterface
232
     */
233
    private function createFeedbackConnection($serviceName)
234
    {
235
        $credentials  = $this->getServiceCredentials($serviceName);
236
        return $this->clientFactory->createServiceClient($serviceName, $credentials, true);
237
    }
238
239
    /**
240
     * Tries to connect and send a message to notification service
241
     *
242
     * @return bool
243
     * @throws Zbox\UnifiedPush\Exception\InvalidRecipientException
244
     * @throws Zbox\UnifiedPush\Exception\DispatchMessageException
245
     * @throws Zbox\UnifiedPush\Exception\MalformedNotificationException
246
     */
247
    private function sendNotifications()
248
    {
249
        while ($notification = $this->notificationBuilder->getNotification()) {
250
            try {
251
                $connection = $this->getConnection($notification->getType());
252
                $connection->setNotification($notification);
253
254
                $response = $connection->sendRequest();
255
                $this->addResponse($response);
256
            } catch (InvalidRecipientException $e) {
257
                while ($recipient = $e->getRecipientDevice()) {
258
                    $this->application->addInvalidRecipient($notification->getType(), $recipient);
259
                }
260
261
            } catch (DispatchMessageException $e) {
262
                $this->logger->warning(
263
                    sprintf("Dispatch message warning with code %d  '%s'", $e->getCode(), $e->getMessage())
264
                );
265
266
            } catch (MalformedNotificationException $e) {
267
                $this->logger->error(
268
                    sprintf("Malformed Notification error: %s", $e->getMessage())
269
                );
270
                return false;
271
            }
272
        }
273
        return true;
274
    }
275
}
276