Completed
Push — master ( 333612...dfaa4d )
by Arthur
01:53
created

Client::push()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 2
eloc 14
nc 2
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Pushok package.
5
 *
6
 * (c) Arthur Edamov <[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 Pushok;
13
14
use GuzzleHttp\Client as GuzzleClient;
15
use GuzzleHttp\Exception\RequestException;
16
use GuzzleHttp\Exception\TransferException;
17
use GuzzleHttp\Promise;
18
19
/**
20
 * Class Client
21
 * @package Pushok
22
 */
23
class Client
24
{
25
    /**
26
     * Array of notifications.
27
     *
28
     * @var Notification[]
29
     */
30
    private $notifications = [];
31
32
    /**
33
     * Authentication provider.
34
     *
35
     * @var AuthProviderInterface
36
     */
37
    private $authProvider;
38
39
    /**
40
     * Production or sandbox environment.
41
     *
42
     * @var bool
43
     */
44
    private $isProductionEnv;
45
46
    /**
47
     * Client constructor.
48
     *
49
     * @param AuthProviderInterface $authProvider
50
     * @param bool $isProductionEnv
51
     */
52
    public function __construct(AuthProviderInterface $authProvider, bool $isProductionEnv = false)
53
    {
54
        $this->authProvider = $authProvider;
55
        $this->isProductionEnv = $isProductionEnv;
56
    }
57
58
    /**
59
     * Push notifications to APNs.
60
     *
61
     * @return array
62
     */
63
    public function push(): array
64
    {
65
        $client = new GuzzleClient();
66
67
        $promises = [];
68
        foreach ($this->notifications as $k => $notification) {
69
            $request = new Request($notification, $this->isProductionEnv);
70
71
            $this->authProvider->authenticateClient($request);
72
73
            $promises[] = $client->postAsync($request->getUri(), [
74
                'version' => 2.0,
75
                'http_errors' => false,
76
                'body' => $request->getBody(),
77
                'headers' => $request->getHeaders()
78
            ]);
79
        }
80
81
        $results = Promise\settle($promises)->wait();
82
83
        $responseCollection = $this->mapResults($results);
84
85
        return $responseCollection;
86
    }
87
88
    /**
89
     * Add notification in queue for sending.
90
     *
91
     * @param Notification $notification
92
     */
93
    public function addNotification(Notification $notification)
94
    {
95
        $this->notifications[] = $notification;
96
    }
97
98
    /**
99
     * Add several notifications in queue for sending.
100
     *
101
     * @param Notification[] $notifications
102
     */
103
    public function addNotifications(array $notifications)
104
    {
105
        $this->notifications = array_merge($this->notifications, $notifications);
106
    }
107
108
    /**
109
     * Get already added notifications.
110
     *
111
     * @return Notification[]
112
     */
113
    public function getNotifications()
114
    {
115
        return $this->notifications;
116
    }
117
118
    private function mapResults($results)
119
    {
120
        $responseCollection = [];
121
122
        foreach ($results as $result) {
123
            if (isset($result['value'])) {
124
                $responseCollection[] = Response::createFromPsrInterface($result['value']);
125
            } elseif (isset($result['reason'])) {
126
                $responseCollection[] = $this->mapErrorResponse($result['reason']);
127
            }
128
        }
129
130
        return $responseCollection;
131
    }
132
133
    private function mapErrorResponse(TransferException $error)
134
    {
135
        if ($error instanceof RequestException) {
136
            if ($error->hasResponse()) {
137
                return Response::createFromPsrInterface($error->getResponse());
0 ignored issues
show
Bug introduced by
It seems like $error->getResponse() can be null; however, createFromPsrInterface() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
138
            }
139
140
            return new Response(0, null, $error->getHandlerContext()['error']);
141
        }
142
143
        throw new \Exception($error->getMessage(), $error->getCode());
144
    }
145
}
146