PassbookUpdateNotifier   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
wmc 16
lcom 0
cbo 0
dl 0
loc 86
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A send() 0 33 3
C checkAppleErrorResponse() 0 36 12
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LauLamanApps\ApplePassbookBundle\PushNotification;
6
7
use LauLamanApps\ApplePassbook\Build\Signer;
8
9
/**
10
 * @codeCoverageIgnore
11
 */
12
final class PassbookUpdateNotifier
13
{
14
    /**
15
     * @var Signer
16
     */
17
    private $signer;
18
19
    public function __construct(Signer $signer)
20
    {
21
        $this->signer = $signer;
22
    }
23
24
    /**
25
     * @info Realy need to cleanup this function.
26
     */
27
    public function send(string $token): void
28
    {
29
30
        $ctx = stream_context_create();
31
        stream_context_set_option($ctx, 'ssl', 'passphrase', 'your pass');
32
        stream_context_set_option($ctx, 'ssl', 'local_cert', '/Users/laulaman/path/to/Certificate.pem');
33
        $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
34
        stream_set_blocking ($fp, false);
35
        if (!$fp) {
36
            //ERROR
37
            echo "Failed to connect (stream_socket_client): $err $errstrn";
0 ignored issues
show
Bug introduced by
The variable $errstrn does not exist. Did you mean $errstr?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
38
        } else {
39
40
            $payload = json_encode(['aps' => []]);
41
42
            //Enhanced Notification
43
            $msg = chr(0) . pack('n', 32) . pack('H*', $token) . pack('n', strlen($payload)) . $payload;
44
            //SEND PUSH
45
            $result = fwrite($fp, $msg);
46
            //We can check if an error has been returned while we are sending, but we also need to check once more after we are done sending in case there was a delay with error response.
47
            $this->checkAppleErrorResponse($fp);
48
            usleep(500000); //Pause for half a second. Note I tested this with up to a 5 minute pause, and the error message was still available to be retrieved
49
            $this->checkAppleErrorResponse($fp);
50
            if (!$result)
51
                echo 'Message not delivered' . PHP_EOL;
52
            else {
53
                echo 'Message successfully delivered' . PHP_EOL;
54
                var_dump($result);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($result); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
55
            }
56
            // Close the connection to the server
57
            fclose($fp);
58
        }
59
    }
60
    private function checkAppleErrorResponse($fp) {
61
        //byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID). Should return nothing if OK.
62
        $apple_error_response = fread($fp, 6);
63
        //NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait forever when there is no response to be sent.
64
        if ($apple_error_response) {
65
            //unpack the error response (first byte 'command" should always be 8)
66
            $error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response);
67
            if ($error_response['status_code'] == '0') {
68
                $error_response['status_code'] = '0-No errors encountered';
69
            } else if ($error_response['status_code'] == '1') {
70
                $error_response['status_code'] = '1-Processing error';
71
            } else if ($error_response['status_code'] == '2') {
72
                $error_response['status_code'] = '2-Missing device token';
73
            } else if ($error_response['status_code'] == '3') {
74
                $error_response['status_code'] = '3-Missing topic';
75
            } else if ($error_response['status_code'] == '4') {
76
                $error_response['status_code'] = '4-Missing payload';
77
            } else if ($error_response['status_code'] == '5') {
78
                $error_response['status_code'] = '5-Invalid token size';
79
            } else if ($error_response['status_code'] == '6') {
80
                $error_response['status_code'] = '6-Invalid topic size';
81
            } else if ($error_response['status_code'] == '7') {
82
                $error_response['status_code'] = '7-Invalid payload size';
83
            } else if ($error_response['status_code'] == '8') {
84
                $error_response['status_code'] = '8-Invalid token';
85
            } else if ($error_response['status_code'] == '255') {
86
                $error_response['status_code'] = '255-None (unknown)';
87
            } else {
88
                $error_response['status_code'] = $error_response['status_code'] . '-Not listed';
89
            }
90
            echo '<br><b>+ + + + + + ERROR</b> Response Command:<b>' . $error_response['command'] . '</b>&nbsp;&nbsp;&nbsp;Identifier:<b>' . $error_response['identifier'] . '</b>&nbsp;&nbsp;&nbsp;Status:<b>' . $error_response['status_code'] . '</b><br>';
91
            echo 'Identifier is the rowID (index) in the database that caused the problem, and Apple will disconnect you from server. To continue sending Push Notifications, just start at the next rowID after this Identifier.<br>';
92
            return true;
93
        }
94
        return false;
95
    }
96
97
}
98