OneSignal::sendRequest()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace OneSignal;
6
7
use OneSignal\Exception\BadMethodCallException;
8
use OneSignal\Exception\InvalidArgumentException;
9
use OneSignal\Exception\JsonException;
10
use OneSignal\Resolver\ResolverFactory;
11
use Psr\Http\Client\ClientInterface;
12
use Psr\Http\Message\RequestFactoryInterface;
13
use Psr\Http\Message\RequestInterface;
14
use Psr\Http\Message\StreamFactoryInterface;
15
use const JSON_THROW_ON_ERROR;
16
use function gettype;
17
use function is_array;
18
19
/**
20
 * @method Apps          apps()
21
 * @method Devices       devices()
22
 * @method Notifications notifications()
23
 */
24
class OneSignal
25
{
26
    public const API_URL = 'https://onesignal.com/api/v1';
27
28
    private $config;
29
    private $httpClient;
30
    private $requestFactory;
31
    private $streamFactory;
32
    private $resolverFactory;
33
34
    public function __construct(Config $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory)
35
    {
36
        $this->config = $config;
37
        $this->httpClient = $httpClient;
38
        $this->requestFactory = $requestFactory;
39
        $this->streamFactory = $streamFactory;
40
        $this->resolverFactory = new ResolverFactory($this->config);
41
    }
42
43
    public function getConfig(): Config
44
    {
45
        return $this->config;
46
    }
47
48
    public function getRequestFactory(): RequestFactoryInterface
49
    {
50
        return $this->requestFactory;
51
    }
52
53
    public function getStreamFactory(): StreamFactoryInterface
54
    {
55
        return $this->streamFactory;
56
    }
57
58
    public function sendRequest(RequestInterface $request): array
59
    {
60
        $response = $this->httpClient->sendRequest($request);
61
62
        $contentType = $response->getHeader('Content-Type')[0] ?? 'application/json';
63
64
        if (!preg_match('/\bjson\b/i', $contentType)) {
65
            throw new JsonException("Response content-type is '$contentType' while a JSON-compatible one was expected.");
66
        }
67
68
        $content = $response->getBody()->__toString();
69
70
        try {
71
            $content = json_decode($content, true, 512, JSON_BIGINT_AS_STRING | JSON_THROW_ON_ERROR);
72
        } catch (\JsonException $e) {
73
            throw new JsonException($e->getMessage(), $e->getCode(), $e);
74
        }
75
76
        if (!is_array($content)) {
77
            throw new JsonException(sprintf('JSON content was expected to decode to an array, %s returned.', gettype($content)));
78
        }
79
80
        return $content;
81
    }
82
83
    /**
84
     * @return object
85
     *
86
     * @throws InvalidArgumentException
87
     */
88
    public function api(string $name)
89
    {
90
        switch ($name) {
91
            case 'apps':
92
                $api = new Apps($this, $this->resolverFactory);
93
94
                break;
95
            case 'devices':
96
                $api = new Devices($this, $this->resolverFactory);
97
98
                break;
99
            case 'notifications':
100
                $api = new Notifications($this, $this->resolverFactory);
101
102
                break;
103
            default:
104
                throw new InvalidArgumentException("Undefined api instance called: '$name'.");
105
        }
106
107
        return $api;
108
    }
109
110
    public function __call(string $name, array $args): object
111
    {
112
        try {
113
            return $this->api($name);
114
        } catch (InvalidArgumentException $e) {
115
            throw new BadMethodCallException("Undefined method called: '$name'.");
116
        }
117
    }
118
}
119