Completed
Push — master ( 58620c...f23d9f )
by Vitaliy
02:20
created

ExceptionFactory::createByReason()   D

Complexity

Conditions 30
Paths 30

Size

Total Lines 106
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 106
rs 4.425
c 0
b 0
f 0
cc 30
eloc 64
nc 30
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the AppleApnPush package
5
 *
6
 * (c) Vitaliy Zhuk <[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 Apple\ApnPush\Protocol\Http\ExceptionFactory;
13
14
use Apple\ApnPush\Exception\SendMessage\BadCertificateEnvironmentException;
15
use Apple\ApnPush\Exception\SendMessage\BadCertificateException;
16
use Apple\ApnPush\Exception\SendMessage\BadCollapseIdException;
17
use Apple\ApnPush\Exception\SendMessage\BadDeviceTokenException;
18
use Apple\ApnPush\Exception\SendMessage\BadExpirationDateException;
19
use Apple\ApnPush\Exception\SendMessage\BadMessageIdException;
20
use Apple\ApnPush\Exception\SendMessage\BadPathException;
21
use Apple\ApnPush\Exception\SendMessage\BadPriorityException;
22
use Apple\ApnPush\Exception\SendMessage\BadTopicException;
23
use Apple\ApnPush\Exception\SendMessage\DeviceTokenNotForTopicException;
24
use Apple\ApnPush\Exception\SendMessage\DuplicateHeadersException;
25
use Apple\ApnPush\Exception\SendMessage\ExpiredProviderTokenException;
26
use Apple\ApnPush\Exception\SendMessage\ForbiddenException;
27
use Apple\ApnPush\Exception\SendMessage\IdleTimeoutException;
28
use Apple\ApnPush\Exception\SendMessage\InternalServerErrorException;
29
use Apple\ApnPush\Exception\SendMessage\InvalidProviderTokenException;
30
use Apple\ApnPush\Exception\SendMessage\InvalidResponseException;
31
use Apple\ApnPush\Exception\SendMessage\MethodNotAllowedException;
32
use Apple\ApnPush\Exception\SendMessage\MissingContentInResponseException;
33
use Apple\ApnPush\Exception\SendMessage\MissingDeviceTokenException;
34
use Apple\ApnPush\Exception\SendMessage\MissingErrorReasonInResponseException;
35
use Apple\ApnPush\Exception\SendMessage\MissingProviderTokenException;
36
use Apple\ApnPush\Exception\SendMessage\MissingTopicException;
37
use Apple\ApnPush\Exception\SendMessage\PayloadEmptyException;
38
use Apple\ApnPush\Exception\SendMessage\PayloadTooLargeException;
39
use Apple\ApnPush\Exception\SendMessage\SendMessageException;
40
use Apple\ApnPush\Exception\SendMessage\ServiceUnavailableException;
41
use Apple\ApnPush\Exception\SendMessage\ShutdownException;
42
use Apple\ApnPush\Exception\SendMessage\TooManyProviderTokenUpdatesException;
43
use Apple\ApnPush\Exception\SendMessage\TooManyRequestsException;
44
use Apple\ApnPush\Exception\SendMessage\TopicDisallowedException;
45
use Apple\ApnPush\Exception\SendMessage\UndefinedErrorException;
46
use Apple\ApnPush\Exception\SendMessage\UnregisteredException;
47
use Apple\ApnPush\Protocol\Http\Response;
48
49
/**
50
 * Default exception factory for create exception via response.
51
 * For all error codes, please see: https://developer.apple.com/library/prerelease/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW17
52
 */
53
class ExceptionFactory implements ExceptionFactoryInterface
54
{
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function create(Response $response) : SendMessageException
59
    {
60
        $content = $response->getContent();
61
62
        if (!$content) {
63
            return new MissingContentInResponseException();
64
        }
65
66
        $json = json_decode($content, true);
67
68
        if (null === $json) {
69
            return new InvalidResponseException(sprintf(
70
                'Can not parse JSON in response. Error: %d - %s',
71
                json_last_error(),
72
                json_last_error_msg()
73
            ));
74
        }
75
76
        if (!array_key_exists('reason', $json)) {
77
            return new MissingErrorReasonInResponseException();
78
        }
79
80
        $reason = $json['reason'];
81
82
        return $this->createByReason($reason, $json);
83
    }
84
85
    /**
86
     * Create exception by reason
87
     *
88
     * @param string $reason
89
     * @param array  $json
90
     *
91
     * @return SendMessageException
92
     */
93
    private function createByReason(string $reason, array $json)
94
    {
95
        $reason = strtolower($reason);
96
97
        switch ($reason) {
98
            // Bad request (400)
99
            case 'badcollapseid':
100
                return new BadCollapseIdException();
101
102
            case 'baddevicetoken':
103
                return new BadDeviceTokenException();
104
105
            case 'badexpirationdate':
106
                return new BadExpirationDateException();
107
108
            case 'badmessageid':
109
                return new BadMessageIdException();
110
111
            case 'badpriority':
112
                return new BadPriorityException();
113
114
            case 'badtopic':
115
                return new BadTopicException();
116
117
            case 'devicetokennotfortopic':
118
                return new DeviceTokenNotForTopicException();
119
120
            case 'duplicateheaders':
121
                return new DuplicateHeadersException();
122
123
            case 'idletimeout':
124
                return new IdleTimeoutException();
125
126
            case 'missingdevicetoken':
127
                return new MissingDeviceTokenException();
128
129
            case 'missingtopic':
130
                return new MissingTopicException();
131
132
            case 'payloadempty':
133
                return new PayloadEmptyException();
134
135
            case 'topicdisallowed':
136
                return new TopicDisallowedException();
137
138
            // Access denied (403)
139
            case 'badcertificate':
140
                return new BadCertificateException();
141
142
            case 'badcertificateenvironment':
143
                return new BadCertificateEnvironmentException();
144
145
            case 'expiredprovidertoken':
146
                return new ExpiredProviderTokenException();
147
148
            case 'forbidden':
149
                return new ForbiddenException();
150
151
            case 'invalidprovidertoken':
152
                return new InvalidProviderTokenException();
153
154
            case 'missingprovidertoken':
155
                return new MissingProviderTokenException();
156
157
            // Not found (404)
158
            case 'badpath':
159
                return new BadPathException();
160
161
            // Method not allowed (405)
162
            case 'methodnotallowed':
163
                return new MethodNotAllowedException();
164
165
            // Gone (410)
166
            case 'unregistered':
167
                $timestamp = array_key_exists('timestamp', $json) ? $json['timestamp'] : 0;
168
                $lastConfirmed = new \DateTime('now', new \DateTimeZone('UTC'));
169
                $lastConfirmed->setTimestamp($timestamp);
170
171
                return new UnregisteredException($lastConfirmed);
172
173
            // Request entity too large (413)
174
            case 'payloadtoolarge':
175
                return new PayloadTooLargeException();
176
177
            // Too many requests (429)
178
            case 'toomanyprovidertokenupdates':
179
                return new TooManyProviderTokenUpdatesException();
180
181
            case 'toomanyrequests':
182
                return new TooManyRequestsException();
183
184
            // Internal server error (500)
185
            case 'internalservererror':
186
                return new InternalServerErrorException();
187
188
            // Service unavailable (503)
189
            case 'serviceunavailable':
190
                return new ServiceUnavailableException();
191
192
            case 'shutdown':
193
                return new ShutdownException();
194
195
            default:
196
                return new UndefinedErrorException();
197
        }
198
    }
199
}
200