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.
Passed
Push — master ( acbac9...06dcea )
by
unknown
02:25
created

LeverPhp::notes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
namespace ViaWork\LeverPhp;
4
5
use Exception;
6
use GrahamCampbell\GuzzleFactory\GuzzleFactory;
7
use GuzzleHttp\Client as GuzzleClient;
8
use GuzzleHttp\Exception\ClientException;
9
use GuzzleHttp\HandlerStack;
10
use Illuminate\Support\LazyCollection;
11
use Psr\Http\Message\ResponseInterface;
12
use Spatie\GuzzleRateLimiterMiddleware\RateLimiterMiddleware;
13
use Spatie\GuzzleRateLimiterMiddleware\Store;
14
15
class LeverPhp
16
{
17
    const BACKOFF_TIME = 1500;
18
19
    private $leverKey = '';
20
21
    private $endpoint = '';
22
23
    private $client;
24
25
    private $options = [];
26
27
    /**
28
     * LeverPhp constructor.
29
     * @param string|null $leverKey
30
     * @param GuzzleClient|null $client
31
     * @param Store|null $store
32
     */
33
    public function __construct(string $leverKey = null, GuzzleClient $client = null, Store $store = null)
34
    {
35
        $this->leverKey = $leverKey;
36
37
        $stack = HandlerStack::create();
38
39
        $stack->push(DuplicateAggregatorMiddleware::buildQuery());
40
41
        $stack->push(RateLimiterMiddleware::perSecond(10, $store));
42
43
        $this->client = $client ?? GuzzleFactory::make(
44
                [
45
                    'base_uri' => 'https://api.lever.co/v1/',
46
                    'headers' => [
47
                        'Accept' => 'application/json',
48
                    ],
49
                    'auth' => [$leverKey, ''],
50
                    'handler' => $stack,
51
                ],
52
                self::BACKOFF_TIME
53
            );
54
    }
55
56
    private function reset()
57
    {
58
        $this->endpoint = '';
59
        $this->options = [];
60
    }
61
62
    private function post(array $body): ResponseInterface
63
    {
64
        try {
65
            $response = $this->client->post($this->endpoint, $this->options($body));
66
        } catch (ClientException $exception) {
67
            throw $exception;
68
        } finally {
69
            $this->reset();
70
        }
71
72
        return $response;
73
    }
74
75
    private function options($body)
76
    {
77
        if (isset($this->options['hasFiles'])) {
78
            $options = [];
79
80
            foreach ($body as $key => $item) {
81
82
                // TODO add support for files[] and automate filename and headers fields.
83
                if (in_array($key, ['file', 'files', 'resumeFile'])) {
84
                    $options[] = [
85
                        'name' => $key,
86
                        'contents' => $item['file'],
87
                        'filename' =>  $item['name'],
88
                        'headers' => ['Content-Type' => $item['type']],
89
                    ];
90
91
                    continue;
92
                }
93
94
                if (is_array($item)) {
95
                    foreach ($item as $subKey => $subItem) {
96
                        if (is_numeric($subKey)) {
97
                            $options[] = ['name' => $key.'[]', 'contents' => $subItem];
98
                        }
99
100
                        if (is_string($subKey)) {
101
                            $options[] = ['name' => "{$key}[{$subKey}]", 'contents' => $subItem];
102
                        }
103
                    }
104
                }
105
106
                if (is_string($item)) {
107
                    $options[] = ['name' => $key, 'contents' => $item];
108
                }
109
            }
110
111
            unset($this->options['hasFiles']);
112
113
            return array_merge(['multipart' => $options], $this->options);
114
        }
115
116
        return array_merge(['json' => $body], $this->options);
117
    }
118
119
    private function get(): ResponseInterface
120
    {
121
        try {
122
            $response = $this->client->get($this->endpoint, $this->options);
123
        } catch (ClientException $exception) {
124
            throw $exception;
125
        } finally {
126
            $this->reset();
127
        }
128
129
        return $response;
130
    }
131
132
    private function put(array $body): ResponseInterface
133
    {
134
        try {
135
            $response = $this->client->put($this->endpoint, $this->options($body));
136
        } catch (ClientException $exception) {
137
            throw $exception;
138
        } finally {
139
            $this->reset();
140
        }
141
142
        return $response;
143
    }
144
145
    public function create(array $body, string $method = 'post'): array
146
    {
147
        $response = $this->responseToArray($this->{$method}($body));
148
149
        return $response['data'];
150
    }
151
152
    public function update(array $body): array
153
    {
154
        return $this->create($body);
155
    }
156
157
    public function putUpdate(array $body): array
158
    {
159
        return $this->create($body, 'put');
160
    }
161
162
    /** @return LazyCollection|array */
163
    public function fetch()
164
    {
165
        $response = $this->responseToArray($this->get());
166
167
        if (! array_key_exists('hasNext', $response)) {
168
            return $response['data'];
169
        }
170
171
        return LazyCollection::make(function () use ($response) {
172
            do {
173
                foreach ($response['data'] as $item) {
174
                    yield $item;
175
                }
176
177
                $response['data'] = [];
178
179
                if (! empty($response['next'])) {
180
                    $response = $this->responseToArray(
181
                        $this->addParameter('offset', $response['next'])->get()
182
                    );
183
                }
184
            } while (count($response['data']) > 0);
185
        });
186
    }
187
188
    public function leverKey(): string
189
    {
190
        return $this->leverKey;
191
    }
192
193
    public function client(): GuzzleClient
194
    {
195
        return $this->client;
196
    }
197
198
    private function responseToArray(ResponseInterface $response): array
199
    {
200
        return json_decode($response->getBody()->getContents(), true);
201
    }
202
203
    public function expand($expandable)
204
    {
205
        return $this->addParameter('expand', $expandable);
206
    }
207
208
    public function performAs(string $userId)
209
    {
210
        return $this->addParameter('perform_as', $userId);
211
    }
212
213
    public function include($includable)
214
    {
215
        return $this->addParameter('include', $includable);
216
    }
217
218
    /**
219
     * @param string $field
220
     * @param string|array $value
221
     * @return $this
222
     */
223
    public function addParameter(string $field, $value)
224
    {
225
        if (! empty($field) && ! empty($value)) {
226
            $value = is_string($value) ? [$value] : $value;
227
228
            $this->options['query'][$field] = array_merge($this->options['query'][$field] ?? [], $value);
229
        }
230
231
        return $this;
232
    }
233
234
    public function opportunities(string $opportunityId = '')
235
    {
236
        $this->endpoint = 'opportunities'.(empty($opportunityId) ? '' : '/'.$opportunityId);
237
238
        return $this;
239
    }
240
241
    public function resumes(string $resumeId = '')
242
    {
243
        $this->endpoint .= '/resumes'.(empty($resumeId) ? '' : '/'.$resumeId);
244
245
        return $this;
246
    }
247
248
    public function download()
249
    {
250
        $this->endpoint .= '/download';
251
252
        return $this->get()->getBody();
253
    }
254
255
    public function offers()
256
    {
257
        // TODO next release.
258
        // $regex = '/^opportunities\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/';
259
        // if (preg_match($regex, $this->endpoint) === 0){
260
        //     throw new Exception('Did not chain methods in correct order.');
261
        // }
262
263
        $this->endpoint .= '/offers';
264
265
        return $this;
266
    }
267
268
    public function stages()
269
    {
270
        // TODO next release.
271
        // $regex = '/^opportunities\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/';
272
        // if (preg_match($regex, $this->endpoint) === 0){
273
        //     throw new Exception('Did not chain methods in correct order.');
274
        // }
275
276
        $this->endpoint .= '/stage';
277
278
        return $this;
279
    }
280
281
    public function postings(string $postingId = '')
282
    {
283
        $this->endpoint = 'postings'.(empty($postingId) ? '' : '/'.$postingId);
284
285
        return $this;
286
    }
287
288
    public function sendConfirmationEmail()
289
    {
290
        return $this->addParameter('send_confirmation_email', 'true');
291
    }
292
293
    public function apply(array $body): array
294
    {
295
        $this->endpoint .= '/apply';
296
297
        return $this->create($body);
298
    }
299
300
    public function state(string $state)
301
    {
302
        if (! in_array($state, ['published', 'internal', 'closed', 'draft', 'pending', 'rejected'])) {
303
            throw new Exception('Not a valid state');
304
        }
305
306
        return $this->addParameter('state', $state);
307
    }
308
309
    /**
310
     * @param array|string $team
311
     * @return $this
312
     */
313
    public function team($team)
314
    {
315
        return $this->addParameter('team', $team);
316
    }
317
318
    /**
319
     * @param array|string $department
320
     * @return $this
321
     */
322
    public function department($department)
323
    {
324
        return $this->addParameter('department', $department);
325
    }
326
327
    /**
328
     * @return $this
329
     */
330
    public function parse()
331
    {
332
        return $this->addParameter('parse', 'true');
333
    }
334
335
    public function hasFiles()
336
    {
337
        $this->options['hasFiles'] = true;
338
339
        return $this;
340
    }
341
342
    /**
343
     * @param array|string $email
344
     * @return $this
345
     */
346
    public function email($email)
347
    {
348
        return $this->addParameter('email', $email);
349
    }
350
351
    /**
352
     * @param array|string $stageId
353
     * @return $this
354
     */
355
    public function stage($stageId)
356
    {
357
        return $this->addParameter('stage_id', $stageId);
358
    }
359
360
    public function archived()
361
    {
362
        $this->endpoint .= '/archived';
363
364
        return $this;
365
    }
366
367
    public function notes($noteId)
368
    {
369
        $this->endpoint = 'notes'.(empty($noteId) ? '' : '/'.$noteId);
370
371
        return $this;
372
    }
373
374
    /**
375
     * @param array|string $postingId
376
     * @return $this
377
     */
378
    public function posting($postingId)
379
    {
380
        return $this->addParameter('posting_id', $postingId);
381
    }
382
}
383