SendGrid::newWithClient()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace StephaneCoinon\SendGridActivity;
4
5
use Http\Client\Common\Plugin\BaseUriPlugin;
6
use Http\Client\HttpClient;
7
use Http\Discovery\MessageFactoryDiscovery;
8
use Http\Discovery\UriFactoryDiscovery;
9
use StephaneCoinon\SendGridActivity\HttpClientFactory;
10
use StephaneCoinon\SendGridActivity\Integrations\Framework;
11
use StephaneCoinon\SendGridActivity\Requests\Request;
12
use StephaneCoinon\SendGridActivity\Support\Testing\ApiResponseFactory;
13
14
/**
15
 * SendGrid API client.
16
 */
17
class SendGrid
18
{
19
    /**
20
     * API base URL.
21
     *
22
     * @var string
23
     */
24
    protected $apiUrl = 'https://api.sendgrid.com';
25
26
    /**
27
     * API version.
28
     *
29
     * @var string
30
     */
31
    protected $apiVersion = 'v3';
32
33
    /**
34
     * Underlying HTTP client.
35
     *
36
     * @var \Http\Client\HttpClient
37
     */
38
    protected $client;
39
40
    /**
41
     * Message factory.
42
     *
43
     * @var \Http\Message\MessageFactory
44
     */
45
    protected $messageFactory;
46
47
    /**
48
     * Make a new ApiClient instance.
49
     *
50
     * If $client is null, a new HttpClient using $apiKey is instantiated.
51
     * If $apiKey is null, SENDGRID_API_KEY environment variable is used.
52
     * $apiKey is not used when $client is specified.
53
     *
54
     * @param null|string $apiKey
55
     * @param null|\Http\Client\HttpClient $client
56
     */
57
    public function __construct($apiKey = null, HttpClient $client = null)
58
    {
59
        $this->messageFactory = MessageFactoryDiscovery::find();
60
        $this->client = $client ?? HttpClientFactory::create(
61
            $apiKey ?? getenv('SENDGRID_API_KEY'),
62
            [
63
                new BaseUriPlugin(
64
                    UriFactoryDiscovery::find()->createUri($this->apiUrl)
65
                )
66
            ]
67
        );
68
    }
69
70
    /**
71
     *
72
     * @return self
73
     */
74
75
    /**
76
     * Get a new SendGrid instance.
77
     *
78
     * @param null|string $apiKey
79
     * @param null|\Http\Client\HttpClient $client
80
     * @return self
81
     */
82
    public static function newInstance($apiKey = null, HttpClient $client = null): self
83
    {
84
        return Framework::isLaravel()
85
            ? app(static::class)
86
            : new static($apiKey, $client);
87
    }
88
89
    /**
90
     * Static constructor to get a ApiClient instance with a given HTTP client.
91
     *
92
     * @param  \Http\Client\HttpClient $client
93
     * @return self
94
     */
95
    public static function newWithClient(HttpClient $client): self
96
    {
97
        return static::newInstance()->withClient($client);
98
    }
99
100
    /**
101
     * Get a new SendGrid instance with a mock client pre-loaded with HTTP responses.
102
     *
103
     * @param  array $responses
104
     * @return self
105
     */
106
    public static function mock(array $responses): self
107
    {
108
        $client = new \Http\Mock\Client;
109
        foreach ($responses as $response) {
110
            $client->addResponse((new ApiResponseFactory)->json()->build($response));
111
        }
112
113
        return static::newWithClient($client);
114
    }
115
116
    /**
117
     * Set the underlying HTTP client.
118
     *
119
     * @param  \Http\Client\HttpClient $client
120
     * @return self
121
     */
122
    public function withClient(HttpClient $client): self
123
    {
124
        $this->client = $client;
125
126
        return $this;
127
    }
128
129
    /**
130
     * Get underlying HTTP client.
131
     *
132
     * @return \Http\Client\HttpClient
133
     */
134
    public function getClient(): HttpClient
135
    {
136
        return $this->client;
137
    }
138
139
    /**
140
     * Make a "raw" HTTP request.
141
     *
142
     * JSON responses are automatically decoded.
143
     *
144
     * @param  string $method HTTP method
145
     * @param  string $url
146
     * @return string|array
147
     */
148
    public function requestRaw(string $method, string $url = '')
149
    {
150
        $response = $this->client->sendRequest(
151
            $this->messageFactory->createRequest(
152
                $method, "{$this->apiVersion}/{$url}"
153
            )
154
        );
155
156
        if ($response->getStatusCode() != 200) {
157
            var_dump(['request failed' => $response->getBody()->getContents()]); die();
0 ignored issues
show
Security Debugging Code introduced by
var_dump(array('request ...Body()->getContents())) looks like debug code. Are you sure you do not want to remove it?
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
158
            // throw new \Exception('Request failed');
159
        }
160
161
        $content = $response->getBody()->getContents();
162
        $contentType = $response->getHeader('Content-Type');
163
        $isJson = in_array('application/json', $contentType);
164
165
        return $isJson ? json_decode($content, true) : $content;
166
    }
167
168
    /**
169
     * Make a request using a Request instance.
170
     *
171
     * @param  Request $request
172
     * @return Response|Response[]
173
     */
174
    public function request(Request $request)
175
    {
176
        $responseModel = $request->getResponseModel();
177
        $response = $this->requestRaw(
178
            $request->getMethod(), $request->buildUrl()
179
        );
180
181
        return $responseModel::createFromApiResponse($response, [
182
            'api' => $this,
183
            'request' => $request,
184
        ]);
185
    }
186
}
187